aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Android.mk131
-rw-r--r--CHANGES.txt207
-rw-r--r--CONTRIBUTORS.txt11
-rw-r--r--LICENSE (renamed from COPYING.txt)0
-rw-r--r--Makefile.am111
-rw-r--r--Makefile.in455
-rw-r--r--README.md (renamed from README.txt)51
-rw-r--r--aclocal.m4722
-rwxr-xr-xautogen.sh6
-rw-r--r--benchmarks/ProtoBench.java203
-rw-r--r--benchmarks/google_message1.datbin0 -> 228 bytes
-rw-r--r--benchmarks/google_message2.datbin0 -> 84570 bytes
-rw-r--r--benchmarks/google_size.proto136
-rw-r--r--benchmarks/google_speed.proto136
-rw-r--r--benchmarks/readme.txt50
-rw-r--r--build.gradle6
-rwxr-xr-xcompile347
-rwxr-xr-xconfig.guess594
-rw-r--r--config.h.in9
-rwxr-xr-xconfig.sub371
-rwxr-xr-xconfigure5043
-rw-r--r--configure.ac20
-rwxr-xr-xdepcomp586
-rw-r--r--editors/proto.vim9
-rw-r--r--examples/AddPerson.java14
-rw-r--r--examples/README.txt2
-rw-r--r--gtest/CHANGES22
-rw-r--r--gtest/CMakeLists.txt384
-rw-r--r--gtest/CONTRIBUTORS3
-rw-r--r--gtest/Makefile.am459
-rw-r--r--gtest/Makefile.in2296
-rw-r--r--gtest/README561
-rw-r--r--gtest/aclocal.m4775
-rwxr-xr-xgtest/build-aux/compile347
-rwxr-xr-xgtest/build-aux/config.guess594
-rwxr-xr-xgtest/build-aux/config.sub371
-rwxr-xr-xgtest/build-aux/depcomp586
-rwxr-xr-xgtest/build-aux/install-sh38
-rw-r--r--gtest/build-aux/ltmain.sh4
-rwxr-xr-xgtest/build-aux/missing460
-rwxr-xr-xgtest/build-aux/test-driver139
-rw-r--r--gtest/codegear/gtest.groupproj24
-rw-r--r--gtest/codegear/gtest_unittest.cbproj16
-rwxr-xr-xgtest/configure696
-rw-r--r--gtest/configure.ac22
-rw-r--r--gtest/fused-src/gtest/gtest-all.cc8510
-rw-r--r--gtest/fused-src/gtest/gtest.h18007
-rw-r--r--gtest/fused-src/gtest/gtest_main.cc39
-rw-r--r--gtest/include/gtest/gtest-death-test.h4
-rw-r--r--gtest/include/gtest/gtest-message.h10
-rw-r--r--gtest/include/gtest/gtest-param-test.h16
-rw-r--r--gtest/include/gtest/gtest-param-test.h.pump18
-rw-r--r--gtest/include/gtest/gtest-spi.h4
-rw-r--r--gtest/include/gtest/gtest-test-part.h36
-rw-r--r--gtest/include/gtest/gtest-typed-test.h10
-rw-r--r--gtest/include/gtest/gtest.h364
-rw-r--r--gtest/include/gtest/internal/gtest-death-test-internal.h15
-rw-r--r--gtest/include/gtest/internal/gtest-filepath.h11
-rw-r--r--gtest/include/gtest/internal/gtest-internal.h79
-rw-r--r--gtest/include/gtest/internal/gtest-linked_ptr.h2
-rw-r--r--gtest/include/gtest/internal/gtest-param-util-generated.h21
-rw-r--r--gtest/include/gtest/internal/gtest-param-util-generated.h.pump21
-rw-r--r--gtest/include/gtest/internal/gtest-param-util.h51
-rw-r--r--gtest/include/gtest/internal/gtest-port.h727
-rw-r--r--gtest/include/gtest/internal/gtest-string.h54
-rw-r--r--gtest/include/gtest/internal/gtest-tuple.h24
-rw-r--r--gtest/include/gtest/internal/gtest-tuple.h.pump13
-rw-r--r--gtest/include/gtest/internal/gtest-type-util.h6
-rw-r--r--gtest/include/gtest/internal/gtest-type-util.h.pump2
-rw-r--r--gtest/make/Makefile10
-rwxr-xr-x[-rw-r--r--]gtest/msvc/gtest-md.sln0
-rwxr-xr-x[-rw-r--r--]gtest/msvc/gtest-md.vcproj0
-rwxr-xr-x[-rw-r--r--]gtest/msvc/gtest.sln0
-rwxr-xr-x[-rw-r--r--]gtest/msvc/gtest.vcproj0
-rwxr-xr-x[-rw-r--r--]gtest/msvc/gtest_main-md.vcproj0
-rwxr-xr-x[-rw-r--r--]gtest/msvc/gtest_main.vcproj0
-rwxr-xr-x[-rw-r--r--]gtest/msvc/gtest_prod_test-md.vcproj0
-rwxr-xr-x[-rw-r--r--]gtest/msvc/gtest_prod_test.vcproj0
-rwxr-xr-x[-rw-r--r--]gtest/msvc/gtest_unittest-md.vcproj0
-rwxr-xr-x[-rw-r--r--]gtest/msvc/gtest_unittest.vcproj0
-rw-r--r--gtest/samples/prime_tables.h3
-rw-r--r--gtest/samples/sample10_unittest.cc6
-rw-r--r--gtest/samples/sample2.cc14
-rw-r--r--gtest/samples/sample2.h12
-rw-r--r--gtest/samples/sample2_unittest.cc2
-rw-r--r--gtest/samples/sample3-inl.h50
-rw-r--r--gtest/samples/sample3_unittest.cc6
-rw-r--r--gtest/samples/sample5_unittest.cc8
-rw-r--r--gtest/samples/sample7_unittest.cc12
-rw-r--r--gtest/samples/sample8_unittest.cc12
-rw-r--r--gtest/samples/sample9_unittest.cc2
-rw-r--r--gtest/scons/SConscript325
-rw-r--r--gtest/scons/SConstruct.common356
-rwxr-xr-xgtest/scripts/gtest-config.in8
-rwxr-xr-xgtest/scripts/pump.py835
-rw-r--r--gtest/src/gtest-all.cc6
-rw-r--r--gtest/src/gtest-death-test.cc34
-rw-r--r--gtest/src/gtest-filepath.cc64
-rw-r--r--gtest/src/gtest-internal-inl.h413
-rw-r--r--gtest/src/gtest-port.cc151
-rw-r--r--gtest/src/gtest-test-part.cc16
-rw-r--r--gtest/src/gtest-typed-test.cc12
-rw-r--r--gtest/src/gtest.cc362
-rw-r--r--gtest/test/gtest-death-test_test.cc82
-rw-r--r--gtest/test/gtest-filepath_test.cc106
-rw-r--r--gtest/test/gtest-listener_test.cc63
-rw-r--r--gtest/test/gtest-message_test.cc24
-rw-r--r--gtest/test/gtest-options_test.cc139
-rw-r--r--gtest/test/gtest-param-test_test.cc137
-rw-r--r--gtest/test/gtest-port_test.cc341
-rw-r--r--gtest/test/gtest-test-part_test.cc49
-rw-r--r--gtest/test/gtest-tuple_test.cc42
-rw-r--r--gtest/test/gtest-typed-test_test.cc12
-rw-r--r--gtest/test/gtest_all_test.cc1
-rwxr-xr-xgtest/test/gtest_break_on_failure_unittest.py11
-rw-r--r--gtest/test/gtest_break_on_failure_unittest_.cc20
-rw-r--r--gtest/test/gtest_color_test_.cc13
-rwxr-xr-xgtest/test/gtest_env_var_test.py10
-rwxr-xr-xgtest/test/gtest_filter_unittest.py189
-rwxr-xr-xgtest/test/gtest_help_test.py55
-rw-r--r--gtest/test/gtest_help_test_.cc4
-rw-r--r--gtest/test/gtest_nc.cc234
-rwxr-xr-xgtest/test/gtest_nc_test.py106
-rwxr-xr-xgtest/test/gtest_output_test.py86
-rw-r--r--gtest/test/gtest_output_test_.cc162
-rw-r--r--gtest/test/gtest_output_test_golden_lin.txt72
-rwxr-xr-xgtest/test/gtest_shuffle_test.py14
-rw-r--r--gtest/test/gtest_stress_test.cc150
-rwxr-xr-xgtest/test/gtest_test_utils.py65
-rw-r--r--gtest/test/gtest_unittest.cc1057
-rw-r--r--gtest/test/production.h2
-rwxr-xr-xgtest/test/run_tests_util.py466
-rwxr-xr-xgtest/test/run_tests_util_test.py676
-rw-r--r--gtest/xcode/Config/General.xcconfig2
-rw-r--r--gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj153
-rw-r--r--gtest/xcode/Samples/FrameworkSample/runtests.sh62
-rw-r--r--gtest/xcode/Samples/FrameworkSample/widget.cc6
-rw-r--r--gtest/xcode/Samples/FrameworkSample/widget.h8
-rw-r--r--gtest/xcode/Samples/FrameworkSample/widget_test.cc4
-rw-r--r--gtest/xcode/Scripts/runtests.sh29
-rwxr-xr-x[-rw-r--r--]gtest/xcode/Scripts/versiongenerate.py35
-rwxr-xr-xinstall-sh38
-rw-r--r--java/README.txt32
-rw-r--r--java/pom.xml70
-rw-r--r--java/src/main/java/com/google/protobuf/AbstractMessage.java599
-rw-r--r--java/src/main/java/com/google/protobuf/AbstractMessageLite.java51
-rw-r--r--java/src/main/java/com/google/protobuf/AbstractParser.java253
-rw-r--r--java/src/main/java/com/google/protobuf/BlockingRpcChannel.java2
-rw-r--r--java/src/main/java/com/google/protobuf/BlockingService.java2
-rw-r--r--java/src/main/java/com/google/protobuf/BoundedByteString.java163
-rw-r--r--java/src/main/java/com/google/protobuf/ByteString.java937
-rw-r--r--java/src/main/java/com/google/protobuf/CodedInputStream.java730
-rw-r--r--java/src/main/java/com/google/protobuf/CodedOutputStream.java282
-rw-r--r--java/src/main/java/com/google/protobuf/Descriptors.java533
-rw-r--r--java/src/main/java/com/google/protobuf/DynamicMessage.java226
-rw-r--r--java/src/main/java/com/google/protobuf/Extension.java96
-rw-r--r--java/src/main/java/com/google/protobuf/ExtensionRegistry.java188
-rw-r--r--java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java20
-rw-r--r--java/src/main/java/com/google/protobuf/FieldSet.java433
-rw-r--r--java/src/main/java/com/google/protobuf/GeneratedMessage.java1294
-rw-r--r--java/src/main/java/com/google/protobuf/GeneratedMessageLite.java793
-rw-r--r--java/src/main/java/com/google/protobuf/Internal.java272
-rw-r--r--java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java31
-rw-r--r--java/src/main/java/com/google/protobuf/LazyField.java154
-rw-r--r--java/src/main/java/com/google/protobuf/LazyFieldLite.java176
-rw-r--r--java/src/main/java/com/google/protobuf/LazyStringArrayList.java367
-rw-r--r--java/src/main/java/com/google/protobuf/LazyStringList.java163
-rw-r--r--java/src/main/java/com/google/protobuf/LiteralByteString.java362
-rw-r--r--java/src/main/java/com/google/protobuf/Message.java127
-rw-r--r--java/src/main/java/com/google/protobuf/MessageLite.java89
-rw-r--r--java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java60
-rw-r--r--java/src/main/java/com/google/protobuf/MessageOrBuilder.java143
-rw-r--r--java/src/main/java/com/google/protobuf/MessageReflection.java931
-rw-r--r--java/src/main/java/com/google/protobuf/Parser.java261
-rw-r--r--java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java2
-rw-r--r--java/src/main/java/com/google/protobuf/ProtocolStringList.java48
-rw-r--r--java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java696
-rw-r--r--java/src/main/java/com/google/protobuf/RopeByteString.java957
-rw-r--r--java/src/main/java/com/google/protobuf/RpcCallback.java2
-rw-r--r--java/src/main/java/com/google/protobuf/RpcChannel.java2
-rw-r--r--java/src/main/java/com/google/protobuf/RpcController.java2
-rw-r--r--java/src/main/java/com/google/protobuf/RpcUtil.java7
-rw-r--r--java/src/main/java/com/google/protobuf/Service.java2
-rw-r--r--java/src/main/java/com/google/protobuf/ServiceException.java12
-rw-r--r--java/src/main/java/com/google/protobuf/SingleFieldBuilder.java241
-rw-r--r--java/src/main/java/com/google/protobuf/SmallSortedMap.java618
-rw-r--r--java/src/main/java/com/google/protobuf/TextFormat.java1381
-rw-r--r--java/src/main/java/com/google/protobuf/UninitializedMessageException.java2
-rw-r--r--java/src/main/java/com/google/protobuf/UnknownFieldSet.java48
-rw-r--r--java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java205
-rw-r--r--java/src/main/java/com/google/protobuf/Utf8.java349
-rw-r--r--java/src/main/java/com/google/protobuf/WireFormat.java16
-rw-r--r--java/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java259
-rw-r--r--java/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java28
-rw-r--r--java/src/main/java/com/google/protobuf/nano/Extension.java33
-rw-r--r--java/src/main/java/com/google/protobuf/nano/FieldArray.java34
-rw-r--r--java/src/main/java/com/google/protobuf/nano/FieldData.java69
-rw-r--r--java/src/main/java/com/google/protobuf/nano/InternalNano.java8
-rw-r--r--java/src/main/java/com/google/protobuf/nano/MessageNano.java8
-rw-r--r--java/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java4
-rw-r--r--java/src/main/java/com/google/protobuf/nano/UnknownFieldData.java4
-rw-r--r--java/src/test/java/com/google/protobuf/AbstractMessageTest.java84
-rw-r--r--java/src/test/java/com/google/protobuf/BoundedByteStringTest.java68
-rw-r--r--java/src/test/java/com/google/protobuf/ByteStringTest.java759
-rw-r--r--java/src/test/java/com/google/protobuf/CheckUtf8Test.java141
-rw-r--r--java/src/test/java/com/google/protobuf/CodedInputStreamTest.java286
-rw-r--r--java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java101
-rw-r--r--java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java80
-rw-r--r--java/src/test/java/com/google/protobuf/DescriptorsTest.java286
-rw-r--r--java/src/test/java/com/google/protobuf/DynamicMessageTest.java136
-rw-r--r--java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java48
-rw-r--r--java/src/test/java/com/google/protobuf/GeneratedMessageTest.java922
-rw-r--r--java/src/test/java/com/google/protobuf/IsValidUtf8Test.java180
-rw-r--r--java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java421
-rw-r--r--java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java134
-rw-r--r--java/src/test/java/com/google/protobuf/LazyFieldTest.java121
-rw-r--r--java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java319
-rw-r--r--java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java174
-rw-r--r--java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java143
-rw-r--r--java/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java85
-rw-r--r--java/src/test/java/com/google/protobuf/LiteTest.java34
-rw-r--r--java/src/test/java/com/google/protobuf/LiteralByteStringTest.java396
-rw-r--r--java/src/test/java/com/google/protobuf/MessageTest.java42
-rw-r--r--java/src/test/java/com/google/protobuf/NanoTest.java62
-rw-r--r--java/src/test/java/com/google/protobuf/NestedBuildersTest.java185
-rw-r--r--java/src/test/java/com/google/protobuf/ParserTest.java381
-rw-r--r--java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java190
-rw-r--r--java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java97
-rw-r--r--java/src/test/java/com/google/protobuf/RopeByteStringTest.java115
-rw-r--r--java/src/test/java/com/google/protobuf/ServiceTest.java16
-rw-r--r--java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java155
-rw-r--r--java/src/test/java/com/google/protobuf/SmallSortedMapTest.java420
-rw-r--r--java/src/test/java/com/google/protobuf/TestBadIdentifiers.java96
-rw-r--r--java/src/test/java/com/google/protobuf/TestUtil.java460
-rw-r--r--java/src/test/java/com/google/protobuf/TextFormatTest.java422
-rw-r--r--java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java218
-rw-r--r--java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java227
-rw-r--r--java/src/test/java/com/google/protobuf/WireFormatTest.java189
-rw-r--r--java/src/test/java/com/google/protobuf/lazy_fields_lite.proto61
-rw-r--r--java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto55
-rw-r--r--java/src/test/java/com/google/protobuf/multiple_files_test.proto14
-rw-r--r--java/src/test/java/com/google/protobuf/nested_builders_test.proto53
-rw-r--r--java/src/test/java/com/google/protobuf/nested_extension.proto46
-rw-r--r--java/src/test/java/com/google/protobuf/nested_extension_lite.proto48
-rw-r--r--java/src/test/java/com/google/protobuf/non_nested_extension.proto49
-rw-r--r--java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto50
-rw-r--r--java/src/test/java/com/google/protobuf/outer_class_name_test.proto38
-rw-r--r--java/src/test/java/com/google/protobuf/outer_class_name_test2.proto42
-rw-r--r--java/src/test/java/com/google/protobuf/outer_class_name_test3.proto43
-rw-r--r--java/src/test/java/com/google/protobuf/test_bad_identifiers.proto157
-rw-r--r--java/src/test/java/com/google/protobuf/test_check_utf8.proto50
-rw-r--r--java/src/test/java/com/google/protobuf/test_check_utf8_size.proto51
-rw-r--r--java/src/test/java/com/google/protobuf/test_custom_options.proto43
-rw-r--r--java/src/test/java/com/google/protobuf/test_extra_interfaces.proto60
-rw-r--r--[-rwxr-xr-x]ltmain.sh3905
-rw-r--r--m4/acx_check_suncc.m41
-rw-r--r--m4/acx_pthread.m434
-rw-r--r--m4/libtool.m42400
-rw-r--r--m4/ltoptions.m432
-rw-r--r--m4/ltsugar.m420
-rw-r--r--m4/ltversion.m412
-rw-r--r--m4/lt~obsolete.m412
-rw-r--r--m4/stl_hash.m498
-rwxr-xr-xmissing460
-rwxr-xr-xmore_tests/Makefile41
-rwxr-xr-xpost_process_dist.sh60
-rw-r--r--protobuf.pc.in3
-rw-r--r--python/README.txt40
-rwxr-xr-xpython/ez_setup.py27
-rwxr-xr-xpython/google/protobuf/descriptor.py301
-rw-r--r--python/google/protobuf/descriptor_database.py137
-rw-r--r--python/google/protobuf/descriptor_pool.py643
-rw-r--r--python/google/protobuf/internal/api_implementation.cc139
-rwxr-xr-xpython/google/protobuf/internal/api_implementation.py89
-rw-r--r--python/google/protobuf/internal/api_implementation_default_test.py63
-rwxr-xr-xpython/google/protobuf/internal/containers.py61
-rwxr-xr-xpython/google/protobuf/internal/cpp_message.py663
-rwxr-xr-xpython/google/protobuf/internal/decoder.py228
-rw-r--r--python/google/protobuf/internal/descriptor_database_test.py63
-rw-r--r--python/google/protobuf/internal/descriptor_pool_test.py564
-rw-r--r--python/google/protobuf/internal/descriptor_pool_test1.proto94
-rw-r--r--python/google/protobuf/internal/descriptor_pool_test2.proto70
-rw-r--r--python/google/protobuf/internal/descriptor_python_test.py (renamed from gtest/scons/SConstruct)47
-rwxr-xr-xpython/google/protobuf/internal/descriptor_test.py425
-rwxr-xr-xpython/google/protobuf/internal/encoder.py120
-rw-r--r--python/google/protobuf/internal/enum_type_wrapper.py89
-rw-r--r--python/google/protobuf/internal/factory_test1.proto57
-rw-r--r--python/google/protobuf/internal/factory_test2.proto92
-rwxr-xr-xpython/google/protobuf/internal/generator_test.py141
-rw-r--r--python/google/protobuf/internal/message_factory_python_test.py54
-rw-r--r--python/google/protobuf/internal/message_factory_test.py131
-rwxr-xr-xpython/google/protobuf/internal/message_listener.py2
-rw-r--r--python/google/protobuf/internal/message_python_test.py54
-rwxr-xr-xpython/google/protobuf/internal/message_test.py618
-rw-r--r--python/google/protobuf/internal/missing_enum_values.proto50
-rw-r--r--python/google/protobuf/internal/more_extensions.proto2
-rw-r--r--python/google/protobuf/internal/more_extensions_dynamic.proto49
-rw-r--r--python/google/protobuf/internal/more_messages.proto2
-rwxr-xr-xpython/google/protobuf/internal/python_message.py1251
-rwxr-xr-xpython/google/protobuf/internal/reflection_test.py870
-rwxr-xr-xpython/google/protobuf/internal/service_reflection_test.py8
-rw-r--r--python/google/protobuf/internal/symbol_database_test.py120
-rw-r--r--python/google/protobuf/internal/test_bad_identifiers.proto52
-rwxr-xr-xpython/google/protobuf/internal/test_util.py117
-rwxr-xr-xpython/google/protobuf/internal/text_encoding_test.py68
-rwxr-xr-xpython/google/protobuf/internal/text_format_test.py569
-rwxr-xr-xpython/google/protobuf/internal/type_checkers.py74
-rwxr-xr-xpython/google/protobuf/internal/unknown_fields_test.py231
-rwxr-xr-xpython/google/protobuf/internal/wire_format.py2
-rwxr-xr-xpython/google/protobuf/internal/wire_format_test.py10
-rwxr-xr-xpython/google/protobuf/message.py34
-rw-r--r--python/google/protobuf/message_factory.py155
-rw-r--r--python/google/protobuf/pyext/README6
-rw-r--r--python/google/protobuf/pyext/__init__.py (renamed from MODULE_LICENSE_BSD_LIKE)0
-rw-r--r--python/google/protobuf/pyext/cpp_message.py61
-rw-r--r--python/google/protobuf/pyext/descriptor.cc357
-rw-r--r--python/google/protobuf/pyext/descriptor.h96
-rw-r--r--python/google/protobuf/pyext/descriptor_cpp2_test.py58
-rw-r--r--python/google/protobuf/pyext/extension_dict.cc338
-rw-r--r--python/google/protobuf/pyext/extension_dict.h123
-rw-r--r--python/google/protobuf/pyext/message.cc2561
-rw-r--r--python/google/protobuf/pyext/message.h305
-rw-r--r--python/google/protobuf/pyext/message_factory_cpp2_test.py56
-rw-r--r--python/google/protobuf/pyext/proto2_api_test.proto38
-rw-r--r--python/google/protobuf/pyext/python.proto66
-rw-r--r--python/google/protobuf/pyext/python_protobuf.h57
-rwxr-xr-xpython/google/protobuf/pyext/reflection_cpp2_generated_test.py94
-rw-r--r--python/google/protobuf/pyext/repeated_composite_container.cc763
-rw-r--r--python/google/protobuf/pyext/repeated_composite_container.h172
-rw-r--r--python/google/protobuf/pyext/repeated_scalar_container.cc825
-rw-r--r--python/google/protobuf/pyext/repeated_scalar_container.h112
-rw-r--r--python/google/protobuf/pyext/scoped_pyobject_ptr.h95
-rwxr-xr-xpython/google/protobuf/reflection.py1071
-rwxr-xr-xpython/google/protobuf/service.py2
-rwxr-xr-xpython/google/protobuf/service_reflection.py2
-rw-r--r--python/google/protobuf/symbol_database.py185
-rw-r--r--python/google/protobuf/text_encoding.py110
-rwxr-xr-xpython/google/protobuf/text_format.py586
-rwxr-xr-xpython/setup.py160
-rw-r--r--src/Makefile.am148
-rw-r--r--src/Makefile.in4202
-rw-r--r--src/google/protobuf/SEBS240
-rw-r--r--src/google/protobuf/compiler/code_generator.cc21
-rw-r--r--src/google/protobuf/compiler/code_generator.h29
-rw-r--r--src/google/protobuf/compiler/command_line_interface.cc512
-rw-r--r--src/google/protobuf/compiler/command_line_interface.h84
-rw-r--r--src/google/protobuf/compiler/command_line_interface_unittest.cc333
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc44
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum.cc60
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum.h10
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum_field.cc100
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum_field.h27
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_extension.cc10
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_extension.h9
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_field.cc59
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_field.h28
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.cc153
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.h9
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_generator.cc17
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_generator.h4
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.cc169
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.h64
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.cc1329
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.h13
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message_field.cc127
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message_field.h27
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_options.h58
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc42
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_primitive_field.cc87
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_primitive_field.h28
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_service.cc8
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_service.h6
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.cc294
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.h31
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto25
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc878
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.h51
-rw-r--r--src/google/protobuf/compiler/importer.cc48
-rw-r--r--src/google/protobuf/compiler/importer.h22
-rw-r--r--src/google/protobuf/compiler/importer_unittest.cc57
-rw-r--r--src/google/protobuf/compiler/java/java_context.cc195
-rw-r--r--src/google/protobuf/compiler/java/java_context.h95
-rw-r--r--src/google/protobuf/compiler/java/java_doc_comment.cc233
-rw-r--r--src/google/protobuf/compiler/java/java_doc_comment.h69
-rw-r--r--src/google/protobuf/compiler/java/java_doc_comment_unittest.cc67
-rw-r--r--src/google/protobuf/compiler/java/java_enum.cc161
-rw-r--r--src/google/protobuf/compiler/java/java_enum.h19
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field.cc661
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field.h83
-rw-r--r--src/google/protobuf/compiler/java/java_extension.cc250
-rw-r--r--src/google/protobuf/compiler/java/java_extension.h48
-rw-r--r--src/google/protobuf/compiler/java/java_field.cc199
-rw-r--r--src/google/protobuf/compiler/java/java_field.h90
-rw-r--r--src/google/protobuf/compiler/java/java_file.cc434
-rw-r--r--src/google/protobuf/compiler/java/java_file.h38
-rw-r--r--src/google/protobuf/compiler/java/java_generator.cc84
-rw-r--r--src/google/protobuf/compiler/java/java_generator.h4
-rw-r--r--src/google/protobuf/compiler/java/java_generator_factory.cc77
-rw-r--r--src/google/protobuf/compiler/java/java_generator_factory.h101
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.cc472
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.h205
-rw-r--r--src/google/protobuf/compiler/java/java_lazy_message_field.cc826
-rw-r--r--src/google/protobuf/compiler/java/java_lazy_message_field.h121
-rw-r--r--src/google/protobuf/compiler/java/java_message.cc1442
-rw-r--r--src/google/protobuf/compiler/java/java_message.h64
-rw-r--r--src/google/protobuf/compiler/java/java_message_field.cc1334
-rw-r--r--src/google/protobuf/compiler/java/java_message_field.h101
-rw-r--r--src/google/protobuf/compiler/java/java_name_resolver.cc266
-rw-r--r--src/google/protobuf/compiler/java/java_name_resolver.h124
-rw-r--r--src/google/protobuf/compiler/java/java_plugin_unittest.cc43
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field.cc804
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field.h85
-rw-r--r--src/google/protobuf/compiler/java/java_service.cc87
-rw-r--r--src/google/protobuf/compiler/java/java_service.h40
-rw-r--r--src/google/protobuf/compiler/java/java_shared_code_generator.cc201
-rw-r--r--src/google/protobuf/compiler/java/java_shared_code_generator.h90
-rw-r--r--src/google/protobuf/compiler/java/java_string_field.cc1056
-rw-r--r--src/google/protobuf/compiler/java/java_string_field.h160
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_file.h4
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_enum.cc40
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_enum_field.cc39
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_enum_field.h1
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_extension.cc2
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_field.h1
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_file.h4
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_generator.cc14
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_helpers.cc4
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_message.cc88
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_message.h2
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_message_field.cc21
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_message_field.h2
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_params.h38
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_primitive_field.cc8
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_primitive_field.h1
-rw-r--r--src/google/protobuf/compiler/main.cc4
-rw-r--r--src/google/protobuf/compiler/mock_code_generator.cc85
-rw-r--r--src/google/protobuf/compiler/mock_code_generator.h15
-rw-r--r--src/google/protobuf/compiler/package_info.h2
-rw-r--r--src/google/protobuf/compiler/parser.cc1158
-rw-r--r--src/google/protobuf/compiler/parser.h262
-rw-r--r--src/google/protobuf/compiler/parser_unittest.cc1372
-rw-r--r--src/google/protobuf/compiler/plugin.cc37
-rw-r--r--src/google/protobuf/compiler/plugin.h3
-rw-r--r--src/google/protobuf/compiler/plugin.pb.cc418
-rw-r--r--src/google/protobuf/compiler/plugin.pb.h482
-rw-r--r--src/google/protobuf/compiler/plugin.proto6
-rw-r--r--src/google/protobuf/compiler/python/python_generator.cc382
-rw-r--r--src/google/protobuf/compiler/python/python_generator.h19
-rw-r--r--src/google/protobuf/compiler/python/python_plugin_unittest.cc32
-rw-r--r--src/google/protobuf/compiler/subprocess.cc41
-rw-r--r--src/google/protobuf/compiler/subprocess.h7
-rw-r--r--src/google/protobuf/compiler/test_plugin.cc2
-rwxr-xr-xsrc/google/protobuf/compiler/zip_output_unittest.sh38
-rw-r--r--src/google/protobuf/compiler/zip_writer.cc36
-rw-r--r--src/google/protobuf/compiler/zip_writer.h36
-rw-r--r--src/google/protobuf/descriptor.cc1481
-rw-r--r--src/google/protobuf/descriptor.h378
-rw-r--r--src/google/protobuf/descriptor.pb.cc4636
-rw-r--r--src/google/protobuf/descriptor.pb.h4212
-rw-r--r--src/google/protobuf/descriptor.proto292
-rw-r--r--src/google/protobuf/descriptor_database.cc12
-rw-r--r--src/google/protobuf/descriptor_database.h9
-rw-r--r--src/google/protobuf/descriptor_database_unittest.cc2
-rw-r--r--src/google/protobuf/descriptor_pb2_test.py54
-rw-r--r--src/google/protobuf/descriptor_unittest.cc1707
-rw-r--r--src/google/protobuf/dynamic_message.cc262
-rw-r--r--src/google/protobuf/dynamic_message.h18
-rw-r--r--src/google/protobuf/dynamic_message_unittest.cc70
-rw-r--r--src/google/protobuf/extension_set.cc649
-rw-r--r--src/google/protobuf/extension_set.h490
-rw-r--r--src/google/protobuf/extension_set_heavy.cc303
-rw-r--r--src/google/protobuf/extension_set_unittest.cc471
-rw-r--r--src/google/protobuf/generated_enum_reflection.h91
-rw-r--r--src/google/protobuf/generated_message_reflection.cc636
-rw-r--r--src/google/protobuf/generated_message_reflection.h144
-rw-r--r--src/google/protobuf/generated_message_reflection_unittest.cc417
-rw-r--r--src/google/protobuf/generated_message_util.cc14
-rw-r--r--src/google/protobuf/generated_message_util.h60
-rw-r--r--src/google/protobuf/io/coded_stream.cc164
-rw-r--r--src/google/protobuf/io/coded_stream.h218
-rw-r--r--src/google/protobuf/io/coded_stream_inl.h13
-rw-r--r--src/google/protobuf/io/coded_stream_unittest.cc283
-rw-r--r--src/google/protobuf/io/gzip_stream.cc62
-rw-r--r--src/google/protobuf/io/gzip_stream.h16
-rwxr-xr-xsrc/google/protobuf/io/gzip_stream_unittest.sh2
-rw-r--r--src/google/protobuf/io/package_info.h2
-rw-r--r--src/google/protobuf/io/printer.cc20
-rw-r--r--src/google/protobuf/io/printer.h8
-rw-r--r--src/google/protobuf/io/printer_unittest.cc32
-rw-r--r--src/google/protobuf/io/strtod.cc113
-rw-r--r--src/google/protobuf/io/strtod.h50
-rw-r--r--src/google/protobuf/io/tokenizer.cc546
-rw-r--r--src/google/protobuf/io/tokenizer.h117
-rw-r--r--src/google/protobuf/io/tokenizer_unittest.cc358
-rw-r--r--src/google/protobuf/io/zero_copy_stream.cc11
-rw-r--r--src/google/protobuf/io/zero_copy_stream.h12
-rw-r--r--src/google/protobuf/io/zero_copy_stream_impl.cc13
-rw-r--r--src/google/protobuf/io/zero_copy_stream_impl.h3
-rw-r--r--src/google/protobuf/io/zero_copy_stream_impl_lite.cc24
-rw-r--r--src/google/protobuf/io/zero_copy_stream_impl_lite.h16
-rw-r--r--src/google/protobuf/io/zero_copy_stream_unittest.cc264
-rw-r--r--src/google/protobuf/lite_unittest.cc246
-rw-r--r--src/google/protobuf/message.cc55
-rw-r--r--src/google/protobuf/message.h264
-rw-r--r--src/google/protobuf/message_lite.cc9
-rw-r--r--src/google/protobuf/message_lite.h14
-rw-r--r--src/google/protobuf/message_unittest.cc154
-rw-r--r--src/google/protobuf/package_info.h2
-rw-r--r--src/google/protobuf/reflection_ops.cc25
-rw-r--r--src/google/protobuf/reflection_ops.h3
-rw-r--r--src/google/protobuf/reflection_ops_unittest.cc78
-rw-r--r--src/google/protobuf/repeated_field.cc28
-rw-r--r--src/google/protobuf/repeated_field.h547
-rw-r--r--src/google/protobuf/repeated_field_reflection_unittest.cc195
-rw-r--r--src/google/protobuf/repeated_field_unittest.cc522
-rw-r--r--src/google/protobuf/service.cc2
-rw-r--r--src/google/protobuf/service.h2
-rw-r--r--src/google/protobuf/stubs/atomicops.h227
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h325
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_arm_gcc.h151
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_arm_qnx.h146
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h122
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_generic_gcc.h137
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_macosx.h225
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_mips_gcc.h313
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_pnacl.h73
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_solaris.h188
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_tsan.h219
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc137
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_x86_gcc.h293
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc112
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_x86_msvc.h150
-rw-r--r--src/google/protobuf/stubs/common.cc42
-rw-r--r--src/google/protobuf/stubs/common.h129
-rw-r--r--src/google/protobuf/stubs/common_unittest.cc20
-rw-r--r--src/google/protobuf/stubs/hash.h14
-rw-r--r--src/google/protobuf/stubs/map_util.h771
-rw-r--r--src/google/protobuf/stubs/once.cc81
-rw-r--r--src/google/protobuf/stubs/once.h103
-rw-r--r--src/google/protobuf/stubs/once_unittest.cc2
-rw-r--r--src/google/protobuf/stubs/platform_macros.h103
-rw-r--r--src/google/protobuf/stubs/shared_ptr.h470
-rw-r--r--src/google/protobuf/stubs/stl_util.h121
-rw-r--r--src/google/protobuf/stubs/stringprintf.cc175
-rw-r--r--src/google/protobuf/stubs/stringprintf.h76
-rw-r--r--src/google/protobuf/stubs/stringprintf_unittest.cc152
-rw-r--r--src/google/protobuf/stubs/strutil.cc233
-rw-r--r--src/google/protobuf/stubs/strutil.h123
-rw-r--r--src/google/protobuf/stubs/strutil_unittest.cc12
-rw-r--r--src/google/protobuf/stubs/substitute.cc4
-rw-r--r--src/google/protobuf/stubs/substitute.h2
-rw-r--r--src/google/protobuf/stubs/template_util.h138
-rw-r--r--src/google/protobuf/stubs/template_util_unittest.cc130
-rw-r--r--src/google/protobuf/stubs/type_traits.h336
-rw-r--r--src/google/protobuf/stubs/type_traits_unittest.cc628
-rw-r--r--src/google/protobuf/test_util.cc687
-rw-r--r--src/google/protobuf/test_util.h45
-rw-r--r--src/google/protobuf/test_util_lite.cc191
-rw-r--r--src/google/protobuf/test_util_lite.h2
-rw-r--r--src/google/protobuf/testdata/bad_utf8_string1
-rw-r--r--src/google/protobuf/testdata/golden_messagebin487 -> 531 bytes
-rw-r--r--src/google/protobuf/testdata/golden_message_oneof_implementedbin0 -> 515 bytes
-rw-r--r--src/google/protobuf/testdata/text_format_unittest_data.txt18
-rw-r--r--src/google/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt129
-rw-r--r--src/google/protobuf/testdata/text_format_unittest_data_pointy.txt134
-rw-r--r--src/google/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt129
-rw-r--r--src/google/protobuf/testdata/text_format_unittest_extensions_data.txt18
-rw-r--r--src/google/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt134
-rw-r--r--src/google/protobuf/testing/file.cc20
-rw-r--r--src/google/protobuf/testing/file.h16
-rw-r--r--src/google/protobuf/testing/googletest.cc13
-rw-r--r--src/google/protobuf/testing/googletest.h18
-rw-r--r--src/google/protobuf/testing/zcgunzip.cc2
-rw-r--r--src/google/protobuf/testing/zcgzip.cc2
-rw-r--r--src/google/protobuf/text_format.cc871
-rw-r--r--src/google/protobuf/text_format.h247
-rw-r--r--src/google/protobuf/text_format_unittest.cc461
-rw-r--r--src/google/protobuf/unittest.proto251
-rw-r--r--src/google/protobuf/unittest_custom_options.proto120
-rw-r--r--src/google/protobuf/unittest_embed_optimize_for.proto2
-rw-r--r--src/google/protobuf/unittest_empty.proto2
-rw-r--r--src/google/protobuf/unittest_enormous_descriptor.proto2
-rw-r--r--src/google/protobuf/unittest_extension_nano.proto4
-rw-r--r--src/google/protobuf/unittest_import.proto5
-rw-r--r--src/google/protobuf/unittest_import_lite.proto4
-rw-r--r--src/google/protobuf/unittest_import_public.proto40
-rw-r--r--src/google/protobuf/unittest_import_public_lite.proto42
-rw-r--r--src/google/protobuf/unittest_lite.proto74
-rw-r--r--src/google/protobuf/unittest_lite_imports_nonlite.proto2
-rw-r--r--src/google/protobuf/unittest_mset.proto13
-rw-r--r--src/google/protobuf/unittest_no_generic_services.proto7
-rw-r--r--src/google/protobuf/unittest_optimize_for.proto9
-rw-r--r--src/google/protobuf/unknown_field_set.cc99
-rw-r--r--src/google/protobuf/unknown_field_set.h96
-rw-r--r--src/google/protobuf/unknown_field_set_unittest.cc97
-rw-r--r--src/google/protobuf/wire_format.cc106
-rw-r--r--src/google/protobuf/wire_format.h44
-rw-r--r--src/google/protobuf/wire_format_lite.cc128
-rw-r--r--src/google/protobuf/wire_format_lite.h57
-rw-r--r--src/google/protobuf/wire_format_lite_inl.h223
-rw-r--r--src/google/protobuf/wire_format_unittest.cc249
-rwxr-xr-xtest-driver139
-rwxr-xr-xvsprojects/extract_includes.bat8
-rw-r--r--vsprojects/libprotobuf-lite.vcproj38
-rw-r--r--vsprojects/libprotobuf.vcproj46
-rw-r--r--vsprojects/libprotoc.vcproj872
-rw-r--r--vsprojects/lite-test.vcproj38
-rw-r--r--vsprojects/protobuf.sln184
-rw-r--r--vsprojects/protoc.vcproj384
-rwxr-xr-xvsprojects/test_plugin.vcproj38
-rw-r--r--vsprojects/tests.vcproj62
612 files changed, 133576 insertions, 25718 deletions
diff --git a/.gitignore b/.gitignore
index ac1b297..992ab5c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,3 +55,4 @@ src/testzip.proto
src/testzip.zip
vsprojects/config.h
java/target/
+!prebuilts/**
diff --git a/Android.mk b/Android.mk
index f042d82..9b8d0ef 100644
--- a/Android.mk
+++ b/Android.mk
@@ -16,15 +16,18 @@
LOCAL_PATH := $(call my-dir)
-IGNORED_WARNINGS := -Wno-sign-compare -Wno-unused-parameter -Wno-sign-promo
+IGNORED_WARNINGS := -Wno-sign-compare -Wno-unused-parameter -Wno-sign-promo -Wno-error=return-type
CC_LITE_SRC_FILES := \
+ src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc \
+ src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc \
src/google/protobuf/stubs/common.cc \
src/google/protobuf/stubs/once.cc \
- src/google/protobuf/stubs/hash.cc \
src/google/protobuf/stubs/hash.h \
- src/google/protobuf/stubs/map-util.h \
- src/google/protobuf/stubs/stl_util-inl.h \
+ src/google/protobuf/stubs/map_util.h \
+ src/google/protobuf/stubs/shared_ptr.h \
+ src/google/protobuf/stubs/stringprintf.cc \
+ src/google/protobuf/stubs/stringprintf.h \
src/google/protobuf/extension_set.cc \
src/google/protobuf/generated_message_util.cc \
src/google/protobuf/message_lite.cc \
@@ -44,10 +47,30 @@ JAVA_LITE_SRC_FILES := \
java/src/main/java/com/google/protobuf/CodedInputStream.java \
java/src/main/java/com/google/protobuf/ExtensionRegistryLite.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/FieldSet.java \
java/src/main/java/com/google/protobuf/Internal.java \
java/src/main/java/com/google/protobuf/WireFormat.java \
- java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
+ java/src/main/java/com/google/protobuf/GeneratedMessageLite.java \
+ java/src/main/java/com/google/protobuf/BoundedByteString.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/LazyStringList.java \
+ java/src/main/java/com/google/protobuf/LazyStringArrayList.java \
+ java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java \
+ java/src/main/java/com/google/protobuf/LiteralByteString.java \
+ java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java \
+ java/src/main/java/com/google/protobuf/Parser.java \
+ java/src/main/java/com/google/protobuf/ProtocolStringList.java \
+ java/src/main/java/com/google/protobuf/RopeByteString.java \
+ java/src/main/java/com/google/protobuf/SmallSortedMap.java \
+ java/src/main/java/com/google/protobuf/Utf8.java
+
+# This contains more source files than needed for the full version, but the
+# additional files should not create any conflict.
+JAVA_FULL_SRC_FILES := \
+ $(call all-java-files-under, java/src/main/java) \
+ src/google/protobuf/descriptor.proto
COMPILER_SRC_FILES := \
src/google/protobuf/descriptor.cc \
@@ -88,17 +111,24 @@ COMPILER_SRC_FILES := \
src/google/protobuf/compiler/cpp/cpp_primitive_field.cc \
src/google/protobuf/compiler/cpp/cpp_service.cc \
src/google/protobuf/compiler/cpp/cpp_string_field.cc \
+ src/google/protobuf/compiler/java/java_context.cc \
src/google/protobuf/compiler/java/java_enum.cc \
src/google/protobuf/compiler/java/java_enum_field.cc \
src/google/protobuf/compiler/java/java_extension.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 \
+ src/google/protobuf/compiler/java/java_generator_factory.cc \
src/google/protobuf/compiler/java/java_helpers.cc \
+ src/google/protobuf/compiler/java/java_lazy_message_field.cc \
src/google/protobuf/compiler/java/java_message.cc \
src/google/protobuf/compiler/java/java_message_field.cc \
+ src/google/protobuf/compiler/java/java_name_resolver.cc \
src/google/protobuf/compiler/java/java_primitive_field.cc \
+ src/google/protobuf/compiler/java/java_shared_code_generator.cc \
src/google/protobuf/compiler/java/java_service.cc \
+ src/google/protobuf/compiler/java/java_string_field.cc \
+ src/google/protobuf/compiler/java/java_doc_comment.cc \
src/google/protobuf/compiler/javamicro/javamicro_enum.cc \
src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc \
src/google/protobuf/compiler/javamicro/javamicro_field.cc \
@@ -122,22 +152,25 @@ COMPILER_SRC_FILES := \
src/google/protobuf/io/coded_stream.cc \
src/google/protobuf/io/gzip_stream.cc \
src/google/protobuf/io/printer.cc \
+ src/google/protobuf/io/strtod.cc \
src/google/protobuf/io/tokenizer.cc \
src/google/protobuf/io/zero_copy_stream.cc \
src/google/protobuf/io/zero_copy_stream_impl.cc \
src/google/protobuf/io/zero_copy_stream_impl_lite.cc \
+ src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc \
+ src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc \
src/google/protobuf/stubs/common.cc \
- src/google/protobuf/stubs/hash.cc \
src/google/protobuf/stubs/once.cc \
src/google/protobuf/stubs/structurally_valid.cc \
src/google/protobuf/stubs/strutil.cc \
- src/google/protobuf/stubs/substitute.cc
+ src/google/protobuf/stubs/substitute.cc \
+ src/google/protobuf/stubs/stringprintf.cc
# Java nano library (for device-side users)
# =======================================================
include $(CLEAR_VARS)
-LOCAL_MODULE := libprotobuf-java-2.3.0-nano
+LOCAL_MODULE := libprotobuf-java-nano
LOCAL_MODULE_TAGS := optional
LOCAL_SDK_VERSION := 8
@@ -150,7 +183,7 @@ include $(BUILD_STATIC_JAVA_LIBRARY)
# =======================================================
include $(CLEAR_VARS)
-LOCAL_MODULE := host-libprotobuf-java-2.3.0-nano
+LOCAL_MODULE := host-libprotobuf-java-nano
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, java/src/main/java/com/google/protobuf/nano)
@@ -161,7 +194,7 @@ include $(BUILD_HOST_JAVA_LIBRARY)
# =======================================================
include $(CLEAR_VARS)
-LOCAL_MODULE := libprotobuf-java-2.3.0-micro
+LOCAL_MODULE := libprotobuf-java-micro
LOCAL_MODULE_TAGS := optional
LOCAL_SDK_VERSION := 8
@@ -173,7 +206,7 @@ include $(BUILD_STATIC_JAVA_LIBRARY)
# =======================================================
include $(CLEAR_VARS)
-LOCAL_MODULE := host-libprotobuf-java-2.3.0-micro
+LOCAL_MODULE := host-libprotobuf-java-micro
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, java/src/main/java/com/google/protobuf/micro)
@@ -184,9 +217,9 @@ include $(BUILD_HOST_JAVA_LIBRARY)
# =======================================================
include $(CLEAR_VARS)
-LOCAL_MODULE := libprotobuf-java-2.3.0-lite
+LOCAL_MODULE := libprotobuf-java-lite
LOCAL_MODULE_TAGS := optional
-LOCAL_SDK_VERSION := 8
+LOCAL_SDK_VERSION := 9
LOCAL_SRC_FILES := $(JAVA_LITE_SRC_FILES)
@@ -196,18 +229,29 @@ include $(BUILD_STATIC_JAVA_LIBRARY)
# =======================================================
include $(CLEAR_VARS)
-LOCAL_MODULE := host-libprotobuf-java-2.3.0-lite
+LOCAL_MODULE := host-libprotobuf-java-lite
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(JAVA_LITE_SRC_FILES)
include $(BUILD_HOST_JAVA_LIBRARY)
+# Java full library (for host-side users)
+# =======================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := host-libprotobuf-java-full
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(JAVA_FULL_SRC_FILES)
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
# C++ lite library
# =======================================================
include $(CLEAR_VARS)
-LOCAL_MODULE := libprotobuf-cpp-2.3.0-lite
+LOCAL_MODULE := libprotobuf-cpp-lite
LOCAL_MODULE_TAGS := optional
LOCAL_CPP_EXTENSION := .cc
@@ -243,6 +287,25 @@ LOCAL_NDK_STL_VARIANT := stlport_static
include $(BUILD_STATIC_LIBRARY)
+# C++ lite library (libc++ flavored for the platform)
+# =======================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libprotobuf-cpp-lite
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CPP_EXTENSION := .cc
+
+LOCAL_SRC_FILES := $(CC_LITE_SRC_FILES)
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/android \
+ $(LOCAL_PATH)/src
+
+LOCAL_CFLAGS := -DGOOGLE_PROTOBUF_NO_RTTI $(IGNORED_WARNINGS)
+
+include $(BUILD_SHARED_LIBRARY)
+
# C++ full library
# =======================================================
protobuf_cc_full_src_files := \
@@ -266,6 +329,7 @@ protobuf_cc_full_src_files := \
src/google/protobuf/wire_format.cc \
src/google/protobuf/io/gzip_stream.cc \
src/google/protobuf/io/printer.cc \
+ src/google/protobuf/io/strtod.cc \
src/google/protobuf/io/tokenizer.cc \
src/google/protobuf/io/zero_copy_stream_impl.cc \
src/google/protobuf/compiler/importer.cc \
@@ -275,7 +339,7 @@ protobuf_cc_full_src_files := \
# =======================================================
include $(CLEAR_VARS)
-LOCAL_MODULE := libprotobuf-cpp-2.3.0-full
+LOCAL_MODULE := libprotobuf-cpp-full
LOCAL_MODULE_TAGS := optional
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := $(protobuf_cc_full_src_files)
@@ -313,7 +377,7 @@ include $(BUILD_STATIC_LIBRARY)
# =======================================================
include $(CLEAR_VARS)
-LOCAL_MODULE := libprotobuf-cpp-2.3.0-full-gnustl-rtti
+LOCAL_MODULE := libprotobuf-cpp-full-gnustl-rtti
LOCAL_MODULE_TAGS := optional
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := $(protobuf_cc_full_src_files)
@@ -328,6 +392,24 @@ LOCAL_NDK_STL_VARIANT := gnustl_static
include $(BUILD_STATIC_LIBRARY)
+# C++ full library - libc++ version for the platform
+# =======================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libprotobuf-cpp-full
+LOCAL_MODULE_TAGS := optional
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_SRC_FILES := $(protobuf_cc_full_src_files)
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/android \
+ external/zlib \
+ $(LOCAL_PATH)/src
+
+LOCAL_CFLAGS := -DGOOGLE_PROTOBUF_NO_RTTI $(IGNORED_WARNINGS)
+LOCAL_SHARED_LIBRARIES := libz
+
+include $(BUILD_SHARED_LIBRARY)
+
# Clean temp vars
protobuf_cc_full_src_files :=
@@ -342,6 +424,10 @@ LOCAL_MODULE := aprotoc
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_TAGS := optional
+# Use the system's libstdc++ (libc++ on mac) because we copy aprotoc to
+# unbundled projects where libc++.so may not be available.
+LOCAL_CXX_STL := libstdc++
+
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := $(COMPILER_SRC_FILES)
@@ -393,6 +479,8 @@ include $(CLEAR_VARS)
LOCAL_MODULE := android-nano-test-parcelable
LOCAL_MODULE_TAGS := tests
LOCAL_SDK_VERSION := current
+# Only needed at compile-time.
+LOCAL_JAVA_LIBRARIES := android-support-annotations
LOCAL_PROTOC_OPTIMIZE_TYPE := nano
@@ -401,7 +489,8 @@ LOCAL_SRC_FILES := src/google/protobuf/unittest_simple_nano.proto
LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/src
LOCAL_PROTO_JAVA_OUTPUT_PARAMS := \
- parcelable_messages = true
+ parcelable_messages = true, \
+ generate_intdefs = true
include $(BUILD_STATIC_JAVA_LIBRARY)
@@ -411,6 +500,8 @@ include $(CLEAR_VARS)
LOCAL_MODULE := android-nano-test-parcelable-extendable
LOCAL_MODULE_TAGS := tests
LOCAL_SDK_VERSION := current
+# Only needed at compile-time.
+LOCAL_JAVA_LIBRARIES := android-support-annotations
LOCAL_PROTOC_OPTIMIZE_TYPE := nano
@@ -420,6 +511,7 @@ LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/src
LOCAL_PROTO_JAVA_OUTPUT_PARAMS := \
parcelable_messages = true, \
+ generate_intdefs = true, \
store_unknown_fields = true
include $(BUILD_STATIC_JAVA_LIBRARY)
@@ -437,10 +529,11 @@ LOCAL_SRC_FILES := $(call all-java-files-under, java/src/device/test/java/com/go
LOCAL_MANIFEST_FILE := java/src/device/test/AndroidManifest.xml
-LOCAL_STATIC_JAVA_LIBRARIES := libprotobuf-java-2.3.0-nano \
+LOCAL_STATIC_JAVA_LIBRARIES := libprotobuf-java-nano \
android-nano-test-parcelable \
android-nano-test-parcelable-extendable
LOCAL_DEX_PREOPT := false
include $(BUILD_PACKAGE)
+
diff --git a/CHANGES.txt b/CHANGES.txt
index eebd57d..0d0ac81 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,209 @@
-2009-01-08 version 2.3.0:
+2014-10-20 version 2.6.1:
+
+ C++
+ * Added atomicops support for Solaris.
+ * Released memory allocated by InitializeDefaultRepeatedFields() and
+ GetEmptyString(). Some memory sanitizers reported them as memory leaks.
+
+ Java
+ * Updated DynamicMessage.setField() to handle repeated enum values
+ correctly.
+ * Fixed a bug that caused NullPointerException to be thrown when
+ converting manually constructed FileDescriptorProto to
+ FileDescriptor.
+
+ Python
+ * Fixed WhichOneof() to work with de-serialized protobuf messages.
+ * Fixed a missing file problem of Python C++ implementation.
+
+2014-08-15 version 2.6.0:
+
+ General
+ * Added oneofs(unions) feature. Fields in the same oneof will share
+ memory and at most one field can be set at the same time. Use the
+ oneof keyword to define a oneof like:
+ message SampleMessage {
+ oneof test_oneof {
+ string name = 4;
+ YourMessage sub_message = 9;
+ }
+ }
+ * Files, services, enums, messages, methods and enum values can be marked
+ as deprecated now.
+ * Added Support for list values, including lists of mesaages, when
+ parsing text-formatted protos in C++ and Java.
+ For example: foo: [1, 2, 3]
+
+ C++
+ * Enhanced customization on TestFormat printing.
+ * Added SwapFields() in reflection API to swap a subset of fields.
+ Added SetAllocatedMessage() in reflection API.
+ * Repeated primitive extensions are now packable. The
+ [packed=true] option only affects serializers. Therefore, it is
+ possible to switch a repeated extension field to packed format
+ without breaking backwards-compatibility.
+ * Various speed optimizations.
+
+ Java
+ * writeTo() method in ByteString can now write a substring to an
+ output stream. Added endWith() method for ByteString.
+ * ByteString and ByteBuffer are now supported in CodedInputStream
+ and CodedOutputStream.
+ * java_generate_equals_and_hash can now be used with the LITE_RUNTIME.
+
+ Python
+ * A new C++-backed extension module (aka "cpp api v2") that replaces the
+ old ("cpp api v1") one. Much faster than the pure Python code. This one
+ resolves many bugs and is recommended for general use over the
+ pure Python when possible.
+ * Descriptors now have enum_types_by_name and extension_types_by_name dict
+ attributes.
+ * Support for Python 3.
+
+2013-02-27 version 2.5.0:
+
+ General
+ * New notion "import public" that allows a proto file to forward the content
+ it imports to its importers. For example,
+ // foo.proto
+ import public "bar.proto";
+ import "baz.proto";
+
+ // qux.proto
+ import "foo.proto";
+ // Stuff defined in bar.proto may be used in this file, but stuff from
+ // baz.proto may NOT be used without importing it explicitly.
+ This is useful for moving proto files. To move a proto file, just leave
+ a single "import public" in the old proto file.
+ * New enum option "allow_alias" that specifies whether different symbols can
+ be assigned the same numeric value. Default value is "true". Setting it to
+ false causes the compiler to reject enum definitions where multiple symbols
+ have the same numeric value.
+ Note: We plan to flip the default value to "false" in a future release.
+ Projects using enum aliases should set the option to "true" in their .proto
+ files.
+
+ C++
+ * New generated method set_allocated_foo(Type* foo) for message and string
+ fields. This method allows you to set the field to a pre-allocated object
+ and the containing message takes the ownership of that object.
+ * Added SetAllocatedExtension() and ReleaseExtension() to extensions API.
+ * Custom options are now formatted correctly when descriptors are printed in
+ text format.
+ * Various speed optimizations.
+
+ Java
+ * Comments in proto files are now collected and put into generated code as
+ comments for corresponding classes and data members.
+ * Added Parser to parse directly into messages without a Builder. For
+ example,
+ Foo foo = Foo.PARSER.ParseFrom(input);
+ Using Parser is ~25% faster than using Builder to parse messages.
+ * Added getters/setters to access the underlying ByteString of a string field
+ directly.
+ * ByteString now supports more operations: substring(), prepend(), and
+ append(). The implementation of ByteString uses a binary tree structure
+ to support these operations efficiently.
+ * New method findInitializationErrors() that lists all missing required
+ fields.
+ * Various code size and speed optimizations.
+
+ Python
+ * Added support for dynamic message creation. DescriptorDatabase,
+ DescriptorPool, and MessageFactory work like their C++ couterparts to
+ simplify Descriptor construction from *DescriptorProtos, and MessageFactory
+ provides a message instance from a Descriptor.
+ * Added pickle support for protobuf messages.
+ * Unknown fields are now preserved after parsing.
+ * Fixed bug where custom options were not correctly populated. Custom
+ options can be accessed now.
+ * Added EnumTypeWrapper that provides better accessibility to enum types.
+ * Added ParseMessage(descriptor, bytes) to generate a new Message instance
+ from a descriptor and a byte string.
+
+2011-05-01 version 2.4.1:
+
+ C++
+ * Fixed the frendship problem for old compilers to make the library now gcc 3
+ compatible again.
+ * Fixed vcprojects/extract_includes.bat to extract compiler/plugin.h.
+
+ Java
+ * Removed usages of JDK 1.6 only features to make the library now JDK 1.5
+ compatible again.
+ * Fixed a bug about negative enum values.
+ * serialVersionUID is now defined in generated messages for java serializing.
+ * Fixed protoc to use java.lang.Object, which makes "Object" now a valid
+ message name again.
+
+ Python
+ * Experimental C++ implementation now requires C++ protobuf library installed.
+ See the README.txt in the python directory for details.
+
+2011-02-02 version 2.4.0:
+
+ General
+ * The RPC (cc|java|py)_generic_services default value is now false instead of
+ true.
+ * Custom options can have aggregate types. For example,
+ message MyOption {
+ optional string comment = 1;
+ optional string author = 2;
+ }
+ extend google.protobuf.FieldOptions {
+ optional MyOption myoption = 12345;
+ }
+ This option can now be set as follows:
+ message SomeType {
+ optional int32 field = 1 [(myoption) = { comment:'x' author:'y' }];
+ }
+
+ C++
+ * Various speed and code size optimizations.
+ * Added a release_foo() method on string and message fields.
+ * Fixed gzip_output_stream sub-stream handling.
+
+ Java
+ * Builders now maintain sub-builders for sub-messages. Use getFooBuilder() to
+ get the builder for the sub-message "foo". This allows you to repeatedly
+ modify deeply-nested sub-messages without rebuilding them.
+ * Builder.build() no longer invalidates the Builder for generated messages
+ (You may continue to modify it and then build another message).
+ * Code generator will generate efficient equals() and hashCode()
+ implementations if new option java_generate_equals_and_hash is enabled.
+ (Otherwise, reflection-based implementations are used.)
+ * Generated messages now implement Serializable.
+ * Fields with [deprecated=true] will be marked with @Deprecated in Java.
+ * Added lazy conversion of UTF-8 encoded strings to String objects to improve
+ performance.
+ * Various optimizations.
+ * Enum value can be accessed directly, instead of calling getNumber() on the
+ enum member.
+ * For each enum value, an integer constant is also generated with the suffix
+ _VALUE.
+
+ Python
+ * Added an experimental C++ implementation for Python messages via a Python
+ extension. Implementation type is controlled by an environment variable
+ PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION (valid values: "cpp" and "python")
+ The default value is currently "python" but will be changed to "cpp" in
+ future release.
+ * Improved performance on message instantiation significantly.
+ Most of the work on message instantiation is done just once per message
+ class, instead of once per message instance.
+ * Improved performance on text message parsing.
+ * Allow add() to forward keyword arguments to the concrete class.
+ E.g. instead of
+ item = repeated_field.add()
+ item.foo = bar
+ item.baz = quux
+ You can do:
+ repeated_field.add(foo=bar, baz=quux)
+ * Added a sort() interface to the BaseContainer.
+ * Added an extend() method to repeated composite fields.
+ * Added UTF8 debug string support.
+
+2010-01-08 version 2.3.0:
General
* Parsers for repeated numeric fields now always accept both packed and
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index a20efc4..717ffc1 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -50,7 +50,7 @@ Patch contributors:
text format.
Brian Atkinson <nairb774@gmail.com>
* Added @Override annotation to generated Java code where appropriate.
- Vincent Choinire <Choiniere.Vincent@hydro.qc.ca>
+ Vincent Choinière <Choiniere.Vincent@hydro.qc.ca>
* Tru64 support.
Monty Taylor <monty.taylor@gmail.com>
* Solaris 10 + Sun Studio fixes.
@@ -80,5 +80,14 @@ Patch contributors:
* Fixes for Solaris 10 32/64-bit confusion.
Evan Jones <evanj@mit.edu>
* Optimize Java serialization code when writing a small message to a stream.
+ * Optimize Java serialization of strings so that UTF-8 encoding happens only
+ once per string per serialization call.
+ * Clean up some Java warnings.
+ * Fix bug with permanent callbacks that delete themselves when run.
Michael Kucharski <m.kucharski@gmail.com>
* Added CodedInputStream.getTotalBytesRead().
+ Kacper Kowalik <xarthisius.kk@gmail.com>
+ * Fixed m4/acx_pthread.m4 problem for some Linux distributions.
+ William Orr <will@worrbase.com>
+ * Fixed detection of sched_yield on Solaris.
+ * Added atomicops for Solaris
diff --git a/COPYING.txt b/LICENSE
index 705db57..705db57 100644
--- a/COPYING.txt
+++ b/LICENSE
diff --git a/Makefile.am b/Makefile.am
index b65daee..24e5e55 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,9 +38,9 @@ pkgconfig_DATA = protobuf.pc protobuf-lite.pc
EXTRA_DIST = \
autogen.sh \
generate_descriptor_proto.sh \
- README.txt \
+ README.md \
INSTALL.txt \
- COPYING.txt \
+ LICENSE \
CONTRIBUTORS.txt \
CHANGES.txt \
editors/README.txt \
@@ -69,13 +69,16 @@ EXTRA_DIST = \
examples/list_people.py \
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/BlockingRpcChannel.java \
java/src/main/java/com/google/protobuf/BlockingService.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/DynamicMessage.java \
+ java/src/main/java/com/google/protobuf/Extension.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 \
@@ -83,57 +86,157 @@ EXTRA_DIST = \
java/src/main/java/com/google/protobuf/GeneratedMessageLite.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/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/Parser.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/Service.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/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/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/DynamicMessageTest.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/IsValidUtf8Test.java \
+ java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java \
+ java/src/test/java/com/google/protobuf/LazyFieldTest.java \
+ java/src/test/java/com/google/protobuf/LazyFieldLiteTest.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/LiteralByteStringTest.java \
java/src/test/java/com/google/protobuf/LiteTest.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/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/UnknownFieldSetTest.java \
+ java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \
java/src/test/java/com/google/protobuf/WireFormatTest.java \
+ 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/multiple_files_test.proto \
+ java/src/test/java/com/google/protobuf/nested_builders_test.proto \
+ java/src/test/java/com/google/protobuf/nested_extension_lite.proto \
+ java/src/test/java/com/google/protobuf/nested_extension.proto \
+ java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto \
+ java/src/test/java/com/google/protobuf/non_nested_extension.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/pom.xml \
java/README.txt \
- python/google/protobuf/internal/generator_test.py \
+ python/google/protobuf/internal/api_implementation.cc \
+ python/google/protobuf/internal/api_implementation.py \
+ python/google/protobuf/internal/api_implementation_default_test.py \
python/google/protobuf/internal/containers.py \
+ python/google/protobuf/internal/cpp_message.py \
python/google/protobuf/internal/decoder.py \
+ python/google/protobuf/internal/descriptor_database_test.py \
+ python/google/protobuf/internal/descriptor_pool_test.py \
+ python/google/protobuf/internal/descriptor_pool_test1.proto \
+ python/google/protobuf/internal/descriptor_pool_test2.proto \
+ python/google/protobuf/internal/descriptor_python_test.py \
python/google/protobuf/internal/descriptor_test.py \
python/google/protobuf/internal/encoder.py \
+ 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/generator_test.py \
+ python/google/protobuf/internal/message_factory_python_test.py \
+ python/google/protobuf/internal/message_factory_test.py \
python/google/protobuf/internal/message_listener.py \
+ python/google/protobuf/internal/message_python_test.py \
python/google/protobuf/internal/message_test.py \
+ python/google/protobuf/internal/missing_enum_values.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/python_message.py \
python/google/protobuf/internal/reflection_test.py \
python/google/protobuf/internal/service_reflection_test.py \
+ python/google/protobuf/internal/symbol_database_test.py \
+ python/google/protobuf/internal/test_bad_identifiers.proto \
python/google/protobuf/internal/test_util.py \
+ python/google/protobuf/internal/text_encoding_test.py \
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/wire_format.py \
python/google/protobuf/internal/wire_format_test.py \
python/google/protobuf/internal/__init__.py \
+ python/google/protobuf/pyext/README \
+ python/google/protobuf/pyext/cpp_message.py \
+ python/google/protobuf/pyext/descriptor.h \
+ python/google/protobuf/pyext/descriptor.cc \
+ python/google/protobuf/pyext/descriptor_cpp2_test.py \
+ python/google/protobuf/pyext/extension_dict.h \
+ python/google/protobuf/pyext/extension_dict.cc \
+ python/google/protobuf/pyext/message.h \
+ python/google/protobuf/pyext/message.cc \
+ python/google/protobuf/pyext/message_factory_cpp2_test.py \
+ 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/reflection_cpp2_generated_test.py \
+ 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_scalar_container.cc \
+ 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/message.py \
+ python/google/protobuf/message_factory.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 \
diff --git a/Makefile.in b/Makefile.in
index d13f7c7..93d7a44 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -16,6 +15,51 @@
@SET_MAKE@
VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -36,11 +80,11 @@ build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = .
-DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in $(srcdir)/config.h.in \
- $(srcdir)/protobuf-lite.pc.in $(srcdir)/protobuf.pc.in \
- $(top_srcdir)/configure config.guess config.sub depcomp \
- install-sh ltmain.sh missing
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/configure $(am__configure_deps) \
+ $(srcdir)/config.h.in $(srcdir)/protobuf.pc.in \
+ $(srcdir)/protobuf-lite.pc.in compile config.guess config.sub \
+ depcomp install-sh missing ltmain.sh
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ac_system_extensions.m4 \
$(top_srcdir)/m4/acx_check_suncc.m4 \
@@ -56,15 +100,33 @@ mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES = protobuf.pc protobuf-lite.pc
CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
SOURCES =
DIST_SOURCES =
-RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
- html-recursive info-recursive install-data-recursive \
- install-dvi-recursive install-exec-recursive \
- install-html-recursive install-info-recursive \
- install-pdf-recursive install-ps-recursive install-recursive \
- installcheck-recursive installdirs-recursive pdf-recursive \
- ps-recursive uninstall-recursive
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -96,11 +158,33 @@ am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
DATA = $(pkgconfig_DATA)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
-AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
- $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
- distdir dist dist-all distcheck
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+ $(LISP)config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
+CSCOPE = cscope
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -110,6 +194,7 @@ am__remove_distdir = \
&& rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
@@ -137,12 +222,14 @@ am__relativize = \
reldir="$$dir2"
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
+DIST_TARGETS = dist-gzip
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
@@ -159,6 +246,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -182,10 +270,13 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -213,6 +304,7 @@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
@@ -247,7 +339,6 @@ libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
@@ -282,9 +373,9 @@ pkgconfig_DATA = protobuf.pc protobuf-lite.pc
EXTRA_DIST = \
autogen.sh \
generate_descriptor_proto.sh \
- README.txt \
+ README.md \
INSTALL.txt \
- COPYING.txt \
+ LICENSE \
CONTRIBUTORS.txt \
CHANGES.txt \
editors/README.txt \
@@ -313,13 +404,16 @@ EXTRA_DIST = \
examples/list_people.py \
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/BlockingRpcChannel.java \
java/src/main/java/com/google/protobuf/BlockingService.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/DynamicMessage.java \
+ java/src/main/java/com/google/protobuf/Extension.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 \
@@ -327,57 +421,157 @@ EXTRA_DIST = \
java/src/main/java/com/google/protobuf/GeneratedMessageLite.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/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/Parser.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/Service.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/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/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/DynamicMessageTest.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/IsValidUtf8Test.java \
+ java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java \
+ java/src/test/java/com/google/protobuf/LazyFieldTest.java \
+ java/src/test/java/com/google/protobuf/LazyFieldLiteTest.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/LiteralByteStringTest.java \
java/src/test/java/com/google/protobuf/LiteTest.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/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/UnknownFieldSetTest.java \
+ java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \
java/src/test/java/com/google/protobuf/WireFormatTest.java \
+ 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/multiple_files_test.proto \
+ java/src/test/java/com/google/protobuf/nested_builders_test.proto \
+ java/src/test/java/com/google/protobuf/nested_extension_lite.proto \
+ java/src/test/java/com/google/protobuf/nested_extension.proto \
+ java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto \
+ java/src/test/java/com/google/protobuf/non_nested_extension.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/pom.xml \
java/README.txt \
- python/google/protobuf/internal/generator_test.py \
+ python/google/protobuf/internal/api_implementation.cc \
+ python/google/protobuf/internal/api_implementation.py \
+ python/google/protobuf/internal/api_implementation_default_test.py \
python/google/protobuf/internal/containers.py \
+ python/google/protobuf/internal/cpp_message.py \
python/google/protobuf/internal/decoder.py \
+ python/google/protobuf/internal/descriptor_database_test.py \
+ python/google/protobuf/internal/descriptor_pool_test.py \
+ python/google/protobuf/internal/descriptor_pool_test1.proto \
+ python/google/protobuf/internal/descriptor_pool_test2.proto \
+ python/google/protobuf/internal/descriptor_python_test.py \
python/google/protobuf/internal/descriptor_test.py \
python/google/protobuf/internal/encoder.py \
+ 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/generator_test.py \
+ python/google/protobuf/internal/message_factory_python_test.py \
+ python/google/protobuf/internal/message_factory_test.py \
python/google/protobuf/internal/message_listener.py \
+ python/google/protobuf/internal/message_python_test.py \
python/google/protobuf/internal/message_test.py \
+ python/google/protobuf/internal/missing_enum_values.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/python_message.py \
python/google/protobuf/internal/reflection_test.py \
python/google/protobuf/internal/service_reflection_test.py \
+ python/google/protobuf/internal/symbol_database_test.py \
+ python/google/protobuf/internal/test_bad_identifiers.proto \
python/google/protobuf/internal/test_util.py \
+ python/google/protobuf/internal/text_encoding_test.py \
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/wire_format.py \
python/google/protobuf/internal/wire_format_test.py \
python/google/protobuf/internal/__init__.py \
+ python/google/protobuf/pyext/README \
+ python/google/protobuf/pyext/cpp_message.py \
+ python/google/protobuf/pyext/descriptor.h \
+ python/google/protobuf/pyext/descriptor.cc \
+ python/google/protobuf/pyext/descriptor_cpp2_test.py \
+ python/google/protobuf/pyext/extension_dict.h \
+ python/google/protobuf/pyext/extension_dict.cc \
+ python/google/protobuf/pyext/message.h \
+ python/google/protobuf/pyext/message.cc \
+ python/google/protobuf/pyext/message_factory_cpp2_test.py \
+ 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/reflection_cpp2_generated_test.py \
+ 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_scalar_container.cc \
+ 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/message.py \
+ python/google/protobuf/message_factory.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 \
@@ -414,7 +608,7 @@ all: config.h
.SUFFIXES:
am--refresh: Makefile
@:
-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -441,20 +635,20 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
-$(top_srcdir)/configure: $(am__configure_deps)
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
-$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
config.h: stamp-h1
- @if test ! -f $@; then rm -f stamp-h1; else :; fi
- @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
+ @test -f $@ || rm -f stamp-h1
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
-$(srcdir)/config.h.in: $(am__configure_deps)
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
@@ -476,8 +670,11 @@ distclean-libtool:
-rm -f libtool config.lt
install-pkgconfigDATA: $(pkgconfig_DATA)
@$(NORMAL_INSTALL)
- test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -494,22 +691,25 @@ uninstall-pkgconfigDATA:
dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
# This directory's subdirectories are mostly independent; you can cd
-# into them and run `make' without going through this Makefile.
-# To change the values of `make' variables: instead of editing Makefiles,
-# (1) if the variable is set in `config.status', edit `config.status'
-# (which will cause the Makefiles to be regenerated when you run `make');
-# (2) otherwise, pass the desired values on the `make' command line.
-$(RECURSIVE_TARGETS):
- @fail= failcom='exit 1'; \
- for f in x $$MAKEFLAGS; do \
- case $$f in \
- *=* | --[!k]*);; \
- *k*) failcom='fail=yes';; \
- esac; \
- done; \
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
@@ -524,57 +724,12 @@ $(RECURSIVE_TARGETS):
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
-$(RECURSIVE_CLEAN_TARGETS):
- @fail= failcom='exit 1'; \
- for f in x $$MAKEFLAGS; do \
- case $$f in \
- *=* | --[!k]*);; \
- *k*) failcom='fail=yes';; \
- esac; \
- done; \
- dot_seen=no; \
- case "$@" in \
- distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
- *) list='$(SUBDIRS)' ;; \
- esac; \
- rev=''; for subdir in $$list; do \
- if test "$$subdir" = "."; then :; else \
- rev="$$subdir $$rev"; \
- fi; \
- done; \
- rev="$$rev ."; \
- target=`echo $@ | sed s/-recursive//`; \
- for subdir in $$rev; do \
- echo "Making $$target in $$subdir"; \
- if test "$$subdir" = "."; then \
- local_target="$$target-am"; \
- else \
- local_target="$$target"; \
- fi; \
- ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
- || eval $$failcom; \
- done && test -z "$$fail"
-tags-recursive:
- list='$(SUBDIRS)'; for subdir in $$list; do \
- test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
- done
-ctags-recursive:
- list='$(SUBDIRS)'; for subdir in $$list; do \
- test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
- done
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
@@ -590,12 +745,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
- list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ $(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
@@ -607,15 +757,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$$unique; \
fi; \
fi
-ctags: CTAGS
-CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
@@ -624,9 +770,31 @@ GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+ test ! -s cscope.files \
+ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+ -rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+ -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(DISTFILES)
$(am__remove_distdir)
@@ -662,13 +830,10 @@ distdir: $(DISTFILES)
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
- test -d "$(distdir)/$$subdir" \
- || $(MKDIR_P) "$(distdir)/$$subdir" \
- || exit 1; \
- fi; \
- done
- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
@@ -697,40 +862,42 @@ distdir: $(DISTFILES)
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-lzip: distdir
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
- $(am__remove_distdir)
-
-dist-lzma: distdir
- tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-tarZ: distdir
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-shar: distdir
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
-dist dist-all: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
+dist dist-all:
+ $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+ $(am__post_remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
@@ -741,8 +908,6 @@ distcheck: dist
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
- *.tar.lzma*) \
- lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.lz*) \
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \
@@ -754,18 +919,19 @@ distcheck: dist
*.zip*) \
unzip $(distdir).zip ;;\
esac
- chmod -R a-w $(distdir); chmod a+w $(distdir)
- mkdir $(distdir)/_build
- mkdir $(distdir)/_inst
+ chmod -R a-w $(distdir)
+ chmod u+w $(distdir)
+ mkdir $(distdir)/_build $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build \
- && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ && ../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
+ --srcdir=.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
@@ -788,7 +954,7 @@ distcheck: dist
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
@@ -928,13 +1094,12 @@ ps-am:
uninstall-am: uninstall-pkgconfigDATA
-.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check-am \
- ctags-recursive install-am install-strip tags-recursive
+.MAKE: $(am__recursive_targets) all check-am install-am install-strip
-.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
- all all-am am--refresh check check-am check-local clean \
- clean-generic clean-libtool clean-local ctags ctags-recursive \
- dist dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma \
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+ am--refresh check check-am check-local clean clean-cscope \
+ clean-generic clean-libtool clean-local cscope cscopelist-am \
+ ctags ctags-am dist dist-all dist-bzip2 dist-gzip dist-lzip \
dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \
distclean-generic distclean-hdr distclean-libtool \
distclean-tags distcleancheck distdir distuninstallcheck dvi \
@@ -946,7 +1111,7 @@ uninstall-am: uninstall-pkgconfigDATA
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
- ps ps-am tags tags-recursive uninstall uninstall-am \
+ ps ps-am tags tags-am uninstall uninstall-am \
uninstall-pkgconfigDATA
diff --git a/README.txt b/README.md
index a8f6604..5fbb344 100644
--- a/README.txt
+++ b/README.md
@@ -1,17 +1,32 @@
Protocol Buffers - Google's data interchange format
+===================================================
+
Copyright 2008 Google Inc.
-http://code.google.com/apis/protocolbuffers/
+
+https://developers.google.com/protocol-buffers/
C++ Installation - Unix
-=======================
+-----------------------
+
+If you get the source from github, you need to generate the configure script
+first:
+
+ $ ./autogen.sh
+
+This will download gtest 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 gtest 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
- $ make install
+ $ ./configure
+ $ make
+ $ make check
+ $ make install
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.
@@ -21,7 +36,7 @@ Proceed at your own risk.
For advanced usage information on configure and make, see INSTALL.txt.
-** Hint on install location **
+**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.
@@ -33,7 +48,7 @@ For advanced usage information on configure and make, see INSTALL.txt.
If you already built the package with a different prefix, make sure
to run "make clean" before building again.
-** Compiling dependent packages **
+**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,
@@ -71,7 +86,7 @@ For advanced usage information on configure and make, see INSTALL.txt.
If you only want protobuf-lite, substitute "protobuf-lite" in place
of "protobuf" in these examples.
-** Note for cross-compiling **
+**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
@@ -94,7 +109,7 @@ For advanced usage information on configure and make, see INSTALL.txt.
has the same version as the protobuf source code you are trying to
use it with.
-** Note for Solaris users **
+**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
@@ -104,7 +119,7 @@ For advanced usage information on configure and make, see INSTALL.txt.
See src/solaris/libstdc++.la for more info on this bug.
-** Note for HP C++ Tru64 users **
+**Note for HP C++ Tru64 users**
To compile invoke configure as follows:
@@ -113,15 +128,15 @@ For advanced usage information on configure and make, see INSTALL.txt.
Also, you will need to use gmake instead of make.
C++ Installation - Windows
-==========================
+--------------------------
-If you are using Micosoft Visual C++, see vsprojects/readme.txt.
+If you are using Microsoft Visual C++, see vsprojects/readme.txt.
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.
@@ -132,10 +147,10 @@ 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
+ ./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
@@ -144,9 +159,9 @@ Note that both of them require you to first install the Protocol
Buffer compiler (protoc), which is part of the C++ package.
Usage
-=====
+-----
The complete documentation for Protocol Buffers is available via the
web at:
- http://code.google.com/apis/protocolbuffers/
+ https://developers.google.com/protocol-buffers/
diff --git a/aclocal.m4 b/aclocal.m4
index 375941e..bb4cc70 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,8 +1,7 @@
-# generated automatically by aclocal 1.11.3 -*- Autoconf -*-
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
-# Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -12,33 +11,31 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,
-[m4_warning([this file was generated for autoconf 2.68.
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
-To do so, use the procedure documented by the package, typically `autoreconf'.])])
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
-
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.11'
+[am__api_version='1.14'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.3], [],
+m4_if([$1], [1.14.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -54,24 +51,22 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.3])dnl
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
-
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
-# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
-# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory. The problem is that $srcdir (and
@@ -90,7 +85,7 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir. In an in-source build this is usually
-# harmless because $srcdir is `.', but things will broke when you
+# harmless because $srcdir is '.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
@@ -116,22 +111,19 @@ am_aux_dir=`cd $ac_aux_dir && pwd`
# AM_CONDITIONAL -*- Autoconf -*-
-# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 9
-
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
-[AC_PREREQ(2.52)dnl
- ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
- [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])dnl
AC_SUBST([$1_FALSE])dnl
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
@@ -150,16 +142,14 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
-# 2010, 2011 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 12
-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
@@ -169,7 +159,7 @@ fi])])
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
-# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
@@ -182,12 +172,13 @@ AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
-ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
- [$1], CXX, [depcc="$CXX" am_compiler_list=],
- [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
- [$1], UPC, [depcc="$UPC" am_compiler_list=],
- [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
- [depcc="$$1" am_compiler_list=])
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
@@ -195,8 +186,8 @@ AC_CACHE_CHECK([dependency style of $depcc],
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
@@ -236,16 +227,16 @@ AC_CACHE_CHECK([dependency style of $depcc],
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
@@ -254,8 +245,8 @@ AC_CACHE_CHECK([dependency style of $depcc],
test "$am__universal" = false || continue
;;
nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
if test "x$enable_dependency_tracking" = xyes; then
continue
else
@@ -263,7 +254,7 @@ AC_CACHE_CHECK([dependency style of $depcc],
fi
;;
msvc7 | msvc7msys | msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
+ # This compiler won't grok '-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
@@ -311,7 +302,7 @@ AM_CONDITIONAL([am__fastdep$1], [
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
-# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
AC_DEFUN([AM_SET_DEPDIR],
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
@@ -321,9 +312,13 @@ AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
-[AC_ARG_ENABLE(dependency-tracking,
-[ --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors])
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
@@ -338,20 +333,18 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-#serial 5
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[{
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
@@ -364,7 +357,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
+ # We used to match only the files named 'Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
@@ -376,21 +369,19 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
+ # from the Makefile without running 'make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
+ test -z "$am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
@@ -408,7 +399,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
-# is enabled. FIXME. This creates each `.P' file that we will
+# is enabled. FIXME. This creates each '.P' file that we will
# need in order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
@@ -418,18 +409,21 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# Do all the work for Automake. -*- Autoconf -*-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 16
-
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
@@ -442,7 +436,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.62])dnl
+[AC_PREREQ([2.65])dnl
dnl Autoconf wants to disallow AM_ names. We explicitly allow
dnl the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
@@ -471,31 +465,40 @@ AC_SUBST([CYGPATH_W])
# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
-[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+[AC_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
-m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
_AM_IF_OPTION([no-define],,
-[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
-AM_MISSING_PROG(AUTOCONF, autoconf)
-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
-AM_MISSING_PROG(AUTOHEADER, autoheader)
-AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
-AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
@@ -506,34 +509,78 @@ _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
[_AM_PROG_TAR([v7])])])
_AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC],
- [_AM_DEPENDENCIES(CC)],
- [define([AC_PROG_CC],
- defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+ [_AM_DEPENDENCIES([CC])],
+ [m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX],
- [_AM_DEPENDENCIES(CXX)],
- [define([AC_PROG_CXX],
- defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
- [_AM_DEPENDENCIES(OBJC)],
- [define([AC_PROG_OBJC],
- defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
])
-_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
-dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
-dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
-dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
-])
-dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+ fi
+fi])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
dnl mangled by Autoconf and run in a shell conditional statement.
m4_define([_AC_COMPILER_EXEEXT],
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
-
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
@@ -555,15 +602,12 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
-# Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
-
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
@@ -577,16 +621,14 @@ if test x"${install_sh}" != xset; then
install_sh="\${SHELL} $am_aux_dir/install-sh"
esac
fi
-AC_SUBST(install_sh)])
+AC_SUBST([install_sh])])
-# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 2
-
# Check whether the underlying file-system supports filenames
# with a leading dot. For instance MS-DOS doesn't.
AC_DEFUN([AM_SET_LEADING_DOT],
@@ -600,15 +642,49 @@ fi
rmdir .tst 2>/dev/null
AC_SUBST([am__leading_dot])])
-# Check to see how 'make' treats includes. -*- Autoconf -*-
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
-# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 4
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless 'enable' is passed literally.
+# For symmetry, 'disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+ [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
+ am_maintainer_other[ make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer])],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
# AM_MAKE_INCLUDE()
# -----------------
@@ -627,7 +703,7 @@ am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
+# Ignore all kinds of additional output from 'make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
@@ -654,15 +730,12 @@ rm -f confinc confmf
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 6
-
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
@@ -670,11 +743,10 @@ AC_DEFUN([AM_MISSING_PROG],
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
-
# AM_MISSING_HAS_RUN
# ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([missing])dnl
@@ -687,54 +759,22 @@ if test x"${MISSING+set}" != xset; then
esac
fi
# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
else
am_missing_run=
- AC_MSG_WARN([`missing' script is too old or missing])
+ AC_MSG_WARN(['missing' script is too old or missing])
fi
])
-# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
-# Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 1
-
-# AM_PROG_MKDIR_P
-# ---------------
-# Check for `mkdir -p'.
-AC_DEFUN([AM_PROG_MKDIR_P],
-[AC_PREREQ([2.60])dnl
-AC_REQUIRE([AC_PROG_MKDIR_P])dnl
-dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
-dnl while keeping a definition of mkdir_p for backward compatibility.
-dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
-dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
-dnl Makefile.ins that do not define MKDIR_P, so we do our own
-dnl adjustment using top_builddir (which is defined more often than
-dnl MKDIR_P).
-AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
-case $mkdir_p in
- [[\\/$]]* | ?:[[\\/]]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-])
-
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 5
-
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
@@ -744,7 +784,7 @@ AC_DEFUN([_AM_MANGLE_OPTION],
# --------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
-[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
# _AM_SET_OPTIONS(OPTIONS)
# ------------------------
@@ -758,24 +798,82 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-# Check to make sure that the build environment is sane. -*- Autoconf -*-
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
-# Free Software Foundation, Inc.
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+ [whether $CC understands -c and -o together],
+ [am_cv_prog_cc_c_o],
+ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 5
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+ ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftest.file
# Reject unsafe characters in $srcdir or the absolute working directory
# name. Accept space and tab only in the latter.
am_lf='
@@ -786,32 +884,40 @@ case `pwd` in
esac
case $srcdir in
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
- AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
esac
-# Do `set' in a subshell so we don't clobber the current shell's
+# Do 'set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$[*]" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- rm -f conftest.file
- if test "$[*]" != "X $srcdir/configure conftest.file" \
- && test "$[*]" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
-alias in your environment])
- fi
-
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+ alias in your environment])
+ fi
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
test "$[2]" = conftest.file
)
then
@@ -821,46 +927,118 @@ else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
-AC_MSG_RESULT(yes)])
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
-# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+ [--enable-silent-rules],
+ [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+ [--disable-silent-rules],
+ [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+ [am_cv_make_support_nested_variables],
+ [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
# AM_PROG_INSTALL_STRIP
# ---------------------
-# One issue with vendor `install' (even GNU) is that you can't
+# One issue with vendor 'install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
-# always use install-sh in `make install-strip', and initialize
+# always use install-sh in "make install-strip", and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 3
-
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
@@ -874,18 +1052,16 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 2
-
# _AM_PROG_TAR(FORMAT)
# --------------------
# Check how to create a tarball in format FORMAT.
-# FORMAT should be one of `v7', `ustar', or `pax'.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
#
# Substitute a variable $(am__tar) that is a command
# writing to stdout a FORMAT-tarball containing the directory
@@ -895,76 +1071,114 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Substitute a variable $(am__untar) that extract such
# a tarball read from stdin.
# $(am__untar) < result.tar
+#
AC_DEFUN([_AM_PROG_TAR],
[# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AC_SUBST([AMTAR], ['$${TAR-tar}'])
-m4_if([$1], [v7],
- [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
- [m4_case([$1], [ustar],, [pax],,
- [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
+
+# We'll loop over all known methods to create a tar archive until one works.
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of `-'.
-for _am_tool in $_am_tools
-do
- case $_am_tool in
- gnutar)
- for _am_tar in tar gnutar gtar;
- do
- AM_RUN_LOG([$_am_tar --version]) && break
- done
- am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
- am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
- am__untar="$_am_tar -xf -"
- ;;
- plaintar)
- # Must skip GNU tar: if it does not support --format= it doesn't create
- # ustar tarball either.
- (tar --version) >/dev/null 2>&1 && continue
- am__tar='tar chf - "$$tardir"'
- am__tar_='tar chf - "$tardir"'
- am__untar='tar xf -'
- ;;
- pax)
- am__tar='pax -L -x $1 -w "$$tardir"'
- am__tar_='pax -L -x $1 -w "$tardir"'
- am__untar='pax -r'
- ;;
- cpio)
- am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
- am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
- am__untar='cpio -i -H $1 -d'
- ;;
- none)
- am__tar=false
- am__tar_=false
- am__untar=false
- ;;
- esac
- # If the value was cached, stop now. We just wanted to have am__tar
- # and am__untar set.
- test -n "${am_cv_prog_tar_$1}" && break
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
+
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ for _am_tool in $_am_tools; do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar; do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
- # tar/untar a dummy directory, and stop if the command works
- rm -rf conftest.dir
- mkdir conftest.dir
- echo GrepMe > conftest.dir/file
- AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ AM_RUN_LOG([cat conftest.dir/file])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
rm -rf conftest.dir
- if test -s conftest.tar; then
- AM_RUN_LOG([$am__untar <conftest.tar])
- grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
- fi
-done
-rm -rf conftest.dir
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+ AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+ AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
diff --git a/autogen.sh b/autogen.sh
index 04d65b1..c3e026d 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -18,9 +18,9 @@ fi
# Check that gtest is present. Usually it is already there since the
# directory is set up as an SVN external.
if test ! -e gtest; then
- echo "Google Test not present. Fetching gtest-1.3.0 from the web..."
- curl http://googletest.googlecode.com/files/gtest-1.3.0.tar.bz2 | tar jx
- mv gtest-1.3.0 gtest
+ echo "Google Test not present. Fetching gtest-1.5.0 from the web..."
+ curl http://googletest.googlecode.com/files/gtest-1.5.0.tar.bz2 | tar jx
+ mv gtest-1.5.0 gtest
fi
set -ex
diff --git a/benchmarks/ProtoBench.java b/benchmarks/ProtoBench.java
new file mode 100644
index 0000000..86d62fe
--- /dev/null
+++ b/benchmarks/ProtoBench.java
@@ -0,0 +1,203 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2009 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.protocolbuffers;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.lang.reflect.Method;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.CodedInputStream;
+import com.google.protobuf.CodedOutputStream;
+import com.google.protobuf.Message;
+
+public class ProtoBench {
+
+ private static final long MIN_SAMPLE_TIME_MS = 2 * 1000;
+ private static final long TARGET_TIME_MS = 30 * 1000;
+
+ private ProtoBench() {
+ // Prevent instantiation
+ }
+
+ public static void main(String[] args) {
+ if (args.length < 2 || (args.length % 2) != 0) {
+ System.err.println("Usage: ProtoBench <descriptor type name> <input data>");
+ System.err.println("The descriptor type name is the fully-qualified message name,");
+ System.err.println("e.g. com.google.protocolbuffers.benchmark.Message1");
+ System.err.println("(You can specify multiple pairs of descriptor type name and input data.)");
+ System.exit(1);
+ }
+ boolean success = true;
+ for (int i = 0; i < args.length; i += 2) {
+ success &= runTest(args[i], args[i + 1]);
+ }
+ System.exit(success ? 0 : 1);
+ }
+
+ /**
+ * Runs a single test. Error messages are displayed to stderr, and the return value
+ * indicates general success/failure.
+ */
+ public static boolean runTest(String type, String file) {
+ System.out.println("Benchmarking " + type + " with file " + file);
+ final Message defaultMessage;
+ try {
+ Class<?> clazz = Class.forName(type);
+ Method method = clazz.getDeclaredMethod("getDefaultInstance");
+ defaultMessage = (Message) method.invoke(null);
+ } catch (Exception e) {
+ // We want to do the same thing with all exceptions. Not generally nice,
+ // but this is slightly different.
+ System.err.println("Unable to get default message for " + type);
+ return false;
+ }
+
+ try {
+ final byte[] inputData = readAllBytes(file);
+ final ByteArrayInputStream inputStream = new ByteArrayInputStream(inputData);
+ final ByteString inputString = ByteString.copyFrom(inputData);
+ final Message sampleMessage = defaultMessage.newBuilderForType().mergeFrom(inputString).build();
+ FileOutputStream devNullTemp = null;
+ CodedOutputStream reuseDevNullTemp = null;
+ try {
+ devNullTemp = new FileOutputStream("/dev/null");
+ reuseDevNullTemp = CodedOutputStream.newInstance(devNullTemp);
+ } catch (FileNotFoundException e) {
+ // ignore: this is probably Windows, where /dev/null does not exist
+ }
+ final FileOutputStream devNull = devNullTemp;
+ final CodedOutputStream reuseDevNull = reuseDevNullTemp;
+ benchmark("Serialize to byte string", inputData.length, new Action() {
+ public void execute() { sampleMessage.toByteString(); }
+ });
+ benchmark("Serialize to byte array", inputData.length, new Action() {
+ public void execute() { sampleMessage.toByteArray(); }
+ });
+ benchmark("Serialize to memory stream", inputData.length, new Action() {
+ public void execute() throws IOException {
+ sampleMessage.writeTo(new ByteArrayOutputStream());
+ }
+ });
+ if (devNull != null) {
+ benchmark("Serialize to /dev/null with FileOutputStream", inputData.length, new Action() {
+ public void execute() throws IOException {
+ sampleMessage.writeTo(devNull);
+ }
+ });
+ benchmark("Serialize to /dev/null reusing FileOutputStream", inputData.length, new Action() {
+ public void execute() throws IOException {
+ sampleMessage.writeTo(reuseDevNull);
+ reuseDevNull.flush(); // force the write to the OutputStream
+ }
+ });
+ }
+ benchmark("Deserialize from byte string", inputData.length, new Action() {
+ public void execute() throws IOException {
+ defaultMessage.newBuilderForType().mergeFrom(inputString).build();
+ }
+ });
+ benchmark("Deserialize from byte array", inputData.length, new Action() {
+ public void execute() throws IOException {
+ defaultMessage.newBuilderForType()
+ .mergeFrom(CodedInputStream.newInstance(inputData)).build();
+ }
+ });
+ benchmark("Deserialize from memory stream", inputData.length, new Action() {
+ public void execute() throws IOException {
+ defaultMessage.newBuilderForType()
+ .mergeFrom(CodedInputStream.newInstance(inputStream)).build();
+ inputStream.reset();
+ }
+ });
+ System.out.println();
+ return true;
+ } catch (Exception e) {
+ System.err.println("Error: " + e.getMessage());
+ System.err.println("Detailed exception information:");
+ e.printStackTrace(System.err);
+ return false;
+ }
+ }
+
+ private static void benchmark(String name, long dataSize, Action action) throws IOException {
+ // Make sure it's JITted "reasonably" hard before running the first progress test
+ for (int i=0; i < 100; i++) {
+ action.execute();
+ }
+
+ // Run it progressively more times until we've got a reasonable sample
+ int iterations = 1;
+ long elapsed = timeAction(action, iterations);
+ while (elapsed < MIN_SAMPLE_TIME_MS) {
+ iterations *= 2;
+ elapsed = timeAction(action, iterations);
+ }
+
+ // Upscale the sample to the target time. Do this in floating point arithmetic
+ // to avoid overflow issues.
+ iterations = (int) ((TARGET_TIME_MS / (double) elapsed) * iterations);
+ elapsed = timeAction(action, iterations);
+ System.out.println(name + ": " + iterations + " iterations in "
+ + (elapsed/1000f) + "s; "
+ + (iterations * dataSize) / (elapsed * 1024 * 1024 / 1000f)
+ + "MB/s");
+ }
+
+ private static long timeAction(Action action, int iterations) throws IOException {
+ System.gc();
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < iterations; i++) {
+ action.execute();
+ }
+ long end = System.currentTimeMillis();
+ return end - start;
+ }
+
+ private static byte[] readAllBytes(String filename) throws IOException {
+ RandomAccessFile file = new RandomAccessFile(new File(filename), "r");
+ byte[] content = new byte[(int) file.length()];
+ file.readFully(content);
+ return content;
+ }
+
+ /**
+ * Interface used to capture a single action to benchmark.
+ */
+ interface Action {
+ void execute() throws IOException;
+ }
+}
diff --git a/benchmarks/google_message1.dat b/benchmarks/google_message1.dat
new file mode 100644
index 0000000..bc0f064
--- /dev/null
+++ b/benchmarks/google_message1.dat
Binary files differ
diff --git a/benchmarks/google_message2.dat b/benchmarks/google_message2.dat
new file mode 100644
index 0000000..06c0944
--- /dev/null
+++ b/benchmarks/google_message2.dat
Binary files differ
diff --git a/benchmarks/google_size.proto b/benchmarks/google_size.proto
new file mode 100644
index 0000000..3e6fbdb
--- /dev/null
+++ b/benchmarks/google_size.proto
@@ -0,0 +1,136 @@
+package benchmarks;
+
+option java_outer_classname = "GoogleSize";
+option optimize_for = CODE_SIZE;
+
+message SizeMessage1 {
+ required string field1 = 1;
+ optional string field9 = 9;
+ optional string field18 = 18;
+ optional bool field80 = 80 [default=false];
+ optional bool field81 = 81 [default=true];
+ required int32 field2 = 2;
+ required int32 field3 = 3;
+ optional int32 field280 = 280;
+ optional int32 field6 = 6 [default=0];
+ optional int64 field22 = 22;
+ optional string field4 = 4;
+ repeated fixed64 field5 = 5;
+ optional bool field59 = 59 [default=false];
+ optional string field7 = 7;
+ optional int32 field16 = 16;
+ optional int32 field130 = 130 [default=0];
+ optional bool field12 = 12 [default=true];
+ optional bool field17 = 17 [default=true];
+ optional bool field13 = 13 [default=true];
+ optional bool field14 = 14 [default=true];
+ optional int32 field104 = 104 [default=0];
+ optional int32 field100 = 100 [default=0];
+ optional int32 field101 = 101 [default=0];
+ optional string field102 = 102;
+ optional string field103 = 103;
+ optional int32 field29 = 29 [default=0];
+ optional bool field30 = 30 [default=false];
+ optional int32 field60 = 60 [default=-1];
+ optional int32 field271 = 271 [default=-1];
+ optional int32 field272 = 272 [default=-1];
+ optional int32 field150 = 150;
+ optional int32 field23 = 23 [default=0];
+ optional bool field24 = 24 [default=false];
+ optional int32 field25 = 25 [default=0];
+ optional SizeMessage1SubMessage field15 = 15;
+ optional bool field78 = 78;
+ optional int32 field67 = 67 [default=0];
+ optional int32 field68 = 68;
+ optional int32 field128 = 128 [default=0];
+ optional string field129 = 129 [default="xxxxxxxxxxxxxxxxxxxxx"];
+ optional int32 field131 = 131 [default=0];
+}
+
+message SizeMessage1SubMessage {
+ optional int32 field1 = 1 [default=0];
+ optional int32 field2 = 2 [default=0];
+ optional int32 field3 = 3 [default=0];
+ optional string field15 = 15;
+ optional bool field12 = 12 [default=true];
+ optional int64 field13 = 13;
+ optional int64 field14 = 14;
+ optional int32 field16 = 16;
+ optional int32 field19 = 19 [default=2];
+ optional bool field20 = 20 [default=true];
+ optional bool field28 = 28 [default=true];
+ optional fixed64 field21 = 21;
+ optional int32 field22 = 22;
+ optional bool field23 = 23 [ default=false ];
+ optional bool field206 = 206 [default=false];
+ optional fixed32 field203 = 203;
+ optional int32 field204 = 204;
+ optional string field205 = 205;
+ optional uint64 field207 = 207;
+ optional uint64 field300 = 300;
+}
+
+message SizeMessage2 {
+ optional string field1 = 1;
+ optional int64 field3 = 3;
+ optional int64 field4 = 4;
+ optional int64 field30 = 30;
+ optional bool field75 = 75 [default=false];
+ optional string field6 = 6;
+ optional bytes field2 = 2;
+ optional int32 field21 = 21 [default=0];
+ optional int32 field71 = 71;
+ optional float field25 = 25;
+ optional int32 field109 = 109 [default=0];
+ optional int32 field210 = 210 [default=0];
+ optional int32 field211 = 211 [default=0];
+ optional int32 field212 = 212 [default=0];
+ optional int32 field213 = 213 [default=0];
+ optional int32 field216 = 216 [default=0];
+ optional int32 field217 = 217 [default=0];
+ optional int32 field218 = 218 [default=0];
+ optional int32 field220 = 220 [default=0];
+ optional int32 field221 = 221 [default=0];
+ optional float field222 = 222 [default=0.0];
+ optional int32 field63 = 63;
+
+ repeated group Group1 = 10 {
+ required float field11 = 11;
+ optional float field26 = 26;
+ optional string field12 = 12;
+ optional string field13 = 13;
+ repeated string field14 = 14;
+ required uint64 field15 = 15;
+ optional int32 field5 = 5;
+ optional string field27 = 27;
+ optional int32 field28 = 28;
+ optional string field29 = 29;
+ optional string field16 = 16;
+ repeated string field22 = 22;
+ repeated int32 field73 = 73;
+ optional int32 field20 = 20 [default=0];
+ optional string field24 = 24;
+ optional SizeMessage2GroupedMessage field31 = 31;
+ }
+ repeated string field128 = 128;
+ optional int64 field131 = 131;
+ repeated string field127 = 127;
+ optional int32 field129 = 129;
+ repeated int64 field130 = 130;
+ optional bool field205 = 205 [default=false];
+ optional bool field206 = 206 [default=false];
+}
+
+message SizeMessage2GroupedMessage {
+ optional float field1 = 1;
+ optional float field2 = 2;
+ optional float field3 = 3 [default=0.0];
+ optional bool field4 = 4;
+ optional bool field5 = 5;
+ optional bool field6 = 6 [default=true];
+ optional bool field7 = 7 [default=false];
+ optional float field8 = 8;
+ optional bool field9 = 9;
+ optional float field10 = 10;
+ optional int64 field11 = 11;
+}
diff --git a/benchmarks/google_speed.proto b/benchmarks/google_speed.proto
new file mode 100644
index 0000000..d6cd032
--- /dev/null
+++ b/benchmarks/google_speed.proto
@@ -0,0 +1,136 @@
+package benchmarks;
+
+option java_outer_classname = "GoogleSpeed";
+option optimize_for = SPEED;
+
+message SpeedMessage1 {
+ required string field1 = 1;
+ optional string field9 = 9;
+ optional string field18 = 18;
+ optional bool field80 = 80 [default=false];
+ optional bool field81 = 81 [default=true];
+ required int32 field2 = 2;
+ required int32 field3 = 3;
+ optional int32 field280 = 280;
+ optional int32 field6 = 6 [default=0];
+ optional int64 field22 = 22;
+ optional string field4 = 4;
+ repeated fixed64 field5 = 5;
+ optional bool field59 = 59 [default=false];
+ optional string field7 = 7;
+ optional int32 field16 = 16;
+ optional int32 field130 = 130 [default=0];
+ optional bool field12 = 12 [default=true];
+ optional bool field17 = 17 [default=true];
+ optional bool field13 = 13 [default=true];
+ optional bool field14 = 14 [default=true];
+ optional int32 field104 = 104 [default=0];
+ optional int32 field100 = 100 [default=0];
+ optional int32 field101 = 101 [default=0];
+ optional string field102 = 102;
+ optional string field103 = 103;
+ optional int32 field29 = 29 [default=0];
+ optional bool field30 = 30 [default=false];
+ optional int32 field60 = 60 [default=-1];
+ optional int32 field271 = 271 [default=-1];
+ optional int32 field272 = 272 [default=-1];
+ optional int32 field150 = 150;
+ optional int32 field23 = 23 [default=0];
+ optional bool field24 = 24 [default=false];
+ optional int32 field25 = 25 [default=0];
+ optional SpeedMessage1SubMessage field15 = 15;
+ optional bool field78 = 78;
+ optional int32 field67 = 67 [default=0];
+ optional int32 field68 = 68;
+ optional int32 field128 = 128 [default=0];
+ optional string field129 = 129 [default="xxxxxxxxxxxxxxxxxxxxx"];
+ optional int32 field131 = 131 [default=0];
+}
+
+message SpeedMessage1SubMessage {
+ optional int32 field1 = 1 [default=0];
+ optional int32 field2 = 2 [default=0];
+ optional int32 field3 = 3 [default=0];
+ optional string field15 = 15;
+ optional bool field12 = 12 [default=true];
+ optional int64 field13 = 13;
+ optional int64 field14 = 14;
+ optional int32 field16 = 16;
+ optional int32 field19 = 19 [default=2];
+ optional bool field20 = 20 [default=true];
+ optional bool field28 = 28 [default=true];
+ optional fixed64 field21 = 21;
+ optional int32 field22 = 22;
+ optional bool field23 = 23 [ default=false ];
+ optional bool field206 = 206 [default=false];
+ optional fixed32 field203 = 203;
+ optional int32 field204 = 204;
+ optional string field205 = 205;
+ optional uint64 field207 = 207;
+ optional uint64 field300 = 300;
+}
+
+message SpeedMessage2 {
+ optional string field1 = 1;
+ optional int64 field3 = 3;
+ optional int64 field4 = 4;
+ optional int64 field30 = 30;
+ optional bool field75 = 75 [default=false];
+ optional string field6 = 6;
+ optional bytes field2 = 2;
+ optional int32 field21 = 21 [default=0];
+ optional int32 field71 = 71;
+ optional float field25 = 25;
+ optional int32 field109 = 109 [default=0];
+ optional int32 field210 = 210 [default=0];
+ optional int32 field211 = 211 [default=0];
+ optional int32 field212 = 212 [default=0];
+ optional int32 field213 = 213 [default=0];
+ optional int32 field216 = 216 [default=0];
+ optional int32 field217 = 217 [default=0];
+ optional int32 field218 = 218 [default=0];
+ optional int32 field220 = 220 [default=0];
+ optional int32 field221 = 221 [default=0];
+ optional float field222 = 222 [default=0.0];
+ optional int32 field63 = 63;
+
+ repeated group Group1 = 10 {
+ required float field11 = 11;
+ optional float field26 = 26;
+ optional string field12 = 12;
+ optional string field13 = 13;
+ repeated string field14 = 14;
+ required uint64 field15 = 15;
+ optional int32 field5 = 5;
+ optional string field27 = 27;
+ optional int32 field28 = 28;
+ optional string field29 = 29;
+ optional string field16 = 16;
+ repeated string field22 = 22;
+ repeated int32 field73 = 73;
+ optional int32 field20 = 20 [default=0];
+ optional string field24 = 24;
+ optional SpeedMessage2GroupedMessage field31 = 31;
+ }
+ repeated string field128 = 128;
+ optional int64 field131 = 131;
+ repeated string field127 = 127;
+ optional int32 field129 = 129;
+ repeated int64 field130 = 130;
+ optional bool field205 = 205 [default=false];
+ optional bool field206 = 206 [default=false];
+}
+
+message SpeedMessage2GroupedMessage {
+ optional float field1 = 1;
+ optional float field2 = 2;
+ optional float field3 = 3 [default=0.0];
+ optional bool field4 = 4;
+ optional bool field5 = 5;
+ optional bool field6 = 6 [default=true];
+ optional bool field7 = 7 [default=false];
+ optional float field8 = 8;
+ optional bool field9 = 9;
+ optional float field10 = 10;
+ optional int64 field11 = 11;
+}
diff --git a/benchmarks/readme.txt b/benchmarks/readme.txt
new file mode 100644
index 0000000..2c836d0
--- /dev/null
+++ b/benchmarks/readme.txt
@@ -0,0 +1,50 @@
+Contents
+--------
+
+This folder contains three kinds of file:
+
+- Code, such as ProtoBench.java, to build the benchmarking framework.
+- Protocol buffer definitions (.proto files)
+- Sample data files
+
+If we end up with a lot of different benchmarks it may be worth
+separating these out info different directories, but while there are
+so few they might as well all be together.
+
+Running a benchmark (Java)
+--------------------------
+
+1) Build protoc and the Java protocol buffer library. The examples
+ below assume a jar file (protobuf.jar) has been built and copied
+ into this directory.
+
+2) Build ProtoBench:
+ $ javac -d tmp -cp protobuf.jar ProtoBench.java
+
+3) Generate code for the relevant benchmark protocol buffer, e.g.
+ $ protoc --java_out=tmp google_size.proto google_speed.proto
+
+4) Build the generated code, e.g.
+ $ cd tmp
+ $ javac -d . -cp ../protobuf.jar benchmarks/*.java
+
+5) Run the test. Arguments are given in pairs - the first argument
+ is the descriptor type; the second is the filename. For example:
+ $ java -cp .;../protobuf.jar com.google.protocolbuffers.ProtoBench
+ benchmarks.GoogleSize$SizeMessage1 ../google_message1.dat
+ benchmarks.GoogleSpeed$SpeedMessage1 ../google_message1.dat
+ benchmarks.GoogleSize$SizeMessage2 ../google_message2.dat
+ benchmarks.GoogleSpeed$SpeedMessage2 ../google_message2.dat
+
+6) Wait! Each test runs for around 30 seconds, and there are 6 tests
+ per class/data combination. The above command would therefore take
+ about 12 minutes to run.
+
+
+Benchmarks available
+--------------------
+
+From Google:
+google_size.proto and google_speed.proto, messages
+google_message1.dat and google_message2.dat. The proto files are
+equivalent, but optimized differently.
diff --git a/build.gradle b/build.gradle
index 95c9b1d..4684592 100644
--- a/build.gradle
+++ b/build.gradle
@@ -55,7 +55,7 @@ jar {
from sourceSets.nano.output, sourceSets.micro.output
baseName "libprotobuf"
appendix "java"
- version "2.3"
+ version "2.6"
classifier "micronano"
}
@@ -64,7 +64,7 @@ task nanoJar(type: Jar) {
dependsOn nanoClasses
baseName "libprotobuf"
appendix "java"
- version "2.3"
+ version "2.6"
classifier "nano"
}
@@ -73,7 +73,7 @@ task microJar(type: Jar) {
dependsOn microClasses
baseName "libprotobuf"
appendix "java"
- version "2.3"
+ version "2.6"
classifier "micro"
}
diff --git a/compile b/compile
new file mode 100755
index 0000000..531136b
--- /dev/null
+++ b/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" "" $nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv/,$2, in
+ *,$file_conv,*)
+ ;;
+ mingw/*)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin/*)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine/*)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+ func_file_conv "$1"
+ if test -z "$lib_path"; then
+ lib_path=$file
+ else
+ lib_path="$lib_path;$file"
+ fi
+ linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+ lib=$1
+ found=no
+ save_IFS=$IFS
+ IFS=';'
+ for dir in $lib_path $LIB
+ do
+ IFS=$save_IFS
+ if $shared && test -f "$dir/$lib.dll.lib"; then
+ found=yes
+ lib=$dir/$lib.dll.lib
+ break
+ fi
+ if test -f "$dir/$lib.lib"; then
+ found=yes
+ lib=$dir/$lib.lib
+ break
+ fi
+ if test -f "$dir/lib$lib.a"; then
+ found=yes
+ lib=$dir/lib$lib.a
+ break
+ fi
+ done
+ IFS=$save_IFS
+
+ if test "$found" != yes; then
+ lib=$lib.lib
+ fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+ # Assume a capable shell
+ lib_path=
+ shared=:
+ linker_opts=
+ for arg
+ do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ eat=1
+ case $2 in
+ *.o | *.[oO][bB][jJ])
+ func_file_conv "$2"
+ set x "$@" -Fo"$file"
+ shift
+ ;;
+ *)
+ func_file_conv "$2"
+ set x "$@" -Fe"$file"
+ shift
+ ;;
+ esac
+ ;;
+ -I)
+ eat=1
+ func_file_conv "$2" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -I*)
+ func_file_conv "${1#-I}" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -l)
+ eat=1
+ func_cl_dashl "$2"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -l*)
+ func_cl_dashl "${1#-l}"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -L)
+ eat=1
+ func_cl_dashL "$2"
+ ;;
+ -L*)
+ func_cl_dashL "${1#-L}"
+ ;;
+ -static)
+ shared=false
+ ;;
+ -Wl,*)
+ arg=${1#-Wl,}
+ save_ifs="$IFS"; IFS=','
+ for flag in $arg; do
+ IFS="$save_ifs"
+ linker_opts="$linker_opts $flag"
+ done
+ IFS="$save_ifs"
+ ;;
+ -Xlinker)
+ eat=1
+ linker_opts="$linker_opts $2"
+ ;;
+ -*)
+ set x "$@" "$1"
+ shift
+ ;;
+ *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+ func_file_conv "$1"
+ set x "$@" -Tp"$file"
+ shift
+ ;;
+ *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+ func_file_conv "$1" mingw
+ set x "$@" "$file"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+ done
+ if test -n "$linker_opts"; then
+ linker_opts="-link$linker_opts"
+ fi
+ exec "$@" $linker_opts
+ exit 1
+}
+
+eat=
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+ cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+ func_cl_wrapper "$@" # Doesn't return...
+ ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ # So we strip '-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no '-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # '.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/config.guess b/config.guess
index 278f9e9..b79252d 100755
--- a/config.guess
+++ b/config.guess
@@ -1,14 +1,12 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
+# Copyright 1992-2013 Free Software Foundation, Inc.
-timestamp='2007-07-22'
+timestamp='2013-06-10'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@@ -17,26 +15,22 @@ timestamp='2007-07-22'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Originally written by Per Bothner <per@bothner.com>.
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner.
#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+
me=`echo "$0" | sed -e 's,.*/,,'`
@@ -56,8 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -139,12 +132,33 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ ;;
+esac
+
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
@@ -170,7 +184,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep __ELF__ >/dev/null
+ | grep -q __ELF__
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
@@ -180,7 +194,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
fi
;;
*)
- os=netbsd
+ os=netbsd
;;
esac
# The OS release
@@ -201,6 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
@@ -223,7 +241,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
@@ -269,7 +287,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit ;;
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@@ -295,12 +316,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
- echo powerpc-ibm-os400
+ echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
- arm:riscos:*:*|arm:RISCOS:*:*)
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@@ -324,14 +345,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -375,23 +415,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
+ exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
@@ -461,8 +501,8 @@ EOF
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@@ -475,7 +515,7 @@ EOF
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
@@ -532,7 +572,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
- *:AIX:*:[45])
+ *:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@@ -575,52 +615,52 @@ EOF
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
+ esac ;;
+ esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ sed 's/^ //' << EOF >$dummy.c
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
@@ -640,7 +680,7 @@ EOF
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep __LP64__ >/dev/null
+ grep -q __LP64__
then
HP_ARCH="hppa2.0w"
else
@@ -711,22 +751,22 @@ EOF
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
- exit ;;
+ exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
- exit ;;
+ exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
- exit ;;
+ exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
- exit ;;
+ exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
- exit ;;
+ exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
@@ -750,14 +790,14 @@ EOF
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@@ -769,40 +809,51 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
- case ${UNAME_MACHINE} in
- pc98)
- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
+ i*:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
- *:Interix*:[3456]*)
- case ${UNAME_MACHINE} in
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
- EM64T | authenticamd)
+ authenticamd | genuineintel | EM64T)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
@@ -823,203 +874,157 @@ EOF
exit ;;
*:GNU:*:*)
# the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
arm*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
exit ;;
avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
cris:Linux:*:*)
- echo cris-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
crisv32:Linux:*:*)
- echo crisv32-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
frv:Linux:*:*)
- echo frv-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
- mips:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips
- #undef mipsel
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mipsel
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- mips64:Linux:*:*)
+ mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
- #undef mips64
- #undef mips64el
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
+ CPU=${UNAME_MACHINE}el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
+ CPU=${UNAME_MACHINE}
#else
CPU=
#endif
#endif
EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
+ or1k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
or32:Linux:*:*)
- echo or32-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
esac
exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
- xtensa:Linux:*:*)
- echo xtensa-unknown-linux-gnu
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
- i*86:Linux:*:*)
- # The BFD linker knows what the default object file format is, so
- # first see if it will tell us. cd to the root directory to prevent
- # problems with other programs or directories called `ld' in the path.
- # Set LC_ALL=C to ensure ld outputs messages in English.
- ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
- | sed -ne '/supported targets:/!d
- s/[ ][ ]*/ /g
- s/.*supported targets: *//
- s/ .*//
- p'`
- case "$ld_supported_targets" in
- elf32-i386)
- TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
- ;;
- a.out-i386-linux)
- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit ;;
- "")
- # Either a pre-BFD a.out linker (linux-gnuoldld) or
- # one that does not give us useful --help.
- echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit ;;
- esac
- # Determine whether the default compiler is a.out or elf
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <features.h>
- #ifdef __ELF__
- # ifdef __GLIBC__
- # if __GLIBC__ >= 2
- LIBC=gnu
- # else
- LIBC=gnulibc1
- # endif
- # else
- LIBC=gnulibc1
- # endif
- #else
- #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
- LIBC=gnu
- #else
- LIBC=gnuaout
- #endif
- #endif
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^LIBC/{
- s: ::g
- p
- }'`"
- test x"${LIBC}" != x && {
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit
- }
- test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
- ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
@@ -1027,11 +1032,11 @@ EOF
echo i386-sequent-sysv4
exit ;;
i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
+ # Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
@@ -1048,7 +1053,7 @@ EOF
i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable
exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;;
i*86:*DOS:*:*)
@@ -1063,7 +1068,7 @@ EOF
fi
exit ;;
i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
@@ -1091,10 +1096,13 @@ EOF
exit ;;
pc:*:*:*)
# Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
- exit ;;
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
@@ -1129,8 +1137,18 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
@@ -1143,7 +1161,7 @@ EOF
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;;
SM[BE]S:UNIX_SV:*:*)
@@ -1163,10 +1181,10 @@ EOF
echo ns32k-sni-sysv
fi
exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
@@ -1192,11 +1210,11 @@ EOF
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
+ echo mips-nec-sysv${UNAME_RELEASE}
else
- echo mips-unknown-sysv${UNAME_RELEASE}
+ echo mips-unknown-sysv${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
@@ -1206,6 +1224,12 @@ EOF
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@@ -1232,9 +1256,21 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
@@ -1248,7 +1284,10 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
- NSE-?:NONSTOP_KERNEL:*:*)
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
@@ -1293,13 +1332,13 @@ EOF
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
+ echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
@@ -1314,11 +1353,14 @@ EOF
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
esac
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
@@ -1336,11 +1378,11 @@ main ()
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
- "4"
+ "4"
#else
- ""
+ ""
#endif
- ); exit (0);
+ ); exit (0);
#endif
#endif
@@ -1474,9 +1516,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
diff --git a/config.h.in b/config.h.in
index 7c85111..e70582e 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,9 +1,9 @@
/* config.h.in. Generated from configure.ac by autoheader. */
-/* the name of <hash_set> */
+/* the name of <hash_map> */
#undef HASH_MAP_CLASS
-/* the location of <hash_map> */
+/* the location of <unordered_map> or <hash_map> */
#undef HASH_MAP_H
/* the namespace of hash_map/hash_set */
@@ -12,7 +12,7 @@
/* the name of <hash_set> */
#undef HASH_SET_CLASS
-/* the location of <hash_set> */
+/* the location of <unordered_set> or <hash_set> */
#undef HASH_SET_H
/* Define to 1 if you have the <dlfcn.h> header file. */
@@ -110,6 +110,9 @@
your system. */
#undef PTHREAD_CREATE_JOINABLE
+/* 64bit enabled */
+#undef SOLARIS_64BIT_ENABLED
+
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
diff --git a/config.sub b/config.sub
index 1761d8b..9633db7 100755
--- a/config.sub
+++ b/config.sub
@@ -1,44 +1,40 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
+# Copyright 1992-2013 Free Software Foundation, Inc.
-timestamp='2007-06-28'
+timestamp='2013-08-10'
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
@@ -72,8 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -120,12 +115,18 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
- nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
@@ -148,10 +149,13 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray)
+ -apple | -axis | -knuth | -cray | -microblaze*)
os=
basic_machine=$1
;;
+ -bluegene*)
+ os=-cnk
+ ;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
@@ -166,10 +170,10 @@ case $os in
os=-chorusos
basic_machine=$1
;;
- -chorusrdb)
- os=-chorusrdb
+ -chorusrdb)
+ os=-chorusrdb
basic_machine=$1
- ;;
+ ;;
-hiux*)
os=-hiuxwe2
;;
@@ -214,6 +218,12 @@ case $os in
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
-lynx*)
os=-lynxos
;;
@@ -238,24 +248,34 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
+ | aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
| bfin \
- | c4x | clipper \
+ | c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
+ | epiphany \
| fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
+ | le32 | le64 \
+ | lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | mcore | mep \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
- | mips64vr | mips64vrel \
+ | mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
@@ -266,31 +286,45 @@ case $basic_machine in
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
+ | moxie \
| mt \
| msp430 \
- | nios | nios2 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
- | or32 \
+ | open8 \
+ | or1k | or32 \
| pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
+ | rl78 | rx \
| score \
- | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu | strongarm \
- | tahoe | thumb | tic4x | tic80 | tron \
- | v850 | v850e \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| we32k \
- | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
- | z8k)
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
basic_machine=$basic_machine-unknown
;;
- m6811 | m68hc11 | m6812 | m68hc12)
- # Motorola 68HC11/12.
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@@ -300,6 +334,21 @@ case $basic_machine in
basic_machine=mt-unknown
;;
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
@@ -314,29 +363,37 @@ case $basic_machine in
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
+ | aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
+ | be32-* | be64-* \
| bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
- | clipper-* | craynv-* | cydra-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
+ | le32-* | le64-* \
+ | lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
- | mips64vr-* | mips64vrel-* \
+ | mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
@@ -347,31 +404,41 @@ case $basic_machine in
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
- | nios-* | nios2-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
- | romp-* | rs6000-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
- | tahoe-* | thumb-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
| tron-* \
- | v850-* | v850e-* | vax-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
| we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
| ymp-* \
- | z8k-*)
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -389,7 +456,7 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
- abacus)
+ abacus)
basic_machine=abacus-unknown
;;
adobe68k)
@@ -435,6 +502,10 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -443,10 +514,35 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
c90)
basic_machine=c90-cray
os=-unicos
;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -475,7 +571,7 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
- cr16)
+ cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
@@ -514,6 +610,10 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
@@ -629,7 +729,6 @@ case $basic_machine in
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
@@ -668,6 +767,14 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -679,8 +786,15 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
mingw32)
- basic_machine=i386-pc
+ basic_machine=i686-pc
os=-mingw32
;;
mingw32ce)
@@ -715,10 +829,18 @@ case $basic_machine in
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@@ -783,6 +905,12 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@@ -813,6 +941,14 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
pbd)
basic_machine=sparc-tti
;;
@@ -857,9 +993,10 @@ case $basic_machine in
;;
power) basic_machine=power-ibm
;;
- ppc) basic_machine=powerpc-unknown
+ ppc | ppcbe) basic_machine=powerpc-unknown
;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
@@ -884,7 +1021,11 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
- rdos)
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
basic_machine=i386-pc
os=-rdos
;;
@@ -953,6 +1094,9 @@ case $basic_machine in
basic_machine=i860-stratus
os=-sysv4
;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
sun2)
basic_machine=m68000-sun
;;
@@ -1009,17 +1153,9 @@ case $basic_machine in
basic_machine=t90-cray
os=-unicos
;;
- tic54x | c54x*)
- basic_machine=tic54x-unknown
- os=-coff
- ;;
- tic55x | c55x*)
- basic_machine=tic55x-unknown
- os=-coff
- ;;
- tic6x | c6x*)
- basic_machine=tic6x-unknown
- os=-coff
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
;;
tx39)
basic_machine=mipstx39-unknown
@@ -1088,6 +1224,9 @@ case $basic_machine in
xps | xps100)
basic_machine=xps100-honeywell
;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
ymp)
basic_machine=ymp-cray
os=-unicos
@@ -1096,6 +1235,10 @@ case $basic_machine in
basic_machine=z8k-unknown
os=-sim
;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
none)
basic_machine=none-none
os=-none
@@ -1134,7 +1277,7 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
- sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
@@ -1181,9 +1324,12 @@ esac
if [ x"$os" != x"" ]
then
case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
+ # First match some system type aliases
+ # that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
@@ -1204,21 +1350,23 @@ case $os in
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
+ | -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -openbsd* | -solidbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* \
- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1226,7 +1374,7 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1265,7 +1413,7 @@ case $os in
-opened*)
os=-openedition
;;
- -os400*)
+ -os400*)
os=-os400
;;
-wince*)
@@ -1314,7 +1462,7 @@ case $os in
-sinix*)
os=-sysv4
;;
- -tpf*)
+ -tpf*)
os=-tpf
;;
-triton*)
@@ -1350,12 +1498,14 @@ case $os in
-aros*)
os=-aros
;;
- -kaos*)
- os=-kaos
- ;;
-zvmoe)
os=-zvmoe
;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
-none)
;;
*)
@@ -1378,10 +1528,10 @@ else
# system, and we'll never get to this point.
case $basic_machine in
- score-*)
+ score-*)
os=-elf
;;
- spu-*)
+ spu-*)
os=-elf
;;
*-acorn)
@@ -1393,8 +1543,23 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
- c4x-* | tic4x-*)
- os=-coff
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
@@ -1414,14 +1579,11 @@ case $basic_machine in
;;
m68000-sun)
os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
;;
m68*-cisco)
os=-aout
;;
- mep-*)
+ mep-*)
os=-elf
;;
mips*-cisco)
@@ -1430,6 +1592,9 @@ case $basic_machine in
mips*-*)
os=-elf
;;
+ or1k-*)
+ os=-elf
+ ;;
or32-*)
os=-coff
;;
@@ -1448,7 +1613,7 @@ case $basic_machine in
*-ibm)
os=-aix
;;
- *-knuth)
+ *-knuth)
os=-mmixware
;;
*-wec)
@@ -1553,7 +1718,7 @@ case $basic_machine in
-sunos*)
vendor=sun
;;
- -aix*)
+ -cnk*|-aix*)
vendor=ibm
;;
-beos*)
diff --git a/configure b/configure
index 5802f1c..746dca2 100755
--- a/configure
+++ b/configure
@@ -1,13 +1,11 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for Protocol Buffers 2.3.0.
+# Generated by GNU Autoconf 2.69 for Protocol Buffers 2.6.1.
#
# Report bugs to <protobuf@googlegroups.com>.
#
#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
@@ -136,6 +134,31 @@ export LANGUAGE
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
@@ -169,12 +192,21 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
else
exitcode=1; echo positional parameters were not saved.
fi
-test x\$exitcode = x0 || exit 1"
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
-test \$(( 1 + 1 )) = 2 || exit 1"
+test \$(( 1 + 1 )) = 2 || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
if (eval "$as_required") 2>/dev/null; then :
as_have_required=yes
else
@@ -214,21 +246,25 @@ IFS=$as_save_IFS
if test "x$CONFIG_SHELL" != x; then :
- # We cannot yet assume a decent shell, so we have to provide a
- # neutralization value for shells without unset; and this also
- # works around shells that cannot unset nonexistent variables.
- # Preserve -v and -x to the replacement shell.
- BASH_ENV=/dev/null
- ENV=/dev/null
- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
- export CONFIG_SHELL
- case $- in # ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
- esac
- exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
fi
if test x$as_have_required = xno; then :
@@ -331,6 +367,14 @@ $as_echo X"$as_dir" |
} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
@@ -452,6 +496,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
chmod +x "$as_me.lineno" ||
{ $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensitive to this).
@@ -486,16 +534,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -507,28 +555,8 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -536,155 +564,8 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-# Check that we are running under the correct shell.
SHELL=${CONFIG_SHELL-/bin/sh}
-case X$lt_ECHO in
-X*--fallback-echo)
- # Remove one level of quotation (which was required for Make).
- ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','`
- ;;
-esac
-
-ECHO=${lt_ECHO-echo}
-if test "X$1" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
-elif test "X$1" = X--fallback-echo; then
- # Avoid inline document here, it may be left over
- :
-elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
- # Yippee, $ECHO works!
- :
-else
- # Restart under the correct shell.
- exec $SHELL "$0" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
- # used as fallback echo
- shift
- cat <<_LT_EOF
-$*
-_LT_EOF
- exit 0
-fi
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test -z "$lt_ECHO"; then
- if test "X${echo_test_string+set}" != Xset; then
- # find a string as large as possible, as long as the shell can cope with it
- for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
- # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
- if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
- { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
- then
- break
- fi
- done
- fi
-
- if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- :
- else
- # The Solaris, AIX, and Digital Unix default echo programs unquote
- # backslashes. This makes it impossible to quote backslashes using
- # echo "$something" | sed 's/\\/\\\\/g'
- #
- # So, first we look for a working echo in the user's PATH.
-
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for dir in $PATH /usr/ucb; do
- IFS="$lt_save_ifs"
- if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
- test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- ECHO="$dir/echo"
- break
- fi
- done
- IFS="$lt_save_ifs"
-
- if test "X$ECHO" = Xecho; then
- # We didn't find a better echo, so look for alternatives.
- if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # This shell has a builtin print -r that does the trick.
- ECHO='print -r'
- elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
- test "X$CONFIG_SHELL" != X/bin/ksh; then
- # If we have ksh, try running configure again with it.
- ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
- export ORIGINAL_CONFIG_SHELL
- CONFIG_SHELL=/bin/ksh
- export CONFIG_SHELL
- exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
- else
- # Try using printf.
- ECHO='printf %s\n'
- if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # Cool, printf works
- :
- elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
- export CONFIG_SHELL
- SHELL="$CONFIG_SHELL"
- export SHELL
- ECHO="$CONFIG_SHELL $0 --fallback-echo"
- elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- ECHO="$CONFIG_SHELL $0 --fallback-echo"
- else
- # maybe with a smaller string...
- prev=:
-
- for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
- if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
- then
- break
- fi
- prev="$cmd"
- done
-
- if test "$prev" != 'sed 50q "$0"'; then
- echo_test_string=`eval $prev`
- export echo_test_string
- exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
- else
- # Oops. We lost completely, so just stick with echo.
- ECHO=echo
- fi
- fi
- fi
- fi
- fi
-fi
-
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-lt_ECHO=$ECHO
-if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
- lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
-fi
-
-
-
test -n "$DJDIR" || exec 7<&0 </dev/null
exec 6>&1
@@ -709,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='Protocol Buffers'
PACKAGE_TARNAME='protobuf'
-PACKAGE_VERSION='2.3.0'
-PACKAGE_STRING='Protocol Buffers 2.3.0'
+PACKAGE_VERSION='2.6.1'
+PACKAGE_STRING='Protocol Buffers 2.6.1'
PACKAGE_BUGREPORT='protobuf@googlegroups.com'
PACKAGE_URL=''
@@ -772,9 +653,12 @@ OTOOL
LIPO
NMEDIT
DSYMUTIL
-lt_ECHO
+MANIFEST_TOOL
RANLIB
+ac_ct_AR
AR
+DLLTOOL
+OBJDUMP
LN_S
NM
ac_ct_DUMPBIN
@@ -813,6 +697,10 @@ CPPFLAGS
LDFLAGS
CFLAGS
CC
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
am__untar
am__tar
AMTAR
@@ -848,6 +736,9 @@ build_os
build_vendor
build_cpu
build
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
target_alias
host_alias
build_alias
@@ -889,6 +780,8 @@ SHELL'
ac_subst_files=''
ac_user_opts='
enable_option_checking
+enable_maintainer_mode
+enable_silent_rules
with_zlib
with_protoc
enable_dependency_tracking
@@ -898,6 +791,7 @@ enable_static
with_pic
enable_fast_install
with_gnu_ld
+with_sysroot
enable_libtool_lock
'
ac_precious_vars='build_alias
@@ -1367,8 +1261,6 @@ target=$target_alias
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
- $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used" >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
@@ -1454,7 +1346,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures Protocol Buffers 2.3.0 to adapt to many kinds of systems.
+\`configure' configures Protocol Buffers 2.6.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1525,7 +1417,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Protocol Buffers 2.3.0:";;
+ short | recursive ) echo "Configuration of Protocol Buffers 2.6.1:";;
esac
cat <<\_ACEOF
@@ -1533,8 +1425,15 @@ Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors
+ --disable-maintainer-mode
+ disable make rules and dependencies not useful (and
+ sometimes confusing) to the casual installer
+ --enable-silent-rules less verbose build output (undo: "make V=1")
+ --disable-silent-rules verbose build output (undo: "make V=0")
+ --enable-dependency-tracking
+ do not reject slow dependency extractors
+ --disable-dependency-tracking
+ speeds up one-time build
--disable-64bit-solaris Build 64 bit binary on Solaris [default=on]
--enable-shared[=PKGS] build shared libraries [default=yes]
--enable-static[=PKGS] build static libraries [default=yes]
@@ -1550,9 +1449,11 @@ Optional Packages:
--with-protoc=COMMAND use the given protoc command instead of building a
new one when building tests (useful for
cross-compiling)
- --with-pic try to use only PIC/non-PIC objects [default=use
+ --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
both]
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sysroot=DIR Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).
Some influential environment variables:
CC C compiler command
@@ -1632,10 +1533,10 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-Protocol Buffers configure 2.3.0
-generated by GNU Autoconf 2.68
+Protocol Buffers configure 2.6.1
+generated by GNU Autoconf 2.69
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1996,7 +1897,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -2140,7 +2041,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -2229,8 +2130,8 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by Protocol Buffers $as_me 2.3.0, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+It was created by Protocol Buffers $as_me 2.6.1, which was
+generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2579,6 +2480,29 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=yes
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
ac_config_headers="$ac_config_headers config.h"
@@ -2733,7 +2657,7 @@ test -n "$target_alias" &&
NONENONEs,x,x, &&
program_prefix=${target_alias}-
-am__api_version='1.11'
+am__api_version='1.14'
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -2772,7 +2696,7 @@ case $as_dir/ in #((
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
if test $ac_prog = install &&
grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
@@ -2830,9 +2754,6 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
$as_echo_n "checking whether build environment is sane... " >&6; }
-# Just in case
-sleep 1
-echo timestamp > conftest.file
# Reject unsafe characters in $srcdir or the absolute working directory
# name. Accept space and tab only in the latter.
am_lf='
@@ -2843,32 +2764,40 @@ case `pwd` in
esac
case $srcdir in
*[\\\"\#\$\&\'\`$am_lf\ \ ]*)
- as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
esac
-# Do `set' in a subshell so we don't clobber the current shell's
+# Do 'set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$*" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- rm -f conftest.file
- if test "$*" != "X $srcdir/configure conftest.file" \
- && test "$*" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
-alias in your environment" "$LINENO" 5
- fi
-
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+ alias in your environment" "$LINENO" 5
+ fi
+ if test "$2" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
test "$2" = conftest.file
)
then
@@ -2880,6 +2809,16 @@ Check your system clock" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
test "$program_prefix" != NONE &&
program_transform_name="s&^&$program_prefix&;$program_transform_name"
# Use a double $ so make ignores it.
@@ -2902,12 +2841,12 @@ if test x"${MISSING+set}" != xset; then
esac
fi
# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
else
am_missing_run=
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
-$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
fi
if test x"${install_sh}" != xset; then
@@ -2919,10 +2858,10 @@ if test x"${install_sh}" != xset; then
esac
fi
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
+# will honor the 'STRIP' environment variable to overrule this program.
if test "$cross_compiling" != no; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
@@ -2941,7 +2880,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2981,7 +2920,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3032,7 +2971,7 @@ do
test -z "$as_dir" && as_dir=.
for ac_prog in mkdir gmkdir; do
for ac_exec_ext in '' $ac_executable_extensions; do
- { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
'mkdir (GNU coreutils) '* | \
'mkdir (coreutils) '* | \
@@ -3061,12 +3000,6 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
$as_echo "$MKDIR_P" >&6; }
-mkdir_p="$MKDIR_P"
-case $mkdir_p in
- [\\/$]* | ?:[\\/]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-
for ac_prog in gawk mawk nawk awk
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
@@ -3085,7 +3018,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AWK="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3149,6 +3082,45 @@ else
fi
rmdir .tst 2>/dev/null
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
if test "`cd $srcdir && pwd`" != "`pwd`"; then
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
# is not polluted with repeated "-I."
@@ -3171,7 +3143,7 @@ fi
# Define the identity of the package.
PACKAGE='protobuf'
- VERSION='2.3.0'
+ VERSION='2.6.1'
cat >>confdefs.h <<_ACEOF
@@ -3199,12 +3171,22 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AMTAR='$${TAR-tar}'
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar pax cpio none'
+
am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
@@ -3212,6 +3194,48 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+ fi
+fi
+
# Check whether --with-zlib was given.
if test "${with_zlib+set}" = set; then :
@@ -3253,7 +3277,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3293,7 +3317,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3346,7 +3370,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3387,7 +3411,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
@@ -3445,7 +3469,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3489,7 +3513,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3935,8 +3959,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdarg.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -4020,6 +4043,65 @@ ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
DEPDIR="${am__leading_dot}deps"
ac_config_commands="$ac_config_commands depfiles"
@@ -4039,7 +4121,7 @@ am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
+# Ignore all kinds of additional output from 'make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
@@ -4095,8 +4177,8 @@ else
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
@@ -4131,16 +4213,16 @@ else
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
@@ -4149,8 +4231,8 @@ else
test "$am__universal" = false || continue
;;
nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
if test "x$enable_dependency_tracking" = xyes; then
continue
else
@@ -4158,7 +4240,7 @@ else
fi
;;
msvc7 | msvc7msys | msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
+ # This compiler won't grok '-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
@@ -4240,7 +4322,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4284,7 +4366,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CXX="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4480,8 +4562,8 @@ else
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
@@ -4516,16 +4598,16 @@ else
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
@@ -4534,8 +4616,8 @@ else
test "$am__universal" = false || continue
;;
nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
if test "x$enable_dependency_tracking" = xyes; then
continue
else
@@ -4543,7 +4625,7 @@ else
fi
;;
msvc7 | msvc7msys | msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
+ # This compiler won't grok '-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
@@ -4754,7 +4836,7 @@ do
for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+ as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
@@ -4820,7 +4902,7 @@ do
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+ as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
@@ -5027,8 +5109,8 @@ else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-# define __EXTENSIONS__ 1
- $ac_includes_default
+# define __EXTENSIONS__ 1
+ $ac_includes_default
int
main ()
{
@@ -5158,7 +5240,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ISAINFO="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5197,6 +5279,9 @@ fi
if test "x$ac_enable_64bit" = "xyes"; then :
+
+$as_echo "#define SOLARIS_64BIT_ENABLED 1" >>confdefs.h
+
if test "x$libdir" = "x\${exec_prefix}/lib"; then :
libdir="${libdir}/${isainfo_k}"
@@ -5243,8 +5328,8 @@ esac
-macro_version='2.2.4'
-macro_revision='1.2976'
+macro_version='2.4.2'
+macro_revision='1.3337'
@@ -5260,6 +5345,75 @@ macro_revision='1.2976'
ltmain="$ac_aux_dir/ltmain.sh"
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case "$ECHO" in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
$as_echo_n "checking for a sed that does not truncate output... " >&6; }
if ${ac_cv_path_SED+:} false; then :
@@ -5282,7 +5436,7 @@ do
for ac_prog in sed gsed; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+ as_fn_executable_p "$ac_path_SED" || continue
# Check for GNU ac_path_SED and select it if it is found.
# Check for GNU $ac_path_SED
case `"$ac_path_SED" --version 2>&1` in
@@ -5361,7 +5515,7 @@ do
for ac_prog in fgrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+ as_fn_executable_p "$ac_path_FGREP" || continue
# Check for GNU ac_path_FGREP and select it if it is found.
# Check for GNU $ac_path_FGREP
case `"$ac_path_FGREP" --version 2>&1` in
@@ -5595,8 +5749,11 @@ if test "$lt_cv_path_NM" != "no"; then
NM="$lt_cv_path_NM"
else
# Didn't find any BSD compatible name lister, look for dumpbin.
- if test -n "$ac_tool_prefix"; then
- for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
@@ -5614,7 +5771,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5640,7 +5797,7 @@ fi
fi
if test -z "$DUMPBIN"; then
ac_ct_DUMPBIN=$DUMPBIN
- for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+ for ac_prog in dumpbin "link -dump"
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
@@ -5658,7 +5815,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5695,6 +5852,15 @@ esac
fi
fi
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
if test "$DUMPBIN" != ":"; then
NM="$DUMPBIN"
@@ -5714,13 +5880,13 @@ if ${lt_cv_nm_interface+:} false; then :
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:5717: $ac_compile\"" >&5)
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
- (eval echo "\"\$as_me:5720: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
- (eval echo "\"\$as_me:5723: output\"" >&5)
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -5766,7 +5932,7 @@ else
lt_cv_sys_max_cmd_len=-1;
;;
- cygwin* | mingw*)
+ cygwin* | mingw* | cegcc*)
# On Win9x/ME, this test blows up -- it succeeds, but takes
# about 5 minutes as the teststring grows exponentially.
# Worse, since 9x/ME are not pre-emptively multitasking,
@@ -5777,6 +5943,11 @@ else
lt_cv_sys_max_cmd_len=8192;
;;
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
amigaos*)
# On AmigaOS with pdksh, this test takes hours, literally.
# So we just punt and use a minimum line length of 8192.
@@ -5802,6 +5973,11 @@ else
lt_cv_sys_max_cmd_len=196608
;;
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
osf*)
# Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
# due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
@@ -5828,7 +6004,8 @@ else
;;
*)
lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len"; then
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
else
@@ -5841,8 +6018,8 @@ else
# If test is not a shell built-in, we'll probably end up computing a
# maximum length that is only half of the actual maximum length, but
# we can't tell.
- while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
- = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
test $i != 17 # 1/2 MB should be enough
do
i=`expr $i + 1`
@@ -5884,8 +6061,8 @@ $as_echo_n "checking whether the shell understands some XSI constructs... " >&6;
# Try some XSI features
xsi_shell=no
( _lt_dummy="a/b/c"
- test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
- = c,a/b,, \
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
&& eval 'test $(( 1 + 1 )) -eq 2 \
&& test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
&& xsi_shell=yes
@@ -5934,6 +6111,80 @@ esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
$as_echo_n "checking for $LD option to reload object files... " >&6; }
if ${lt_cv_ld_reload_flag+:} false; then :
@@ -5950,6 +6201,11 @@ case $reload_flag in
esac
reload_cmds='$LD$reload_flag -o $output$reload_objs'
case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
darwin*)
if test "$GCC" = yes; then
reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
@@ -5967,6 +6223,107 @@ esac
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
$as_echo_n "checking how to recognize dependent libraries... " >&6; }
@@ -6012,15 +6369,23 @@ mingw* | pw32*)
# Base MSYS/MinGW do not provide the 'file' command needed by
# func_win32_libid shell function, so use a weaker test based on 'objdump',
# unless we find 'file', for example because we are cross-compiling.
- if ( file / ) >/dev/null 2>&1; then
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
lt_cv_file_magic_cmd='func_win32_libid'
else
- lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
lt_cv_file_magic_cmd='$OBJDUMP -f'
fi
;;
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
darwin* | rhapsody*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -6041,7 +6406,7 @@ freebsd* | dragonfly*)
fi
;;
-gnu*)
+haiku*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -6053,11 +6418,11 @@ hpux10.20* | hpux11*)
lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
;;
hppa*64*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
;;
*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
lt_cv_file_magic_test_file=/usr/lib/libc.sl
;;
esac
@@ -6078,12 +6443,12 @@ irix5* | irix6* | nonstopux*)
lt_cv_deplibs_check_method=pass_all
;;
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
lt_cv_deplibs_check_method=pass_all
;;
-netbsd*)
+netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
else
@@ -6160,6 +6525,21 @@ esac
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
file_magic_cmd=$lt_cv_file_magic_cmd
deplibs_check_method=$lt_cv_deplibs_check_method
test -z "$deplibs_check_method" && deplibs_check_method=unknown
@@ -6175,9 +6555,162 @@ test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ar; ac_word=$2
+ for ac_prog in ar
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_AR+:} false; then :
@@ -6192,8 +6725,8 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_AR="${ac_tool_prefix}ar"
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
@@ -6213,11 +6746,15 @@ $as_echo "no" >&6; }
fi
+ test -n "$AR" && break
+ done
fi
-if test -z "$ac_cv_prog_AR"; then
+if test -z "$AR"; then
ac_ct_AR=$AR
- # Extract the first word of "ar", so it can be a program name with args.
-set dummy ar; ac_word=$2
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_AR+:} false; then :
@@ -6232,8 +6769,8 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_AR="ar"
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
@@ -6252,6 +6789,10 @@ else
$as_echo "no" >&6; }
fi
+
+ test -n "$ac_ct_AR" && break
+done
+
if test "x$ac_ct_AR" = x; then
AR="false"
else
@@ -6263,17 +6804,73 @@ ac_tool_warned=yes ;;
esac
AR=$ac_ct_AR
fi
-else
- AR="$ac_cv_prog_AR"
fi
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
@@ -6297,7 +6894,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6337,7 +6934,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6396,7 +6993,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6436,7 +7033,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_RANLIB="ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6486,15 +7083,27 @@ old_postuninstall_cmds=
if test -n "$RANLIB"; then
case $host_os in
openbsd*)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
;;
*)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
;;
esac
- old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
fi
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
@@ -6559,7 +7168,7 @@ case $host_os in
aix*)
symcode='[BCDT]'
;;
-cygwin* | mingw* | pw32*)
+cygwin* | mingw* | pw32* | cegcc*)
symcode='[ABCDGISTW]'
;;
hpux*)
@@ -6602,8 +7211,8 @@ esac
lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
# Handle CRLF in mingw tool chain
opt_cr=
@@ -6627,6 +7236,7 @@ for ac_symprfx in "" "_"; do
# which start with @ or ?.
lt_cv_sys_global_symbol_pipe="$AWK '"\
" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
" \$ 0!~/External *\|/{next};"\
" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
@@ -6639,6 +7249,7 @@ for ac_symprfx in "" "_"; do
else
lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
# Check to see that the pipe works correctly.
pipe_works=no
@@ -6664,8 +7275,8 @@ _LT_EOF
test $ac_status = 0; }; then
# Now try to grab the symbols.
nlist=conftest.nm
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5
- (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } && test -s "$nlist"; then
@@ -6680,6 +7291,18 @@ _LT_EOF
if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -6691,7 +7314,7 @@ _LT_EOF
cat <<_LT_EOF >> conftest.$ac_ext
/* The mapping between symbol names and symbols. */
-const struct {
+LT_DLSYM_CONST struct {
const char *name;
void *address;
}
@@ -6717,8 +7340,8 @@ static const void *lt_preloaded_setup() {
_LT_EOF
# Now try linking the two files.
mv conftest.$ac_objext conftstm.$ac_objext
- lt_save_LIBS="$LIBS"
- lt_save_CFLAGS="$CFLAGS"
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
LIBS="conftstm.$ac_objext"
CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
@@ -6728,8 +7351,8 @@ _LT_EOF
test $ac_status = 0; } && test -s conftest${ac_exeext}; then
pipe_works=yes
fi
- LIBS="$lt_save_LIBS"
- CFLAGS="$lt_save_CFLAGS"
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
else
echo "cannot find nm_test_func in $nlist" >&5
fi
@@ -6766,6 +7389,15 @@ else
$as_echo "ok" >&6; }
fi
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
@@ -6788,6 +7420,46 @@ fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+
# Check whether --enable-libtool-lock was given.
if test "${enable_libtool_lock+set}" = set; then :
enableval=$enable_libtool_lock;
@@ -6819,7 +7491,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 6822 "configure"' > conftest.$ac_ext
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -6854,7 +7526,7 @@ ia64-*-hpux*)
rm -rf conftest*
;;
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
@@ -6870,9 +7542,19 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
LD="${LD-ld} -m elf_i386_fbsd"
;;
x86_64-*linux*)
- LD="${LD-ld} -m elf_i386"
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
;;
- ppc64-*linux*|powerpc64-*linux*)
+ powerpc64le-*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
@@ -6891,7 +7573,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
- ppc*-*linux*|powerpc*-*linux*)
+ powerpcle-*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
@@ -6954,7 +7639,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
CFLAGS="$SAVE_CFLAGS"
fi
;;
-sparc*-*solaris*)
+*-*solaris*)
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
@@ -6965,7 +7650,20 @@ sparc*-*solaris*)
case `/usr/bin/file conftest.o` in
*64-bit*)
case $lt_cv_prog_gnu_ld in
- yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ yes*)
+ case $host in
+ i?86-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD="${LD-ld}_sol2"
+ fi
+ ;;
*)
if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
LD="${LD-ld} -64"
@@ -6981,6 +7679,123 @@ esac
need_locks="$enable_libtool_lock"
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
case $host_os in
rhapsody* | darwin*)
@@ -7001,7 +7816,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7041,7 +7856,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7093,7 +7908,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7133,7 +7948,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_NMEDIT="nmedit"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7185,7 +8000,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7225,7 +8040,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_LIPO="lipo"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7277,7 +8092,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7317,7 +8132,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OTOOL="otool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7369,7 +8184,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7409,7 +8224,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OTOOL64="otool64"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7488,7 +8303,13 @@ else
$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
-dynamiclib -Wl,-single_module conftest.c 2>conftest.err
_lt_result=$?
- if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&5
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
lt_cv_apple_cc_single_mod=yes
else
cat conftest.err >&5
@@ -7499,6 +8320,7 @@ else
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
if ${lt_cv_ld_exported_symbols_list+:} false; then :
@@ -7531,6 +8353,41 @@ rm -f core conftest.err conftest.$ac_objext \
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&5
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
case $host_os in
rhapsody* | darwin1.[012])
_lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
@@ -7558,7 +8415,7 @@ $as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
else
_lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
fi
- if test "$DSYMUTIL" != ":"; then
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
_lt_dsymutil='~$DSYMUTIL $lib || :'
else
_lt_dsymutil=
@@ -7581,529 +8438,14 @@ done
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-if test -z "$CXX"; then
- if test -n "$CCC"; then
- CXX=$CCC
- else
- if test -n "$ac_tool_prefix"; then
- for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CXX+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CXX"; then
- ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CXX=$ac_cv_prog_CXX
-if test -n "$CXX"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
-$as_echo "$CXX" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$CXX" && break
- done
-fi
-if test -z "$CXX"; then
- ac_ct_CXX=$CXX
- for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CXX+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_CXX"; then
- ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CXX="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
-if test -n "$ac_ct_CXX"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
-$as_echo "$ac_ct_CXX" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$ac_ct_CXX" && break
-done
-
- if test "x$ac_ct_CXX" = x; then
- CXX="g++"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CXX=$ac_ct_CXX
- fi
-fi
-
- fi
-fi
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
- { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compiler $ac_option >&5") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- sed '10a\
-... rest of stderr output deleted ...
- 10q' conftest.err >conftest.er1
- cat conftest.er1 >&5
- fi
- rm -f conftest.er1 conftest.err
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
-done
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
-$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
-if ${ac_cv_cxx_compiler_gnu+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_compiler_gnu=yes
-else
- ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
-$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
- GXX=yes
-else
- GXX=
-fi
-ac_test_CXXFLAGS=${CXXFLAGS+set}
-ac_save_CXXFLAGS=$CXXFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
-$as_echo_n "checking whether $CXX accepts -g... " >&6; }
-if ${ac_cv_prog_cxx_g+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_save_cxx_werror_flag=$ac_cxx_werror_flag
- ac_cxx_werror_flag=yes
- ac_cv_prog_cxx_g=no
- CXXFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_cv_prog_cxx_g=yes
-else
- CXXFLAGS=""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-
-else
- ac_cxx_werror_flag=$ac_save_cxx_werror_flag
- CXXFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
+func_stripname_cnf ()
{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname_cnf
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_cv_prog_cxx_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_cxx_werror_flag=$ac_save_cxx_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
-$as_echo "$ac_cv_prog_cxx_g" >&6; }
-if test "$ac_test_CXXFLAGS" = set; then
- CXXFLAGS=$ac_save_CXXFLAGS
-elif test $ac_cv_prog_cxx_g = yes; then
- if test "$GXX" = yes; then
- CXXFLAGS="-g -O2"
- else
- CXXFLAGS="-g"
- fi
-else
- if test "$GXX" = yes; then
- CXXFLAGS="-O2"
- else
- CXXFLAGS=
- fi
-fi
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-depcc="$CXX" am_compiler_list=
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
-$as_echo_n "checking dependency style of $depcc... " >&6; }
-if ${am_cv_CXX_dependencies_compiler_type+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
- rm -rf conftest.dir
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
-
- am_cv_CXX_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
- fi
- am__universal=false
- case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac
-
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
- am__obj=sub/conftest.${OBJEXT-o}
- am__minus_obj="-o $am__obj"
- case $depmode in
- gcc)
- # This depmode causes a compiler race in universal mode.
- test "$am__universal" = false || continue
- ;;
- nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- msvc7 | msvc7msys | msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
- # not run yet. These depmodes are late enough in the game, and
- # so weak that their functioning should not be impacted.
- am__obj=conftest.${OBJEXT-o}
- am__minus_obj=
- ;;
- none) break ;;
- esac
- if depmode=$depmode \
- source=sub/conftest.c object=$am__obj \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_CXX_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_CXX_dependencies_compiler_type=none
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
-$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
-CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
-
- if
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
- am__fastdepCXX_TRUE=
- am__fastdepCXX_FALSE='#'
-else
- am__fastdepCXX_TRUE='#'
- am__fastdepCXX_FALSE=
-fi
-
-
-if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
- ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
- (test "X$CXX" != "Xg++"))) ; then
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
-$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
-if test -z "$CXXCPP"; then
- if ${ac_cv_prog_CXXCPP+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- # Double quotes because CXXCPP needs to be expanded
- for CXXCPP in "$CXX -E" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
- break
-fi
-
- done
- ac_cv_prog_CXXCPP=$CXXCPP
-
-fi
- CXXCPP=$ac_cv_prog_CXXCPP
-else
- ac_cv_prog_CXXCPP=$CXXCPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
-$as_echo "$CXXCPP" >&6; }
-ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-_lt_caught_CXX_error=yes; }
-fi
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-else
- _lt_caught_CXX_error=yes
-fi
@@ -8183,7 +8525,22 @@ fi
# Check whether --with-pic was given.
if test "${with_pic+set}" = set; then :
- withval=$with_pic; pic_mode="$withval"
+ withval=$with_pic; lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for lt_pkg in $withval; do
+ IFS="$lt_save_ifs"
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
else
pic_mode=default
fi
@@ -8260,6 +8617,11 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
test -z "$LN_S" && LN_S="ln -s"
@@ -8309,19 +8671,6 @@ _ACEOF
-
-
-
-
-
-
-
-
-
-
-
-
-
case $host_os in
aix3*)
# AIX sometimes has problems with the GCC collect2 program. For some
@@ -8334,23 +8683,6 @@ aix3*)
;;
esac
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\(["`\\]\)/\\\1/g'
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to delay expansion of an escaped single quote.
-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
# Global variables:
ofile=libtool
can_build_shared=yes
@@ -8379,7 +8711,7 @@ for cc_temp in $compiler""; do
*) break;;
esac
done
-cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
# Only perform the check for file, if the check method requires it
@@ -8588,7 +8920,12 @@ if test -n "$compiler"; then
lt_prog_compiler_no_builtin_flag=
if test "$GCC" = yes; then
- lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
@@ -8608,15 +8945,15 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8611: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8615: \$? = $ac_status" >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
$SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
lt_cv_prog_compiler_rtti_exceptions=yes
@@ -8645,8 +8982,6 @@ fi
lt_prog_compiler_pic=
lt_prog_compiler_static=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
if test "$GCC" = yes; then
lt_prog_compiler_wl='-Wl,'
@@ -8680,7 +9015,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
# PIC is the default for these OSes.
;;
- mingw* | cygwin* | pw32* | os2*)
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
# This hack is so that the source file can tell whether it is being
# built for inclusion in a dll (and should export symbols for example).
# Although the cygwin gcc ignores -fPIC, still need this for old-style
@@ -8694,11 +9029,18 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
lt_prog_compiler_pic='-fno-common'
;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
case $host_cpu in
- hppa*64*|ia64*)
+ hppa*64*)
# +Z the default
;;
*)
@@ -8735,6 +9077,15 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
lt_prog_compiler_pic='-fPIC'
;;
esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ if test -n "$lt_prog_compiler_pic"; then
+ lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+ fi
+ ;;
+ esac
else
# PORTME Check for flag to pass linker flags through the system compiler.
case $host_os in
@@ -8748,7 +9099,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
fi
;;
- mingw* | cygwin* | pw32* | os2*)
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
# This hack is so that the source file can tell whether it is being
# built for inclusion in a dll (and should export symbols for example).
lt_prog_compiler_pic='-DDLL_EXPORT'
@@ -8776,14 +9127,34 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
lt_prog_compiler_static='-non_shared'
;;
- linux* | k*bsd*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
- icc* | ecc* | ifort*)
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
lt_prog_compiler_wl='-Wl,'
lt_prog_compiler_pic='-KPIC'
lt_prog_compiler_static='-static'
;;
- pgcc* | pgf77* | pgf90* | pgf95*)
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
# Portland Group compilers (*not* the Pentium gcc compiler,
# which looks to be a dead project)
lt_prog_compiler_wl='-Wl,'
@@ -8795,25 +9166,40 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
# All Alpha code is PIC.
lt_prog_compiler_static='-non_shared'
;;
- xl*)
- # IBM XL C 8.0/Fortran 10.1 on PPC
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
lt_prog_compiler_wl='-Wl,'
lt_prog_compiler_pic='-qpic'
lt_prog_compiler_static='-qstaticlink'
;;
*)
case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Qoption ld '
+ ;;
*Sun\ C*)
# Sun C 5.9
lt_prog_compiler_pic='-KPIC'
lt_prog_compiler_static='-Bstatic'
lt_prog_compiler_wl='-Wl,'
;;
- *Sun\ F*)
- # Sun Fortran 8.3 passes all unrecognized flags to the linker
- lt_prog_compiler_pic='-KPIC'
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
lt_prog_compiler_static='-Bstatic'
- lt_prog_compiler_wl=''
;;
esac
;;
@@ -8845,7 +9231,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
lt_prog_compiler_pic='-KPIC'
lt_prog_compiler_static='-Bstatic'
case $cc_basename in
- f77* | f90* | f95*)
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
lt_prog_compiler_wl='-Qoption ld ';;
*)
lt_prog_compiler_wl='-Wl,';;
@@ -8902,13 +9288,17 @@ case $host_os in
lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
;;
esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
-$as_echo "$lt_prog_compiler_pic" >&6; }
-
-
-
-
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
#
# Check to make sure the PIC flag actually works.
@@ -8932,15 +9322,15 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8935: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8939: \$? = $ac_status" >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
$SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
lt_cv_prog_compiler_pic_works=yes
@@ -8969,6 +9359,11 @@ fi
+
+
+
+
+
#
# Check to make sure the static flag actually works.
#
@@ -8988,7 +9383,7 @@ else
if test -s conftest.err; then
# Append any errors to the config.log.
cat conftest.err 1>&5
- $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
$SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
if diff conftest.exp conftest.er2 >/dev/null; then
lt_cv_prog_compiler_static_works=yes
@@ -9037,16 +9432,16 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:9040: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:9044: \$? = $ac_status" >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
$SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
lt_cv_prog_compiler_c_o=yes
@@ -9092,16 +9487,16 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:9095: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:9099: \$? = $ac_status" >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
$SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
lt_cv_prog_compiler_c_o=yes
@@ -9167,7 +9562,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
hardcode_direct=no
hardcode_direct_absolute=no
hardcode_libdir_flag_spec=
- hardcode_libdir_flag_spec_ld=
hardcode_libdir_separator=
hardcode_minus_L=no
hardcode_shlibpath_var=unsupported
@@ -9196,7 +9590,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
extract_expsyms_cmds=
case $host_os in
- cygwin* | mingw* | pw32*)
+ cygwin* | mingw* | pw32* | cegcc*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
@@ -9211,10 +9605,39 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
openbsd*)
with_gnu_ld=no
;;
+ linux* | k*bsd*-gnu | gnu*)
+ link_all_deplibs=no
+ ;;
esac
ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
# If archive_cmds runs LD, not CC, wlarc should be empty
wlarc='${wl}'
@@ -9232,6 +9655,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
fi
supports_anon_versioning=no
case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
*\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
*\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
*\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
@@ -9247,11 +9671,12 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
ld_shlibs=no
cat <<_LT_EOF 1>&2
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** Warning: the GNU linker, at least up to release 2.19, is reported
*** to be unable to reliably create shared libraries on AIX.
*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
_LT_EOF
fi
@@ -9283,14 +9708,16 @@ _LT_EOF
fi
;;
- cygwin* | mingw* | pw32*)
+ cygwin* | mingw* | pw32* | cegcc*)
# _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
# as there is no search path for DLLs.
hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='${wl}--export-all-symbols'
allow_undefined_flag=unsupported
always_export_symbols=no
enable_shared_with_static_runtimes=yes
- export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
@@ -9308,6 +9735,11 @@ _LT_EOF
fi
;;
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
interix[3-9]*)
hardcode_direct=no
hardcode_shlibpath_var=no
@@ -9323,7 +9755,7 @@ _LT_EOF
archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
- gnu* | linux* | tpf* | k*bsd*-gnu)
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
tmp_diet=no
if test "$host_os" = linux-dietlibc; then
case $cc_basename in
@@ -9333,15 +9765,16 @@ _LT_EOF
if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
&& test "$tmp_diet" = no
then
- tmp_addflag=
+ tmp_addflag=' $pic_flag'
tmp_sharedflag='-shared'
case $cc_basename,$host_cpu in
pgcc*) # Portland Group C compiler
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag'
;;
- pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag -Mnomain' ;;
ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
tmp_addflag=' -i_dynamic' ;;
@@ -9349,13 +9782,20 @@ _LT_EOF
tmp_addflag=' -i_dynamic -nofor_main' ;;
ifc* | ifort*) # Intel Fortran compiler
tmp_addflag=' -nofor_main' ;;
- xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
tmp_sharedflag='-qmkshrobj'
tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
esac
case `$CC -V 2>&1 | sed 5q` in
*Sun\ C*) # Sun C 5.9
- whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
compiler_needs_object=yes
tmp_sharedflag='-G' ;;
*Sun\ F*) # Sun Fortran 8.3
@@ -9371,17 +9811,16 @@ _LT_EOF
fi
case $cc_basename in
- xlf*)
+ xlf* | bgf* | bgxlf* | mpixlf*)
# IBM XL Fortran 10.1 on PPC cannot create shared libs itself
whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
- hardcode_libdir_flag_spec=
- hardcode_libdir_flag_spec_ld='-rpath $libdir'
- archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
if test "x$supports_anon_versioning" = xyes; then
archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
echo "local: *; };" >> $output_objdir/$libname.ver~
- $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
fi
;;
esac
@@ -9390,13 +9829,13 @@ _LT_EOF
fi
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
else
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
fi
;;
@@ -9414,8 +9853,8 @@ _LT_EOF
_LT_EOF
elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
else
ld_shlibs=no
fi
@@ -9461,8 +9900,8 @@ _LT_EOF
*)
if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
else
ld_shlibs=no
fi
@@ -9502,8 +9941,10 @@ _LT_EOF
else
# If we're using GNU nm, then we don't want the "-C" option.
# -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
else
export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
fi
@@ -9565,6 +10006,7 @@ _LT_EOF
if test "$aix_use_runtimelinking" = yes; then
shared_flag="$shared_flag "'${wl}-G'
fi
+ link_all_deplibs=no
else
# not using gcc
if test "$host_cpu" = ia64; then
@@ -9580,6 +10022,7 @@ _LT_EOF
fi
fi
+ export_dynamic_flag_spec='${wl}-bexpall'
# It seems that -bexpall does not export symbols beginning with
# underscore (_), so it is better to generate a list of symbols to export.
always_export_symbols=yes
@@ -9589,7 +10032,13 @@ _LT_EOF
allow_undefined_flag='-berok'
# Determine the default libpath from the value encoded in an
# empty executable.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -9602,25 +10051,32 @@ main ()
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
@@ -9629,7 +10085,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
# Determine the default libpath from the value encoded in an
# empty executable.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -9642,30 +10104,42 @@ main ()
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
# Warning - without using the other run time loading flags,
# -berok will link without error, but may produce a broken library.
no_undefined_flag=' ${wl}-bernotok'
allow_undefined_flag=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec='$convenience'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
archive_cmds_need_lc=yes
# This is similar to how AIX traditionally builds its shared libraries.
archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
@@ -9692,25 +10166,69 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
export_dynamic_flag_spec=-rdynamic
;;
- cygwin* | mingw* | pw32*)
+ cygwin* | mingw* | pw32* | cegcc*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
- hardcode_libdir_flag_spec=' '
- allow_undefined_flag=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- old_archive_from_new_cmds='true'
- # FIXME: Should let the user specify the lib program.
- old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path='`cygpath -w "$srcfile"`'
- enable_shared_with_static_runtimes=yes
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
;;
darwin* | rhapsody*)
@@ -9720,11 +10238,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_direct=no
hardcode_automatic=yes
hardcode_shlibpath_var=unsupported
- whole_archive_flag_spec=''
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec=''
+ fi
link_all_deplibs=yes
allow_undefined_flag="$_lt_dar_allow_undefined"
- if test "$GCC" = "yes"; then
- output_verbose_link_cmd=echo
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
@@ -9742,10 +10269,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_shlibpath_var=no
;;
- freebsd1*)
- ld_shlibs=no
- ;;
-
# FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
# support. Future versions do this automatically, but an explicit c++rt0.o
# does not break anything, and helps significantly (at the cost of a little
@@ -9758,7 +10281,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
# Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
+ freebsd2.*)
archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
hardcode_direct=yes
hardcode_minus_L=yes
@@ -9767,7 +10290,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# FreeBSD 3 and greater uses gcc -shared to do shared libraries.
freebsd* | dragonfly*)
- archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
hardcode_shlibpath_var=no
@@ -9775,7 +10298,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hpux9*)
if test "$GCC" = yes; then
- archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
else
archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
fi
@@ -9790,14 +10313,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
hpux10*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
else
archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
fi
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_flag_spec_ld='+b $libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
hardcode_direct_absolute=yes
@@ -9809,16 +10331,16 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
hpux11*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
else
@@ -9830,7 +10352,46 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
;;
esac
fi
@@ -9858,26 +10419,39 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
irix5* | irix6* | nonstopux*)
if test "$GCC" = yes; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
# Try to use the -exported_symbol ld option, if it does not
# work, assume that -exports_file does not work either and
# implicitly export all symbols.
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-int foo(void) {}
+int foo (void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
-
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
- LDFLAGS="$save_LDFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
else
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
fi
archive_cmds_need_lc='no'
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
@@ -9886,7 +10460,7 @@ rm -f core conftest.err conftest.$ac_objext \
link_all_deplibs=yes
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
@@ -9939,17 +10513,17 @@ rm -f core conftest.err conftest.$ac_objext \
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
allow_undefined_flag=unsupported
- archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
;;
osf3*)
if test "$GCC" = yes; then
allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
else
allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
fi
archive_cmds_need_lc='no'
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
@@ -9959,13 +10533,13 @@ rm -f core conftest.err conftest.$ac_objext \
osf4* | osf5*) # as osf3* with the addition of -msym flag
if test "$GCC" = yes; then
allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
else
allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
# Both c and cxx compiler support -rpath directly
hardcode_libdir_flag_spec='-rpath $libdir'
@@ -9978,9 +10552,9 @@ rm -f core conftest.err conftest.$ac_objext \
no_undefined_flag=' -z defs'
if test "$GCC" = yes; then
wlarc='${wl}'
- archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
else
case `$CC -V 2>&1` in
*"Compilers 5.0"*)
@@ -10168,44 +10742,50 @@ x|xyes)
# to ld, don't add -lc before -lgcc.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
- $RM conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl
- pic_flag=$lt_prog_compiler_pic
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag
- allow_undefined_flag=
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
(eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
- then
- archive_cmds_need_lc=no
- else
- archive_cmds_need_lc=yes
- fi
- allow_undefined_flag=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $RM conftest*
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5
-$as_echo "$archive_cmds_need_lc" >&6; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
;;
esac
fi
@@ -10363,11 +10943,6 @@ esac
-
-
-
-
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
$as_echo_n "checking dynamic linker characteristics... " >&6; }
@@ -10376,16 +10951,23 @@ if test "$GCC" = yes; then
darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
*) lt_awk_arg="/^libraries:/" ;;
esac
- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
# if the path contains ";" then we assume it to be the separator
# otherwise default to the standard path separator (i.e. ":") - it is
# assumed that no part of a normal pathname contains ";" but that should
# okay in the real world where ";" in dirpaths is itself problematic.
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
- else
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
# Ok, now we have the path, separated by spaces, we can step through it
# and add multilib dir if necessary.
lt_tmp_lt_search_path_spec=
@@ -10398,7 +10980,7 @@ if test "$GCC" = yes; then
lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
fi
done
- lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
BEGIN {RS=" "; FS="/|\n";} {
lt_foo="";
lt_count=0;
@@ -10418,7 +11000,13 @@ BEGIN {RS=" "; FS="/|\n";} {
if (lt_foo != "") { lt_freq[lt_foo]++; }
if (lt_freq[lt_foo] == 1) { print lt_foo; }
}'`
- sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
else
sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
fi
@@ -10444,7 +11032,7 @@ need_version=unknown
case $host_os in
aix3*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
shlibpath_var=LIBPATH
@@ -10453,7 +11041,7 @@ aix3*)
;;
aix[4-9]*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
hardcode_into_libs=yes
@@ -10506,7 +11094,7 @@ amigaos*)
m68k)
library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;;
esac
;;
@@ -10518,7 +11106,7 @@ beos*)
;;
bsdi[45]*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
@@ -10531,14 +11119,15 @@ bsdi[45]*)
# libtool to hard-code these into programs
;;
-cygwin* | mingw* | pw32*)
+cygwin* | mingw* | pw32* | cegcc*)
version_type=windows
shrext_cmds=".dll"
need_version=no
need_lib_prefix=no
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32*)
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
library_names_spec='$libname.dll.a'
# DLL is installed to $(libdir)/../bin by postinstall_cmds
postinstall_cmds='base_file=`basename \${file}`~
@@ -10559,36 +11148,83 @@ cygwin* | mingw* | pw32*)
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
;;
- mingw*)
+ mingw* | cegcc*)
# MinGW DLLs use traditional 'lib' prefix
soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
;;
esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
;;
*)
+ # Assume MSVC wrapper
library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
;;
esac
- dynamic_linker='Win32 ld.exe'
# FIXME: first we should search . and the directory the executable is in
shlibpath_var=PATH
;;
@@ -10609,7 +11245,7 @@ darwin* | rhapsody*)
;;
dgux*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
@@ -10617,10 +11253,6 @@ dgux*)
shlibpath_var=LD_LIBRARY_PATH
;;
-freebsd1*)
- dynamic_linker=no
- ;;
-
freebsd* | dragonfly*)
# DragonFly does not have aout. When/if they implement a new
# versioning mechanism, adjust this.
@@ -10628,7 +11260,7 @@ freebsd* | dragonfly*)
objformat=`/usr/bin/objformat`
else
case $host_os in
- freebsd[123]*) objformat=aout ;;
+ freebsd[23].*) objformat=aout ;;
*) objformat=elf ;;
esac
fi
@@ -10646,7 +11278,7 @@ freebsd* | dragonfly*)
esac
shlibpath_var=LD_LIBRARY_PATH
case $host_os in
- freebsd2*)
+ freebsd2.*)
shlibpath_overrides_runpath=yes
;;
freebsd3.[01]* | freebsdelf3.[01]*)
@@ -10665,13 +11297,16 @@ freebsd* | dragonfly*)
esac
;;
-gnu*)
- version_type=linux
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
+ dynamic_linker="$host_os runtime_loader"
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
hardcode_into_libs=yes
;;
@@ -10717,12 +11352,14 @@ hpux9* | hpux10* | hpux11*)
soname_spec='${libname}${release}${shared_ext}$major'
;;
esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
;;
interix[3-9]*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
@@ -10738,7 +11375,7 @@ irix5* | irix6* | nonstopux*)
nonstopux*) version_type=nonstopux ;;
*)
if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
else
version_type=irix
fi ;;
@@ -10775,9 +11412,9 @@ linux*oldld* | linux*aout* | linux*coff*)
dynamic_linker=no
;;
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
- version_type=linux
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -10785,12 +11422,17 @@ linux* | k*bsd*-gnu)
finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
+
# Some binutils ld are patched to set DT_RUNPATH
- save_LDFLAGS=$LDFLAGS
- save_libdir=$libdir
- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -10803,13 +11445,17 @@ main ()
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
- shlibpath_overrides_runpath=yes
+ lt_cv_shlibpath_overrides_runpath=yes
fi
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
- LDFLAGS=$save_LDFLAGS
- libdir=$save_libdir
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
# This implies no fast_install, which is unacceptable.
# Some rework will be needed to allow for fast_install
@@ -10818,7 +11464,7 @@ rm -f core conftest.err conftest.$ac_objext \
# Append ld.so.conf contents to the search path
if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
fi
@@ -10831,6 +11477,18 @@ rm -f core conftest.err conftest.$ac_objext \
dynamic_linker='GNU/Linux ld.so'
;;
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
netbsd*)
version_type=sunos
need_lib_prefix=no
@@ -10850,7 +11508,7 @@ netbsd*)
;;
newsos6)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
@@ -10919,7 +11577,7 @@ rdos*)
;;
solaris*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -10944,7 +11602,7 @@ sunos4*)
;;
sysv4 | sysv4.3*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
@@ -10968,7 +11626,7 @@ sysv4 | sysv4.3*)
sysv4*MP*)
if test -d /usr/nec ;then
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
soname_spec='$libname${shared_ext}.$major'
shlibpath_var=LD_LIBRARY_PATH
@@ -10999,17 +11657,17 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
tpf*)
# TPF is a cross-target only. Preferred cross-host = GNU/Linux.
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_name_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
;;
uts4*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
@@ -11121,6 +11779,11 @@ fi
+
+
+
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
hardcode_action=
@@ -11179,7 +11842,7 @@ else
lt_cv_dlopen_self=yes
;;
- mingw* | pw32*)
+ mingw* | pw32* | cegcc*)
lt_cv_dlopen="LoadLibrary"
lt_cv_dlopen_libs=
;;
@@ -11451,7 +12114,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11454 "configure"
+#line $LINENO "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11492,11 +12155,13 @@ else
# endif
#endif
-#ifdef __cplusplus
-extern "C" void exit (int);
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
#endif
-void fnord() { int i=42;}
+int fnord () { return 42; }
int main ()
{
void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
@@ -11505,13 +12170,17 @@ int main ()
if (self)
{
if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
/* dlclose (self); */
}
else
puts (dlerror ());
- exit (status);
+ return status;
}
_LT_EOF
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
@@ -11551,7 +12220,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11554 "configure"
+#line $LINENO "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11592,11 +12261,13 @@ else
# endif
#endif
-#ifdef __cplusplus
-extern "C" void exit (int);
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
#endif
-void fnord() { int i=42;}
+int fnord () { return 42; }
int main ()
{
void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
@@ -11605,13 +12276,17 @@ int main ()
if (self)
{
if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
/* dlclose (self); */
}
else
puts (dlerror ());
- exit (status);
+ return status;
}
_LT_EOF
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
@@ -11762,6 +12437,145 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
CC="$lt_save_CC"
+ if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+ if ${ac_cv_prog_CXXCPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CXXCPP needs to be expanded
+ for CXXCPP in "$CXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+ CXXCPP=$ac_cv_prog_CXXCPP
+else
+ ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+else
+ _lt_caught_CXX_error=yes
+fi
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
@@ -11778,7 +12592,6 @@ export_dynamic_flag_spec_CXX=
hardcode_direct_CXX=no
hardcode_direct_absolute_CXX=no
hardcode_libdir_flag_spec_CXX=
-hardcode_libdir_flag_spec_ld_CXX=
hardcode_libdir_separator_CXX=
hardcode_minus_L_CXX=no
hardcode_shlibpath_var_CXX=unsupported
@@ -11788,6 +12601,8 @@ module_cmds_CXX=
module_expsym_cmds_CXX=
link_all_deplibs_CXX=unknown
old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
no_undefined_flag_CXX=
whole_archive_flag_spec_CXX=
enable_shared_with_static_runtimes_CXX=no
@@ -11843,6 +12658,7 @@ $RM -r conftest*
# Allow CC to be a program name with arguments.
lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
lt_save_LD=$LD
lt_save_GCC=$GCC
GCC=$GXX
@@ -11860,6 +12676,7 @@ $RM -r conftest*
fi
test -z "${LDCXX+set}" || LD=$LDCXX
CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
compiler=$CC
compiler_CXX=$CC
for cc_temp in $compiler""; do
@@ -11870,7 +12687,7 @@ $RM -r conftest*
*) break;;
esac
done
-cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
if test -n "$compiler"; then
@@ -11999,8 +12816,8 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
# Check if GNU C++ uses GNU ld as the underlying linker, since the
# archiving commands below assume that GNU ld is being used.
if test "$with_gnu_ld" = yes; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
@@ -12032,7 +12849,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
GXX=no
@@ -12131,6 +12948,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
fi
fi
+ export_dynamic_flag_spec_CXX='${wl}-bexpall'
# It seems that -bexpall does not export symbols beginning with
# underscore (_), so it is better to generate a list of symbols to
# export.
@@ -12141,7 +12959,13 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
allow_undefined_flag_CXX='-berok'
# Determine the default libpath from the value encoded in an empty
# executable.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath__CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -12154,26 +12978,33 @@ main ()
_ACEOF
if ac_fn_cxx_try_link "$LINENO"; then :
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath__CXX
+fi
hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
@@ -12182,7 +13013,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
# Determine the default libpath from the value encoded in an
# empty executable.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath__CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -12195,30 +13032,42 @@ main ()
_ACEOF
if ac_fn_cxx_try_link "$LINENO"; then :
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath__CXX
+fi
hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
# Warning - without using the other run time loading flags,
# -berok will link without error, but may produce a broken library.
no_undefined_flag_CXX=' ${wl}-bernotok'
allow_undefined_flag_CXX=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec_CXX='$convenience'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec_CXX='$convenience'
+ fi
archive_cmds_need_lc_CXX=yes
# This is similar to how AIX traditionally builds its shared
# libraries.
@@ -12247,29 +13096,76 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
esac
;;
- cygwin* | mingw* | pw32*)
- # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
- # as there is no search path for DLLs.
- hardcode_libdir_flag_spec_CXX='-L$libdir'
- allow_undefined_flag_CXX=unsupported
- always_export_symbols_CXX=no
- enable_shared_with_static_runtimes_CXX=yes
-
- if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- ld_shlibs_CXX=no
- fi
- ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec_CXX=' '
+ allow_undefined_flag_CXX=unsupported
+ always_export_symbols_CXX=yes
+ file_list_spec_CXX='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
+ enable_shared_with_static_runtimes_CXX=yes
+ # Don't use ranlib
+ old_postinstall_cmds_CXX='chmod 644 $oldlib'
+ postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
+ allow_undefined_flag_CXX=unsupported
+ always_export_symbols_CXX=no
+ enable_shared_with_static_runtimes_CXX=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
darwin* | rhapsody*)
@@ -12277,11 +13173,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_direct_CXX=no
hardcode_automatic_CXX=yes
hardcode_shlibpath_var_CXX=unsupported
- whole_archive_flag_spec_CXX=''
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec_CXX=''
+ fi
link_all_deplibs_CXX=yes
allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
- if test "$GCC" = "yes"; then
- output_verbose_link_cmd=echo
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
@@ -12315,7 +13220,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
esac
;;
- freebsd[12]*)
+ freebsd2.*)
# C++ shared libraries reported to be fairly broken before
# switch to ELF
ld_shlibs_CXX=no
@@ -12331,7 +13236,9 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
ld_shlibs_CXX=yes
;;
- gnu*)
+ haiku*)
+ archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ link_all_deplibs_CXX=yes
;;
hpux9*)
@@ -12358,11 +13265,11 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test "$GXX" = yes; then
- archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
else
# FIXME: insert proper C++ library support
ld_shlibs_CXX=no
@@ -12423,7 +13330,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test "$GXX" = yes; then
@@ -12433,10 +13340,10 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
esac
fi
@@ -12466,7 +13373,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
case $cc_basename in
CC*)
# SGI C++
- archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
# Archives containing C++ object files must be created using
# "CC -ar", where "CC" is the IRIX C++ compiler. This is
@@ -12477,9 +13384,9 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
*)
if test "$GXX" = yes; then
if test "$with_gnu_ld" = no; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
else
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
fi
fi
link_all_deplibs_CXX=yes
@@ -12490,7 +13397,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
inherit_rpath_CXX=yes
;;
- linux* | k*bsd*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
@@ -12508,7 +13415,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
@@ -12545,26 +13452,26 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
pgCC* | pgcpp*)
# Portland Group C++ compiler
case `$CC -V` in
- *pgCC\ [1-5]* | *pgcpp\ [1-5]*)
+ *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
prelink_cmds_CXX='tpldir=Template.dir~
rm -rf $tpldir~
$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
- compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
old_archive_cmds_CXX='tpldir=Template.dir~
rm -rf $tpldir~
$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
- $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
$RANLIB $oldlib'
archive_cmds_CXX='tpldir=Template.dir~
rm -rf $tpldir~
$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
archive_expsym_cmds_CXX='tpldir=Template.dir~
rm -rf $tpldir~
$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
;;
- *) # Version 6 will use weak symbols
+ *) # Version 6 and above use weak symbols
archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
;;
@@ -12572,7 +13479,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
- whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
;;
cxx*)
# Compaq C++
@@ -12591,9 +13498,9 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
;;
- xl*)
+ xl* | mpixl* | bgxl*)
# IBM XL 8.0 on PPC, with GNU ld
hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
@@ -12613,13 +13520,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
hardcode_libdir_flag_spec_CXX='-R$libdir'
- whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
compiler_needs_object_CXX=yes
# Not sure whether something based on
# $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
# would be better.
- output_verbose_link_cmd='echo'
+ output_verbose_link_cmd='func_echo_all'
# Archives containing C++ object files must be created using
# "CC -xar", where "CC" is the Sun C++ compiler. This is
@@ -12688,7 +13595,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
export_dynamic_flag_spec_CXX='${wl}-E'
whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
fi
- output_verbose_link_cmd=echo
+ output_verbose_link_cmd=func_echo_all
else
ld_shlibs_CXX=no
fi
@@ -12723,15 +13630,15 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
case $host in
osf3*)
allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
;;
*)
allow_undefined_flag_CXX=' -expect_unresolved \*'
- archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
echo "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
$RM $lib.exp'
hardcode_libdir_flag_spec_CXX='-rpath $libdir'
;;
@@ -12747,17 +13654,17 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test "$GXX" = yes && test "$with_gnu_ld" = no; then
allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
case $host in
osf3*)
- archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
;;
*)
- archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
;;
esac
@@ -12767,7 +13674,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
# FIXME: insert proper C++ library support
@@ -12803,7 +13710,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
solaris*)
case $cc_basename in
- CC*)
+ CC* | sunCC*)
# Sun C++ 4.2, 5.x and Centerline C++
archive_cmds_need_lc_CXX=yes
no_undefined_flag_CXX=' -zdefs'
@@ -12824,7 +13731,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
esac
link_all_deplibs_CXX=yes
- output_verbose_link_cmd='echo'
+ output_verbose_link_cmd='func_echo_all'
# Archives containing C++ object files must be created using
# "CC -xar", where "CC" is the Sun C++ compiler. This is
@@ -12844,14 +13751,14 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GXX" = yes && test "$with_gnu_ld" = no; then
no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
if $CC --version | $GREP -v '^2\.7' > /dev/null; then
- archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
# g++ 2.7 appears to require `-G' NOT `-shared' on this
# platform.
@@ -12862,7 +13769,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
fi
hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
@@ -12916,6 +13823,10 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
CC*)
archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+ '"$old_archive_cmds_CXX"
+ reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+ '"$reload_cmds_CXX"
;;
*)
archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
@@ -12977,6 +13888,14 @@ private:
};
_LT_EOF
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -12990,7 +13909,7 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
pre_test_object_deps_done=no
for p in `eval "$output_verbose_link_cmd"`; do
- case $p in
+ case ${prev}${p} in
-L* | -R* | -l*)
# Some compilers place space between "-{L,R}" and the path.
@@ -12999,13 +13918,22 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
test $p = "-R"; then
prev=$p
continue
- else
- prev=
fi
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
if test "$pre_test_object_deps_done" = no; then
- case $p in
- -L* | -R*)
+ case ${prev} in
+ -L | -R)
# Internal compiler library paths should come after those
# provided the user. The postdeps already come after the
# user supplied libs so there is no need to process them.
@@ -13025,8 +13953,10 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
postdeps_CXX="${postdeps_CXX} ${prev}${p}"
fi
fi
+ prev=
;;
+ *.lto.$objext) ;; # Ignore GCC LTO objects
*.$objext)
# This assumes that the test object file only shows up
# once in the compiler output.
@@ -13062,6 +13992,7 @@ else
fi
$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
# PORTME: override above test on systems where it is broken
case $host_os in
@@ -13097,7 +14028,7 @@ linux*)
solaris*)
case $cc_basename in
- CC*)
+ CC* | sunCC*)
# The more standards-conforming stlport4 library is
# incompatible with the Cstd library. Avoid specifying
# it if it's in CXXFLAGS. Ignore libCrun as
@@ -13162,8 +14093,6 @@ fi
lt_prog_compiler_pic_CXX=
lt_prog_compiler_static_CXX=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
# C++ specific cases for pic, static, wl, etc.
if test "$GXX" = yes; then
@@ -13197,7 +14126,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
# PIC is the default for these OSes.
;;
- mingw* | cygwin* | os2* | pw32*)
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
# This hack is so that the source file can tell whether it is being
# built for inclusion in a dll (and should export symbols for example).
# Although the cygwin gcc ignores -fPIC, still need this for old-style
@@ -13213,6 +14142,11 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
# DJGPP does not support shared libraries at all
lt_prog_compiler_pic_CXX=
;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static_CXX=
+ ;;
interix[3-9]*)
# Interix 3.x gcc -fpic/-fPIC options generate broken code.
# Instead, we relocate shared libraries at runtime.
@@ -13223,10 +14157,11 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
fi
;;
hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
case $host_cpu in
- hppa*64*|ia64*)
+ hppa*64*)
;;
*)
lt_prog_compiler_pic_CXX='-fPIC'
@@ -13261,6 +14196,11 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
;;
esac
;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+ ;;
dgux*)
case $cc_basename in
ec++*)
@@ -13317,19 +14257,26 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
;;
esac
;;
- linux* | k*bsd*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
KCC*)
# KAI C++ Compiler
lt_prog_compiler_wl_CXX='--backend -Wl,'
lt_prog_compiler_pic_CXX='-fPIC'
;;
- icpc* | ecpc* )
- # Intel C++
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
lt_prog_compiler_wl_CXX='-Wl,'
lt_prog_compiler_pic_CXX='-KPIC'
lt_prog_compiler_static_CXX='-static'
;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-fPIC'
+ lt_prog_compiler_static_CXX='-static'
+ ;;
pgCC* | pgcpp*)
# Portland Group C++ compiler
lt_prog_compiler_wl_CXX='-Wl,'
@@ -13343,8 +14290,8 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
lt_prog_compiler_pic_CXX=
lt_prog_compiler_static_CXX='-non_shared'
;;
- xlc* | xlC*)
- # IBM XL 8.0 on PPC
+ xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
lt_prog_compiler_wl_CXX='-Wl,'
lt_prog_compiler_pic_CXX='-qpic'
lt_prog_compiler_static_CXX='-qstaticlink'
@@ -13374,7 +14321,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
;;
esac
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu)
;;
*qnx* | *nto*)
# QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -13406,7 +14353,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
;;
solaris*)
case $cc_basename in
- CC*)
+ CC* | sunCC*)
# Sun C++ 4.2, 5.x and Centerline C++
lt_prog_compiler_pic_CXX='-KPIC'
lt_prog_compiler_static_CXX='-Bstatic'
@@ -13471,10 +14418,17 @@ case $host_os in
lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
;;
esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX" >&5
-$as_echo "$lt_prog_compiler_pic_CXX" >&6; }
-
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
#
# Check to make sure the PIC flag actually works.
@@ -13498,15 +14452,15 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13501: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:13505: \$? = $ac_status" >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
$SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
lt_cv_prog_compiler_pic_works_CXX=yes
@@ -13532,6 +14486,8 @@ fi
+
+
#
# Check to make sure the static flag actually works.
#
@@ -13551,7 +14507,7 @@ else
if test -s conftest.err; then
# Append any errors to the config.log.
cat conftest.err 1>&5
- $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
$SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
if diff conftest.exp conftest.er2 >/dev/null; then
lt_cv_prog_compiler_static_works_CXX=yes
@@ -13597,16 +14553,16 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13600: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:13604: \$? = $ac_status" >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
$SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
lt_cv_prog_compiler_c_o_CXX=yes
@@ -13649,16 +14605,16 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13652: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:13656: \$? = $ac_status" >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
$SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
lt_cv_prog_compiler_c_o_CXX=yes
@@ -13709,27 +14665,40 @@ fi
$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
case $host_os in
aix[4-9]*)
# If we're using GNU nm, then we don't want the "-C" option.
# -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global defined
+ # symbols, whereas GNU nm marks them as "W".
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
else
export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
fi
;;
pw32*)
export_symbols_cmds_CXX="$ltdll_cmds"
- ;;
- cygwin* | mingw*)
- export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ link_all_deplibs_CXX=no
+ ;;
*)
export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
+ ;;
esac
- exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
$as_echo "$ld_shlibs_CXX" >&6; }
@@ -13761,44 +14730,50 @@ x|xyes)
# to ld, don't add -lc before -lgcc.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
- $RM conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl_CXX
- pic_flag=$lt_prog_compiler_pic_CXX
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
- allow_undefined_flag_CXX=
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl_CXX
+ pic_flag=$lt_prog_compiler_pic_CXX
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+ allow_undefined_flag_CXX=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
(eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
- then
- archive_cmds_need_lc_CXX=no
- else
- archive_cmds_need_lc_CXX=yes
- fi
- allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $RM conftest*
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc_CXX" >&5
-$as_echo "$archive_cmds_need_lc_CXX" >&6; }
+ then
+ lt_cv_archive_cmds_need_lc_CXX=no
+ else
+ lt_cv_archive_cmds_need_lc_CXX=yes
+ fi
+ allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+ archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
;;
esac
fi
@@ -13866,8 +14841,6 @@ esac
-
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
$as_echo_n "checking dynamic linker characteristics... " >&6; }
@@ -13893,7 +14866,7 @@ need_version=unknown
case $host_os in
aix3*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
shlibpath_var=LIBPATH
@@ -13902,7 +14875,7 @@ aix3*)
;;
aix[4-9]*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
hardcode_into_libs=yes
@@ -13955,7 +14928,7 @@ amigaos*)
m68k)
library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;;
esac
;;
@@ -13967,7 +14940,7 @@ beos*)
;;
bsdi[45]*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
@@ -13980,14 +14953,15 @@ bsdi[45]*)
# libtool to hard-code these into programs
;;
-cygwin* | mingw* | pw32*)
+cygwin* | mingw* | pw32* | cegcc*)
version_type=windows
shrext_cmds=".dll"
need_version=no
need_lib_prefix=no
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32*)
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
library_names_spec='$libname.dll.a'
# DLL is installed to $(libdir)/../bin by postinstall_cmds
postinstall_cmds='base_file=`basename \${file}`~
@@ -14008,36 +14982,82 @@ cygwin* | mingw* | pw32*)
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+
;;
- mingw*)
+ mingw* | cegcc*)
# MinGW DLLs use traditional 'lib' prefix
soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
;;
esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
;;
*)
+ # Assume MSVC wrapper
library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
;;
esac
- dynamic_linker='Win32 ld.exe'
# FIXME: first we should search . and the directory the executable is in
shlibpath_var=PATH
;;
@@ -14057,7 +15077,7 @@ darwin* | rhapsody*)
;;
dgux*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
@@ -14065,10 +15085,6 @@ dgux*)
shlibpath_var=LD_LIBRARY_PATH
;;
-freebsd1*)
- dynamic_linker=no
- ;;
-
freebsd* | dragonfly*)
# DragonFly does not have aout. When/if they implement a new
# versioning mechanism, adjust this.
@@ -14076,7 +15092,7 @@ freebsd* | dragonfly*)
objformat=`/usr/bin/objformat`
else
case $host_os in
- freebsd[123]*) objformat=aout ;;
+ freebsd[23].*) objformat=aout ;;
*) objformat=elf ;;
esac
fi
@@ -14094,7 +15110,7 @@ freebsd* | dragonfly*)
esac
shlibpath_var=LD_LIBRARY_PATH
case $host_os in
- freebsd2*)
+ freebsd2.*)
shlibpath_overrides_runpath=yes
;;
freebsd3.[01]* | freebsdelf3.[01]*)
@@ -14113,13 +15129,16 @@ freebsd* | dragonfly*)
esac
;;
-gnu*)
- version_type=linux
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
+ dynamic_linker="$host_os runtime_loader"
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
hardcode_into_libs=yes
;;
@@ -14165,12 +15184,14 @@ hpux9* | hpux10* | hpux11*)
soname_spec='${libname}${release}${shared_ext}$major'
;;
esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
;;
interix[3-9]*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
@@ -14186,7 +15207,7 @@ irix5* | irix6* | nonstopux*)
nonstopux*) version_type=nonstopux ;;
*)
if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
else
version_type=irix
fi ;;
@@ -14223,9 +15244,9 @@ linux*oldld* | linux*aout* | linux*coff*)
dynamic_linker=no
;;
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
- version_type=linux
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -14233,12 +15254,17 @@ linux* | k*bsd*-gnu)
finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
+
# Some binutils ld are patched to set DT_RUNPATH
- save_LDFLAGS=$LDFLAGS
- save_libdir=$libdir
- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -14251,13 +15277,17 @@ main ()
_ACEOF
if ac_fn_cxx_try_link "$LINENO"; then :
if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
- shlibpath_overrides_runpath=yes
+ lt_cv_shlibpath_overrides_runpath=yes
fi
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
- LDFLAGS=$save_LDFLAGS
- libdir=$save_libdir
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
# This implies no fast_install, which is unacceptable.
# Some rework will be needed to allow for fast_install
@@ -14266,7 +15296,7 @@ rm -f core conftest.err conftest.$ac_objext \
# Append ld.so.conf contents to the search path
if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
fi
@@ -14279,6 +15309,18 @@ rm -f core conftest.err conftest.$ac_objext \
dynamic_linker='GNU/Linux ld.so'
;;
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
netbsd*)
version_type=sunos
need_lib_prefix=no
@@ -14298,7 +15340,7 @@ netbsd*)
;;
newsos6)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
@@ -14367,7 +15409,7 @@ rdos*)
;;
solaris*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -14392,7 +15434,7 @@ sunos4*)
;;
sysv4 | sysv4.3*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
@@ -14416,7 +15458,7 @@ sysv4 | sysv4.3*)
sysv4*MP*)
if test -d /usr/nec ;then
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
soname_spec='$libname${shared_ext}.$major'
shlibpath_var=LD_LIBRARY_PATH
@@ -14447,17 +15489,17 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
tpf*)
# TPF is a cross-target only. Preferred cross-host = GNU/Linux.
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_name_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
;;
uts4*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
@@ -14518,6 +15560,8 @@ fi
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
hardcode_action_CXX=
@@ -14565,6 +15609,7 @@ fi
fi # test -n "$compiler"
CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
LDCXX=$LD
LD=$lt_save_LD
GCC=$lt_save_GCC
@@ -14593,6 +15638,8 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
ac_config_commands="$ac_config_commands libtool"
@@ -15053,7 +16100,7 @@ fi
if test "$with_protoc" != "no"; then :
PROTOC=$with_protoc
- if test "$with_protoc" == "yes"; then :
+ if test "$with_protoc" = "yes"; then :
# No argument given. Use system protoc.
PROTOC=protoc
@@ -15219,7 +16266,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_acx_pthread_config="yes"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -15374,7 +16421,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_PTHREAD_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -15576,6 +16623,77 @@ $as_echo "$as_me: WARNING: Impossible to determine how to use pthreads with shar
acx_pthread_ok=no
fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether what we have so far is sufficient with -nostdlib" >&5
+$as_echo_n "checking whether what we have so far is sufficient with -nostdlib... " >&6; }
+ CFLAGS="-nostdlib $CFLAGS"
+ # we need c with nostdlib
+ LIBS="$LIBS -lc"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ done=yes
+else
+ done=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ if test "x$done" = xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+
+ if test x"$done" = xno; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lpthread saves the day" >&5
+$as_echo_n "checking whether -lpthread saves the day... " >&6; }
+ LIBS="-lpthread $LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ done=yes
+else
+ done=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ if test "x$done" = xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ PTHREAD_LIBS="$PTHREAD_LIBS -lpthread"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Impossible to determine how to use pthreads with shared libraries and -nostdlib" >&5
+$as_echo "$as_me: WARNING: Impossible to determine how to use pthreads with shared libraries and -nostdlib" >&2;}
+ fi
+ fi
+
CFLAGS="$save_CFLAGS"
LIBS="$save_LIBS"
CC="$save_CC"
@@ -15604,7 +16722,8 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the location of hash_map" >&5
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking the location of hash_map" >&5
$as_echo_n "checking the location of hash_map... " >&6; }
ac_ext=cpp
@@ -15613,44 +16732,81 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
- ac_cv_cxx_hash_map_header=""
- ac_cv_cxx_hash_map_class=""
- for location in tr1/unordered_map ext/hash_map hash_map; do
- for namespace in std::tr1 __gnu_cxx "" std stdext; do
- for name in unordered_map hash_map; do
-
- if test -z "$ac_cv_cxx_hash_map_header"; then
+ ac_cv_cxx_hash_map=""
+ # First try unordered_map, but not on gcc's before 4.2 -- I've
+ # seen unexplainable unordered_map bugs with -O2 on older gcc's.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
+ # error GCC too old for unordered_map
+ #endif
- # On OSX 1.5 / GCC 4.0.1 (the standard compiler on that platform),
- # calling find() on a const unordered_map does not compile. So, we
- # include a call to find() in our test to detect this broken
- # implementation and avoid using it. Note that ext/hash_map works
- # fine on this platform, so we'll end up using that.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+int
+main ()
+{
+/* no program body necessary */
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ stl_hash_old_gcc=no
+else
+ stl_hash_old_gcc=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ for location in unordered_map tr1/unordered_map; do
+ for namespace in std std::tr1; do
+ if test -z "$ac_cv_cxx_hash_map" -a "$stl_hash_old_gcc" != yes; then
+ # Some older gcc's have a buggy tr1, so test a bit of code.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <$location>
int
main ()
{
-const ${namespace}::$name<int, int> t;
- t.find(1);
+const ${namespace}::unordered_map<int, int> t;
+ return t.find(5) == t.end();
;
return 0;
}
_ACEOF
if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_cv_cxx_hash_map_header="<$location>";
- ac_cv_cxx_hash_namespace="$namespace";
- ac_cv_cxx_hash_map_class="$name";
+ ac_cv_cxx_hash_map="<$location>";
+ ac_cv_cxx_hash_namespace="$namespace";
+ ac_cv_cxx_hash_map_class="unordered_map";
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
- done
+ fi
+ done
+ done
+ # Now try hash_map
+ for location in ext/hash_map hash_map; do
+ for namespace in __gnu_cxx "" std stdext; do
+ if test -z "$ac_cv_cxx_hash_map"; then
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$location>
+int
+main ()
+{
+${namespace}::hash_map<int, int> t
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_hash_map="<$location>";
+ ac_cv_cxx_hash_namespace="$namespace";
+ ac_cv_cxx_hash_map_class="hash_map";
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
done
done
- ac_cv_cxx_hash_set_header=`echo "$ac_cv_cxx_hash_map_header" | sed s/map/set/`;
+ ac_cv_cxx_hash_set=`echo "$ac_cv_cxx_hash_map" | sed s/map/set/`;
ac_cv_cxx_hash_set_class=`echo "$ac_cv_cxx_hash_map_class" | sed s/map/set/`;
- if test -n "$ac_cv_cxx_hash_map_header"; then
+ if test -n "$ac_cv_cxx_hash_map"; then
$as_echo "#define HAVE_HASH_MAP 1" >>confdefs.h
@@ -15659,31 +16815,31 @@ $as_echo "#define HAVE_HASH_SET 1" >>confdefs.h
cat >>confdefs.h <<_ACEOF
-#define HASH_MAP_H $ac_cv_cxx_hash_map_header
+#define HASH_MAP_H $ac_cv_cxx_hash_map
_ACEOF
cat >>confdefs.h <<_ACEOF
-#define HASH_SET_H $ac_cv_cxx_hash_set_header
+#define HASH_SET_H $ac_cv_cxx_hash_set
_ACEOF
cat >>confdefs.h <<_ACEOF
-#define HASH_MAP_CLASS $ac_cv_cxx_hash_map_class
+#define HASH_NAMESPACE $ac_cv_cxx_hash_namespace
_ACEOF
cat >>confdefs.h <<_ACEOF
-#define HASH_SET_CLASS $ac_cv_cxx_hash_set_class
+#define HASH_MAP_CLASS $ac_cv_cxx_hash_map_class
_ACEOF
cat >>confdefs.h <<_ACEOF
-#define HASH_NAMESPACE $ac_cv_cxx_hash_namespace
+#define HASH_SET_CLASS $ac_cv_cxx_hash_set_class
_ACEOF
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_hash_map_header" >&5
-$as_echo "$ac_cv_cxx_hash_map_header" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_hash_map" >&5
+$as_echo "$ac_cv_cxx_hash_map" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
$as_echo "" >&6; }
@@ -15692,6 +16848,75 @@ $as_echo "$as_me: WARNING: could not find an STL hash_map" >&2;}
fi
+case "$target_os" in
+ mingw* | cygwin* | win*)
+ ;;
+ *)
+ # Need to link against rt on Solaris
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sched_yield" >&5
+$as_echo_n "checking for library containing sched_yield... " >&6; }
+if ${ac_cv_search_sched_yield+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sched_yield ();
+int
+main ()
+{
+return sched_yield ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' rt; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_search_sched_yield=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_sched_yield+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_sched_yield+:} false; then :
+
+else
+ ac_cv_search_sched_yield=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sched_yield" >&5
+$as_echo "$ac_cv_search_sched_yield" >&6; }
+ac_res=$ac_cv_search_sched_yield
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "sched_yield was not found on your system
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ ;;
+esac
+
# HACK: Make gtest's configure script pick up our copy of CFLAGS and CXXFLAGS,
# since the flags added by ACX_CHECK_SUNCC must be used when compiling gtest
# too.
@@ -15813,6 +17038,18 @@ LIBOBJS=$ac_libobjs
LTLIBOBJS=$ac_ltlibobjs
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
if test -n "$EXEEXT"; then
am__EXEEXT_TRUE=
am__EXEEXT_FALSE='#'
@@ -15837,10 +17074,6 @@ if test -z "${GCC_TRUE}" && test -z "${GCC_FALSE}"; then
as_fn_error $? "conditional \"GCC\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
-if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
- as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
if test -z "${HAVE_ZLIB_TRUE}" && test -z "${HAVE_ZLIB_FALSE}"; then
as_fn_error $? "conditional \"HAVE_ZLIB\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -16147,16 +17380,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -16216,28 +17449,16 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -16258,8 +17479,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by Protocol Buffers $as_me 2.3.0, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+This file was extended by Protocol Buffers $as_me 2.6.1, which was
+generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -16324,11 +17545,11 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-Protocol Buffers config.status 2.3.0
-configured by $0, generated by GNU Autoconf 2.68,
+Protocol Buffers config.status 2.6.1
+configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -16419,7 +17640,7 @@ fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'
@@ -16453,183 +17674,208 @@ AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
sed_quote_subst='$sed_quote_subst'
double_quote_subst='$double_quote_subst'
delay_variable_subst='$delay_variable_subst'
-macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`'
-macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`'
-enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`'
-enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`'
-pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`'
-enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`'
-host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`'
-host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`'
-host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`'
-build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`'
-build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`'
-build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`'
-SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`'
-Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`'
-GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`'
-EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`'
-FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`'
-LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`'
-NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`'
-LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`'
-max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`'
-ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`'
-exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`'
-lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`'
-lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`'
-lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`'
-reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`'
-reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`'
-file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`'
-AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`'
-AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`'
-STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`'
-RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`'
-old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`'
-CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`'
-compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`'
-GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
-objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`'
-SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`'
-ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`'
-MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`'
-need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`'
-DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`'
-NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`'
-LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`'
-OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`'
-OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`'
-libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`'
-shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`'
-enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`'
-export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
-whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
-compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`'
-allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
-no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`'
-inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`'
-link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`'
-fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`'
-always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`'
-export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
-include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
-prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`'
-variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`'
-need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
-need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`'
-version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`'
-runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`'
-shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
-shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`'
-libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`'
-library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`'
-soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`'
-postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`'
-sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
-sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`'
-enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`'
-enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`'
-enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`'
-old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`'
-striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`'
-compiler_lib_search_dirs='`$ECHO "X$compiler_lib_search_dirs" | $Xsed -e "$delay_single_quote_subst"`'
-predep_objects='`$ECHO "X$predep_objects" | $Xsed -e "$delay_single_quote_subst"`'
-postdep_objects='`$ECHO "X$postdep_objects" | $Xsed -e "$delay_single_quote_subst"`'
-predeps='`$ECHO "X$predeps" | $Xsed -e "$delay_single_quote_subst"`'
-postdeps='`$ECHO "X$postdeps" | $Xsed -e "$delay_single_quote_subst"`'
-compiler_lib_search_path='`$ECHO "X$compiler_lib_search_path" | $Xsed -e "$delay_single_quote_subst"`'
-LD_CXX='`$ECHO "X$LD_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_cmds_CXX='`$ECHO "X$old_archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-compiler_CXX='`$ECHO "X$compiler_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-GCC_CXX='`$ECHO "X$GCC_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "X$lt_prog_compiler_no_builtin_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_wl_CXX='`$ECHO "X$lt_prog_compiler_wl_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_pic_CXX='`$ECHO "X$lt_prog_compiler_pic_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_static_CXX='`$ECHO "X$lt_prog_compiler_static_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_prog_compiler_c_o_CXX='`$ECHO "X$lt_cv_prog_compiler_c_o_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-archive_cmds_need_lc_CXX='`$ECHO "X$archive_cmds_need_lc_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-enable_shared_with_static_runtimes_CXX='`$ECHO "X$enable_shared_with_static_runtimes_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-export_dynamic_flag_spec_CXX='`$ECHO "X$export_dynamic_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-whole_archive_flag_spec_CXX='`$ECHO "X$whole_archive_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-compiler_needs_object_CXX='`$ECHO "X$compiler_needs_object_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_from_new_cmds_CXX='`$ECHO "X$old_archive_from_new_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_from_expsyms_cmds_CXX='`$ECHO "X$old_archive_from_expsyms_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-archive_cmds_CXX='`$ECHO "X$archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-archive_expsym_cmds_CXX='`$ECHO "X$archive_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-module_cmds_CXX='`$ECHO "X$module_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-module_expsym_cmds_CXX='`$ECHO "X$module_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-with_gnu_ld_CXX='`$ECHO "X$with_gnu_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-allow_undefined_flag_CXX='`$ECHO "X$allow_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-no_undefined_flag_CXX='`$ECHO "X$no_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_flag_spec_CXX='`$ECHO "X$hardcode_libdir_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_flag_spec_ld_CXX='`$ECHO "X$hardcode_libdir_flag_spec_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_separator_CXX='`$ECHO "X$hardcode_libdir_separator_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_direct_CXX='`$ECHO "X$hardcode_direct_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_direct_absolute_CXX='`$ECHO "X$hardcode_direct_absolute_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_minus_L_CXX='`$ECHO "X$hardcode_minus_L_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_shlibpath_var_CXX='`$ECHO "X$hardcode_shlibpath_var_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_automatic_CXX='`$ECHO "X$hardcode_automatic_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-inherit_rpath_CXX='`$ECHO "X$inherit_rpath_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-link_all_deplibs_CXX='`$ECHO "X$link_all_deplibs_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-fix_srcfile_path_CXX='`$ECHO "X$fix_srcfile_path_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-always_export_symbols_CXX='`$ECHO "X$always_export_symbols_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-export_symbols_cmds_CXX='`$ECHO "X$export_symbols_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-exclude_expsyms_CXX='`$ECHO "X$exclude_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-include_expsyms_CXX='`$ECHO "X$include_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-prelink_cmds_CXX='`$ECHO "X$prelink_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-file_list_spec_CXX='`$ECHO "X$file_list_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_action_CXX='`$ECHO "X$hardcode_action_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-compiler_lib_search_dirs_CXX='`$ECHO "X$compiler_lib_search_dirs_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-predep_objects_CXX='`$ECHO "X$predep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-postdep_objects_CXX='`$ECHO "X$postdep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-predeps_CXX='`$ECHO "X$predeps_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-postdeps_CXX='`$ECHO "X$postdeps_CXX" | $Xsed -e "$delay_single_quote_subst"`'
-compiler_lib_search_path_CXX='`$ECHO "X$compiler_lib_search_path_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
LTCC='$LTCC'
LTCFLAGS='$LTCFLAGS'
compiler='$compiler_DEFAULT'
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
# Quote evaled strings.
-for var in SED \
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
GREP \
EGREP \
FGREP \
@@ -16639,10 +17885,16 @@ LN_S \
lt_SP2NL \
lt_NL2SP \
reload_flag \
+OBJDUMP \
deplibs_check_method \
file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
AR \
AR_FLAGS \
+archiver_list_spec \
STRIP \
RANLIB \
CC \
@@ -16652,14 +17904,14 @@ lt_cv_sys_global_symbol_pipe \
lt_cv_sys_global_symbol_to_cdecl \
lt_cv_sys_global_symbol_to_c_name_address \
lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
-SHELL \
-ECHO \
+nm_file_list_spec \
lt_prog_compiler_no_builtin_flag \
-lt_prog_compiler_wl \
lt_prog_compiler_pic \
+lt_prog_compiler_wl \
lt_prog_compiler_static \
lt_cv_prog_compiler_c_o \
need_locks \
+MANIFEST_TOOL \
DSYMUTIL \
NMEDIT \
LIPO \
@@ -16673,9 +17925,7 @@ with_gnu_ld \
allow_undefined_flag \
no_undefined_flag \
hardcode_libdir_flag_spec \
-hardcode_libdir_flag_spec_ld \
hardcode_libdir_separator \
-fix_srcfile_path \
exclude_expsyms \
include_expsyms \
file_list_spec \
@@ -16683,6 +17933,7 @@ variables_saved_for_relink \
libname_spec \
library_names_spec \
soname_spec \
+install_override_mode \
finish_eval \
old_striplib \
striplib \
@@ -16693,10 +17944,11 @@ predeps \
postdeps \
compiler_lib_search_path \
LD_CXX \
+reload_flag_CXX \
compiler_CXX \
lt_prog_compiler_no_builtin_flag_CXX \
-lt_prog_compiler_wl_CXX \
lt_prog_compiler_pic_CXX \
+lt_prog_compiler_wl_CXX \
lt_prog_compiler_static_CXX \
lt_cv_prog_compiler_c_o_CXX \
export_dynamic_flag_spec_CXX \
@@ -16706,9 +17958,7 @@ with_gnu_ld_CXX \
allow_undefined_flag_CXX \
no_undefined_flag_CXX \
hardcode_libdir_flag_spec_CXX \
-hardcode_libdir_flag_spec_ld_CXX \
hardcode_libdir_separator_CXX \
-fix_srcfile_path_CXX \
exclude_expsyms_CXX \
include_expsyms_CXX \
file_list_spec_CXX \
@@ -16718,9 +17968,9 @@ postdep_objects_CXX \
predeps_CXX \
postdeps_CXX \
compiler_lib_search_path_CXX; do
- case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[\\\\\\\`\\"\\\$]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
;;
*)
eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -16742,11 +17992,13 @@ module_cmds \
module_expsym_cmds \
export_symbols_cmds \
prelink_cmds \
+postlink_cmds \
postinstall_cmds \
postuninstall_cmds \
finish_cmds \
sys_lib_search_path_spec \
sys_lib_dlsearch_path_spec \
+reload_cmds_CXX \
old_archive_cmds_CXX \
old_archive_from_new_cmds_CXX \
old_archive_from_expsyms_cmds_CXX \
@@ -16755,10 +18007,11 @@ archive_expsym_cmds_CXX \
module_cmds_CXX \
module_expsym_cmds_CXX \
export_symbols_cmds_CXX \
-prelink_cmds_CXX; do
- case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+prelink_cmds_CXX \
+postlink_cmds_CXX; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[\\\\\\\`\\"\\\$]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
;;
*)
eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -16766,12 +18019,6 @@ prelink_cmds_CXX; do
esac
done
-# Fix-up fallback echo if it was mangled by the above quoting rules.
-case \$lt_ECHO in
-*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\`
- ;;
-esac
-
ac_aux_dir='$ac_aux_dir'
xsi_shell='$xsi_shell'
lt_shell_append='$lt_shell_append'
@@ -17405,7 +18652,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
case $ac_file$ac_mode in
"depfiles":C) test x"$AMDEP_TRUE" != x"" || {
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
@@ -17418,7 +18665,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
+ # We used to match only the files named 'Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
@@ -17452,21 +18699,19 @@ $as_echo X"$mf" |
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
+ # from the Makefile without running 'make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
+ test -z "$am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`$as_dirname -- "$file" ||
@@ -17520,7 +18765,8 @@ $as_echo X"$file" |
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
#
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-# 2006, 2007, 2008 Free Software Foundation, Inc.
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
# Written by Gordon Matzigkeit, 1996
#
# This file is part of GNU Libtool.
@@ -17568,6 +18814,15 @@ pic_mode=$pic_mode
# Whether or not to optimize for fast installation.
fast_install=$enable_fast_install
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
# The host system.
host_alias=$host_alias
host=$host
@@ -17617,20 +18872,42 @@ SP2NL=$lt_lt_SP2NL
# turn newlines into spaces.
NL2SP=$lt_lt_NL2SP
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
# Method to check whether dependent libraries are shared objects.
deplibs_check_method=$lt_deplibs_check_method
-# Command to use when deplibs_check_method == "file_magic".
+# Command to use when deplibs_check_method = "file_magic".
file_magic_cmd=$lt_file_magic_cmd
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
# The archiver.
AR=$lt_AR
+
+# Flags to create an archive.
AR_FLAGS=$lt_AR_FLAGS
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
# A symbol stripping program.
STRIP=$lt_STRIP
@@ -17639,6 +18916,9 @@ RANLIB=$lt_RANLIB
old_postinstall_cmds=$lt_old_postinstall_cmds
old_postuninstall_cmds=$lt_old_postuninstall_cmds
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
# A C compiler.
LTCC=$lt_CC
@@ -17657,14 +18937,14 @@ global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
# Transform the output of nm in a C name address pair when lib prefix is needed.
global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
-# An echo program that does not interpret backslashes.
-ECHO=$lt_ECHO
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
# Used to examine libraries when file_magic_cmd begins with "file".
MAGIC_CMD=$MAGIC_CMD
@@ -17672,6 +18952,9 @@ MAGIC_CMD=$MAGIC_CMD
# Must we lock files when doing compilation?
need_locks=$lt_need_locks
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
DSYMUTIL=$lt_DSYMUTIL
@@ -17728,6 +19011,9 @@ library_names_spec=$lt_library_names_spec
# The coded name of the library, if different from the real name.
soname_spec=$lt_soname_spec
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
# Command to use after installation of a shared archive.
postinstall_cmds=$lt_postinstall_cmds
@@ -17767,6 +19053,10 @@ striplib=$lt_striplib
# The linker used to build libraries.
LD=$lt_LD
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
# Commands used to build an old-style archive.
old_archive_cmds=$lt_old_archive_cmds
@@ -17779,12 +19069,12 @@ with_gcc=$GCC
# Compiler flag to turn off builtin functions.
no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl
-
# Additional compiler flags for building library objects.
pic_flag=$lt_lt_prog_compiler_pic
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
# Compiler flag to prevent dynamic linking.
link_static_flag=$lt_lt_prog_compiler_static
@@ -17834,10 +19124,6 @@ no_undefined_flag=$lt_no_undefined_flag
# This must work even if \$libdir does not exist
hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
-# If ld is used when linking, flag to hardcode \$libdir into a binary
-# during linking. This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
-
# Whether we need a single "-rpath" flag with a separated argument.
hardcode_libdir_separator=$lt_hardcode_libdir_separator
@@ -17871,9 +19157,6 @@ inherit_rpath=$inherit_rpath
# Whether libtool must link a program against all its dependency libraries.
link_all_deplibs=$link_all_deplibs
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path=$lt_fix_srcfile_path
-
# Set to "yes" if exported symbols are required.
always_export_symbols=$always_export_symbols
@@ -17889,6 +19172,9 @@ include_expsyms=$lt_include_expsyms
# Commands necessary for linking programs (against libraries) with templates.
prelink_cmds=$lt_prelink_cmds
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
# Specify filename containing input files.
file_list_spec=$lt_file_list_spec
@@ -17935,212 +19221,169 @@ ltmain="$ac_aux_dir/ltmain.sh"
# if finds mixed CR/LF and LF-only lines. Since sed operates in
# text mode, it properly converts lines to CR/LF. This bash problem
# is reportedly fixed, but why not run on old versions too?
- sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
- || (rm -f "$cfgfile"; exit 1)
-
- case $xsi_shell in
- yes)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac
-}
-
-# func_basename file
-func_basename ()
-{
- func_basename_result="${1##*/}"
-}
-
-# func_dirname_and_basename file append nondir_replacement
-# perform func_basename and func_dirname in a single function
-# call:
-# dirname: Compute the dirname of FILE. If nonempty,
-# add APPEND to the result, otherwise set result
-# to NONDIR_REPLACEMENT.
-# value returned in "$func_dirname_result"
-# basename: Compute filename of FILE.
-# value retuned in "$func_basename_result"
-# Implementation must be kept synchronized with func_dirname
-# and func_basename. For efficiency, we do not delegate to
-# those functions but instead duplicate the functionality here.
-func_dirname_and_basename ()
-{
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac
- func_basename_result="${1##*/}"
-}
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-func_stripname ()
-{
- # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
- # positional parameters, so assign one to ordinary parameter first.
- func_stripname_result=${3}
- func_stripname_result=${func_stripname_result#"${1}"}
- func_stripname_result=${func_stripname_result%"${2}"}
-}
-
-# func_opt_split
-func_opt_split ()
-{
- func_opt_split_opt=${1%%=*}
- func_opt_split_arg=${1#*=}
-}
-
-# func_lo2o object
-func_lo2o ()
-{
- case ${1} in
- *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
- *) func_lo2o_result=${1} ;;
- esac
-}
-
-# func_xform libobj-or-source
-func_xform ()
-{
- func_xform_result=${1%.*}.lo
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
- func_arith_result=$(( $* ))
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
- func_len_result=${#1}
-}
-
-_LT_EOF
- ;;
- *) # Bourne compatible functions.
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
- # Extract subdirectory from the argument.
- func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
- if test "X$func_dirname_result" = "X${1}"; then
- func_dirname_result="${3}"
- else
- func_dirname_result="$func_dirname_result${2}"
- fi
-}
-
-# func_basename file
-func_basename ()
-{
- func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
-}
-
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-# func_strip_suffix prefix name
-func_stripname ()
-{
- case ${2} in
- .*) func_stripname_result=`$ECHO "X${3}" \
- | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
- *) func_stripname_result=`$ECHO "X${3}" \
- | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
- esac
-}
-
-# sed scripts:
-my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
-my_sed_long_arg='1s/^-[^=]*=//'
-
-# func_opt_split
-func_opt_split ()
-{
- func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
- func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
-}
-
-# func_lo2o object
-func_lo2o ()
-{
- func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
-}
-
-# func_xform libobj-or-source
-func_xform ()
-{
- func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'`
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
- func_arith_result=`expr "$@"`
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
- func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
-}
-
-_LT_EOF
-esac
-
-case $lt_shell_append in
- yes)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
- eval "$1+=\$2"
-}
-_LT_EOF
- ;;
- *)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
- eval "$1=\$$1\$2"
-}
-
-_LT_EOF
- ;;
- esac
-
-
- sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
- || (rm -f "$cfgfile"; exit 1)
-
- mv -f "$cfgfile" "$ofile" ||
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ if test x"$xsi_shell" = xyes; then
+ sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\ # positional parameters, so assign one to ordinary parameter first.\
+\ func_stripname_result=${3}\
+\ func_stripname_result=${func_stripname_result#"${1}"}\
+\ func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\ func_split_long_opt_name=${1%%=*}\
+\ func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\ func_split_short_opt_arg=${1#??}\
+\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\ case ${1} in\
+\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\ *) func_lo2o_result=${1} ;;\
+\ esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+ func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+ func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+ func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+ eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\ func_quote_for_eval "${2}"\
+\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+ mv -f "$cfgfile" "$ofile" ||
(rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
chmod +x "$ofile"
@@ -18152,6 +19395,10 @@ _LT_EOF
# The linker used to build libraries.
LD=$lt_LD_CXX
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
# Commands used to build an old-style archive.
old_archive_cmds=$lt_old_archive_cmds_CXX
@@ -18164,12 +19411,12 @@ with_gcc=$GCC_CXX
# Compiler flag to turn off builtin functions.
no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl_CXX
-
# Additional compiler flags for building library objects.
pic_flag=$lt_lt_prog_compiler_pic_CXX
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
# Compiler flag to prevent dynamic linking.
link_static_flag=$lt_lt_prog_compiler_static_CXX
@@ -18219,10 +19466,6 @@ no_undefined_flag=$lt_no_undefined_flag_CXX
# This must work even if \$libdir does not exist
hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
-# If ld is used when linking, flag to hardcode \$libdir into a binary
-# during linking. This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX
-
# Whether we need a single "-rpath" flag with a separated argument.
hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
@@ -18256,9 +19499,6 @@ inherit_rpath=$inherit_rpath_CXX
# Whether libtool must link a program against all its dependency libraries.
link_all_deplibs=$link_all_deplibs_CXX
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path=$lt_fix_srcfile_path_CXX
-
# Set to "yes" if exported symbols are required.
always_export_symbols=$always_export_symbols_CXX
@@ -18274,6 +19514,9 @@ include_expsyms=$lt_include_expsyms_CXX
# Commands necessary for linking programs (against libraries) with templates.
prelink_cmds=$lt_prelink_cmds_CXX
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_CXX
+
# Specify filename containing input files.
file_list_spec=$lt_file_list_spec_CXX
diff --git a/configure.ac b/configure.ac
index 63322b4..c07067c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -12,8 +12,9 @@ AC_PREREQ(2.59)
# 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],[2.3.0],[protobuf@googlegroups.com],[protobuf])
+AC_INIT([Protocol Buffers],[2.6.1],[protobuf@googlegroups.com],[protobuf])
+AM_MAINTAINER_MODE([enable])
AC_CONFIG_SRCDIR(src/google/protobuf/message.cc)
AC_CONFIG_HEADERS([config.h])
@@ -28,7 +29,7 @@ AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"],
AC_CANONICAL_TARGET
-AM_INIT_AUTOMAKE
+AM_INIT_AUTOMAKE([subdir-objects])
AC_ARG_WITH([zlib],
[AS_HELP_STRING([--with-zlib],
@@ -89,12 +90,12 @@ AS_IF([test "$with_zlib" != no], [
# First check the zlib header version.
AC_COMPILE_IFELSE(
- AC_LANG_PROGRAM([[
+ [AC_LANG_PROGRAM([[
#include <zlib.h>
#if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1204)
# error zlib version too old
#endif
- ]], []), [
+ ]], [])], [
AC_MSG_RESULT([ok (1.2.0.4 or later)])
# Also need to add -lz to the linker flags and make sure this succeeds.
@@ -118,7 +119,7 @@ AM_CONDITIONAL([HAVE_ZLIB], [test $HAVE_ZLIB = 1])
AS_IF([test "$with_protoc" != "no"], [
PROTOC=$with_protoc
- AS_IF([test "$with_protoc" == "yes"], [
+ AS_IF([test "$with_protoc" = "yes"], [
# No argument given. Use system protoc.
PROTOC=protoc
])
@@ -138,6 +139,15 @@ AM_CONDITIONAL([USE_EXTERNAL_PROTOC], [test "$with_protoc" != "no"])
ACX_PTHREAD
AC_CXX_STL_HASH
+case "$target_os" in
+ mingw* | cygwin* | win*)
+ ;;
+ *)
+ # Need to link against rt on Solaris
+ AC_SEARCH_LIBS([sched_yield], [rt], [], [AC_MSG_FAILURE([sched_yield was not found on your system])])
+ ;;
+esac
+
# HACK: Make gtest's configure script pick up our copy of CFLAGS and CXXFLAGS,
# since the flags added by ACX_CHECK_SUNCC must be used when compiling gtest
# too.
diff --git a/depcomp b/depcomp
index e5f9736..4ebd5b3 100755
--- a/depcomp
+++ b/depcomp
@@ -1,10 +1,9 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
-scriptversion=2007-03-29.01
+scriptversion=2013-05-30.07; # UTC
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software
-# Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -17,9 +16,7 @@ scriptversion=2007-03-29.01
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -30,9 +27,9 @@ scriptversion=2007-03-29.01
case $1 in
'')
- echo "$0: No command. Try \`$0 --help' for more information." 1>&2
- exit 1;
- ;;
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
@@ -42,11 +39,11 @@ as side-effects.
Environment variables:
depmode Dependency tracking mode.
- source Source file read by `PROGRAMS ARGS'.
- object Object file output by `PROGRAMS ARGS'.
+ source Source file read by 'PROGRAMS ARGS'.
+ object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
- tmpdepfile Temporary file to use when outputing dependencies.
+ tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
@@ -59,6 +56,66 @@ EOF
;;
esac
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'. Note that this directory component will
+# be either empty or ending with a '/' character. This is deliberate.
+set_dir_from ()
+{
+ case $1 in
+ */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+ *) dir=;;
+ esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+ base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+ echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+ # If the compiler actually managed to produce a dependency file,
+ # post-process it.
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form 'foo.o: dependency.h'.
+ # Do two passes, one to just change these to
+ # $object: dependency.h
+ # and one to simply output
+ # dependency.h:
+ # which is needed to avoid the deleted-header problem.
+ { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+ sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+ } > "$depfile"
+ rm -f "$tmpdepfile"
+ else
+ make_dummy_depfile
+ fi
+}
+
+# A tabulation character.
+tab=' '
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
@@ -71,6 +128,9 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
@@ -82,9 +142,32 @@ if test "$depmode" = hp; then
fi
if test "$depmode" = dashXmstdout; then
- # This is just like dashmstdout with a different argument.
- dashmflag=-xM
- depmode=dashmstdout
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
fi
case "$depmode" in
@@ -107,8 +190,7 @@ gcc3)
done
"$@"
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@@ -116,13 +198,17 @@ gcc3)
;;
gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
-## -MM, not -M (despite what the docs say).
+## -MM, not -M (despite what the docs say). Also, it might not be
+## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
@@ -130,31 +216,31 @@ gcc)
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
- alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
-## The second -e expression handles DOS-style file names with drive letters.
+ # The second -e expression handles DOS-style file names with drive
+ # letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
-## This next piece of magic avoids the `deleted header file' problem.
+## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
- tr ' ' '
-' < "$tmpdepfile" |
-## Some versions of gcc put a space before the `:'. On the theory
+## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
-## well.
+## well. hp depmode also adds that space, but also prefixes the VPATH
+## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -172,8 +258,7 @@ sgi)
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@@ -181,43 +266,41 @@ sgi)
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
-
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
- # the IRIX cc adds comments like `#:fec' to the end of the
+ # the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
- tr ' ' '
-' < "$tmpdepfile" \
- | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
- tr '
-' ' ' >> $depfile
- echo >> $depfile
-
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+ | tr "$nl" ' ' >> "$depfile"
+ echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
- tr ' ' '
-' < "$tmpdepfile" \
- | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
- >> $depfile
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
else
- # The sourcefile does not contain any dependencies, so just
- # store a dummy comment line, to avoid errors with the Makefile
- # "include basename.Plo" scheme.
- echo "#dummy" > "$depfile"
+ make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
+xlc)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
- # current directory. Also, the AIX compiler puts `$object:' at the
+ # current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ set_dir_from "$object"
+ set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
@@ -230,9 +313,7 @@ aix)
"$@" -M
fi
stat=$?
-
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
@@ -241,44 +322,100 @@ aix)
do
test -f "$tmpdepfile" && break
done
- if test -f "$tmpdepfile"; then
- # Each line is of the form `foo.o: dependent.h'.
- # Do two passes, one to just change these to
- # `$object: dependent.h' and one to simply `dependent.h:'.
- sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
- # That's a tab and a space in the [].
- sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
- else
- # The sourcefile does not contain any dependencies, so just
- # store a dummy comment line, to avoid errors with the Makefile
- # "include basename.Plo" scheme.
- echo "#dummy" > "$depfile"
+ aix_post_process_depfile
+ ;;
+
+tcc)
+ # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+ # FIXME: That version still under development at the moment of writing.
+ # Make that this statement remains true also for stable, released
+ # versions.
+ # It will wrap lines (doesn't matter whether long or short) with a
+ # trailing '\', as in:
+ #
+ # foo.o : \
+ # foo.c \
+ # foo.h \
+ #
+ # It will put a trailing '\' even on the last line, and will use leading
+ # spaces rather than leading tabs (at least since its commit 0394caf7
+ # "Emit spaces for -MD").
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
fi
+ rm -f "$depfile"
+ # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+ # We have to change lines of the first kind to '$object: \'.
+ sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+ # And for each line of the second kind, we have to emit a 'dep.h:'
+ # dummy dependency, to avoid the deleted-header problem.
+ sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
-icc)
- # Intel's C compiler understands `-MD -MF file'. However on
- # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
- # ICC 7.0 will fill foo.d with something like
- # foo.o: sub/foo.c
- # foo.o: sub/foo.h
- # which is wrong. We want:
- # sub/foo.o: sub/foo.c
- # sub/foo.o: sub/foo.h
- # sub/foo.c:
- # sub/foo.h:
- # ICC 7.1 will output
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file. A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+ # Portland's C compiler understands '-MD'.
+ # Will always output deps to 'file.d' where file is the root name of the
+ # source file under compilation, even if file resides in a subdirectory.
+ # The object file name does not affect the name of the '.d' file.
+ # pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
- # and will wrap long lines using \ :
+ # and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
+ set_dir_from "$object"
+ # Use the source, not the object, to determine the base name, since
+ # that's sadly what pgcc will do too.
+ set_base_from "$source"
+ tmpdepfile=$base.d
+
+ # For projects that build the same source file twice into different object
+ # files, the pgcc approach of using the *source* file root name can cause
+ # problems in parallel builds. Use a locking strategy to avoid stomping on
+ # the same $tmpdepfile.
+ lockdir=$base.d-lock
+ trap "
+ echo '$0: caught signal, cleaning up...' >&2
+ rmdir '$lockdir'
+ exit 1
+ " 1 2 13 15
+ numtries=100
+ i=$numtries
+ while test $i -gt 0; do
+ # mkdir is a portable test-and-set.
+ if mkdir "$lockdir" 2>/dev/null; then
+ # This process acquired the lock.
+ "$@" -MD
+ stat=$?
+ # Release the lock.
+ rmdir "$lockdir"
+ break
+ else
+ # If the lock is being held by a different process, wait
+ # until the winning process is done or we timeout.
+ while test -d "$lockdir" && test $i -gt 0; do
+ sleep 1
+ i=`expr $i - 1`
+ done
+ fi
+ i=`expr $i - 1`
+ done
+ trap - 1 2 13 15
+ if test $i -le 0; then
+ echo "$0: failed to acquire lock after $numtries attempts" >&2
+ echo "$0: check lockdir '$lockdir'" >&2
+ exit 1
+ fi
- "$@" -MD -MF "$tmpdepfile"
- stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@@ -290,8 +427,8 @@ icc)
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
- sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
- sed -e 's/$/ :/' >> "$depfile"
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -302,9 +439,8 @@ hp2)
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ set_dir_from "$object"
+ set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
@@ -315,8 +451,7 @@ hp2)
"$@" +Maked
fi
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
@@ -326,72 +461,107 @@ hp2)
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
- sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
- # Add `dependent.h:' lines.
- sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
+ sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add 'dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
else
- echo "#dummy" > "$depfile"
+ make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
- # The Tru64 compiler uses -MD to generate dependencies as a side
- # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
- # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
- # dependencies in `foo.d' instead, so we check for that too.
- # Subdirectories are respected.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
-
- if test "$libtool" = yes; then
- # With Tru64 cc, shared objects can also be used to make a
- # static library. This mechanism is used in libtool 1.4 series to
- # handle both shared and static libraries in a single compilation.
- # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
- #
- # With libtool 1.5 this exception was removed, and libtool now
- # generates 2 separate objects for the 2 libraries. These two
- # compilations output dependencies in $dir.libs/$base.o.d and
- # in $dir$base.o.d. We have to check for both files, because
- # one of the two compilations can be disabled. We should prefer
- # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
- # automatically cleaned when .libs/ is deleted, while ignoring
- # the former would cause a distcleancheck panic.
- tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
- tmpdepfile2=$dir$base.o.d # libtool 1.5
- tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
- tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
- "$@" -Wc,-MD
- else
- tmpdepfile1=$dir$base.o.d
- tmpdepfile2=$dir$base.d
- tmpdepfile3=$dir$base.d
- tmpdepfile4=$dir$base.d
- "$@" -MD
- fi
-
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
- exit $stat
- fi
-
- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
- do
- test -f "$tmpdepfile" && break
- done
- if test -f "$tmpdepfile"; then
- sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
- # That's a tab and a space in the [].
- sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
- else
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile"
- ;;
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in 'foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ set_dir_from "$object"
+ set_base_from "$object"
+
+ if test "$libtool" = yes; then
+ # Libtool generates 2 separate objects for the 2 libraries. These
+ # two compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir$base.o.d # libtool 1.5
+ tmpdepfile2=$dir.libs/$base.o.d # Likewise.
+ tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ # Same post-processing that is required for AIX mode.
+ aix_post_process_depfile
+ ;;
+
+msvc7)
+ if test "$libtool" = yes; then
+ showIncludes=-Wc,-showIncludes
+ else
+ showIncludes=-showIncludes
+ fi
+ "$@" $showIncludes > "$tmpdepfile"
+ stat=$?
+ grep -v '^Note: including file: ' "$tmpdepfile"
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The first sed program below extracts the file names and escapes
+ # backslashes for cygpath. The second sed program outputs the file
+ # name when reading, but also accumulates all include files in the
+ # hold buffer in order to output them again at the end. This only
+ # works with sed implementations that can handle large buffers.
+ sed < "$tmpdepfile" -n '
+/^Note: including file: *\(.*\)/ {
+ s//\1/
+ s/\\/\\\\/g
+ p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+ s/.*/'"$tab"'/
+ G
+ p
+}' >> "$depfile"
+ echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7msys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
@@ -404,13 +574,13 @@ dashmstdout)
# Remove the call to Libtool.
if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
+ while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
- # Remove `-o $object'.
+ # Remove '-o $object'.
IFS=" "
for arg
do
@@ -430,18 +600,18 @@ dashmstdout)
done
test -z "$dashmflag" && dashmflag=-M
- # Require at least two characters before searching for `:'
+ # Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
- # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
- sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
- tr ' ' '
-' < "$tmpdepfile" | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this sed invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -455,41 +625,51 @@ makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
+ while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
- cleared=no
- for arg in "$@"; do
+ cleared=no eat=no
+ for arg
+ do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
- obj_suffix="`echo $object | sed 's/^.*\././'`"
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
- cat < "$tmpdepfile" > "$depfile"
- sed '1,2d' "$tmpdepfile" | tr ' ' '
-' | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ # makedepend may prepend the VPATH from the source file name to the object.
+ # No need to regex-escape $object, excess matching of '.' is harmless.
+ sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process the last invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed '1,2d' "$tmpdepfile" \
+ | tr ' ' "$nl" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
@@ -500,13 +680,13 @@ cpp)
# Remove the call to Libtool.
if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
+ while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
- # Remove `-o $object'.
+ # Remove '-o $object'.
IFS=" "
for arg
do
@@ -525,10 +705,10 @@ cpp)
esac
done
- "$@" -E |
- sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
- -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
- sed '$ s: \\$::' > "$tmpdepfile"
+ "$@" -E \
+ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ | sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
@@ -538,35 +718,56 @@ cpp)
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
- # always write the preprocessed file to stdout, regardless of -o,
- # because we must use -o when running libtool.
+ # always write the preprocessed file to stdout.
"$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
IFS=" "
for arg
do
case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
- set fnord "$@"
- shift
- shift
- ;;
+ set fnord "$@"
+ shift
+ shift
+ ;;
*)
- set fnord "$@" "$arg"
- shift
- shift
- ;;
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
esac
done
- "$@" -E |
- sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
- . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
- echo " " >> "$depfile"
- . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+ echo "$tab" >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
none)
exec "$@"
;;
@@ -585,5 +786,6 @@ exit 0
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
# End:
diff --git a/editors/proto.vim b/editors/proto.vim
index 42f3307..7cd1dbf 100644
--- a/editors/proto.vim
+++ b/editors/proto.vim
@@ -1,6 +1,6 @@
" Protocol Buffers - Google's data interchange format
" Copyright 2008 Google Inc. All rights reserved.
-" http://code.google.com/p/protobuf/
+" 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
@@ -69,11 +69,10 @@ syn keyword pbBool true false
syn match pbInt /-\?\<\d\+\>/
syn match pbInt /\<0[xX]\x+\>/
syn match pbFloat /\<-\?\d*\(\.\d*\)\?/
-" TODO: .proto also supports C-style block comments;
-" see /usr/share/vim/vim70/syntax/c.vim for how it's done.
+syn region pbComment start="\/\*" end="\*\/" contains=@pbCommentGrp
syn region pbComment start="//" skip="\\$" end="$" keepend contains=@pbCommentGrp
-syn region pbString start=/"/ skip=/\\"/ end=/"/
-syn region pbString start=/'/ skip=/\\'/ end=/'/
+syn region pbString start=/"/ skip=/\\./ end=/"/
+syn region pbString start=/'/ skip=/\\./ end=/'/
if version >= 508 || !exists("did_proto_syn_inits")
if version < 508
diff --git a/examples/AddPerson.java b/examples/AddPerson.java
index 4917684..ca5ac27 100644
--- a/examples/AddPerson.java
+++ b/examples/AddPerson.java
@@ -70,8 +70,11 @@ class AddPerson {
// Read the existing address book.
try {
FileInputStream input = new FileInputStream(args[0]);
- addressBook.mergeFrom(input);
- input.close();
+ try {
+ addressBook.mergeFrom(input);
+ } finally {
+ try { input.close(); } catch (Throwable ignore) {}
+ }
} catch (FileNotFoundException e) {
System.out.println(args[0] + ": File not found. Creating a new file.");
}
@@ -83,7 +86,10 @@ class AddPerson {
// Write the new address book back to disk.
FileOutputStream output = new FileOutputStream(args[0]);
- addressBook.build().writeTo(output);
- output.close();
+ try {
+ addressBook.build().writeTo(output);
+ } finally {
+ output.close();
+ }
}
}
diff --git a/examples/README.txt b/examples/README.txt
index d22bf06..f5530a5 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -22,7 +22,7 @@ All of these programs simply take an address book file as their parameter.
The add_person programs will create the file if it doesn't already exist.
These examples are part of the Protocol Buffers tutorial, located at:
- http://code.google.com/apis/protocolbuffers/docs/tutorials.html
+ https://developers.google.com/protocol-buffers/docs/tutorials
* Note that on some platforms you may have to edit the Makefile and remove
"-lpthread" from the linker commands (perhaps replacing it with something else).
diff --git a/gtest/CHANGES b/gtest/CHANGES
index 1858f7f..e574415 100644
--- a/gtest/CHANGES
+++ b/gtest/CHANGES
@@ -1,3 +1,25 @@
+Changes for 1.5.0:
+
+ * New feature: assertions can be safely called in multiple threads
+ where the pthreads library is available.
+ * New feature: predicates used inside EXPECT_TRUE() and friends
+ can now generate custom failure messages.
+ * New feature: Google Test can now be compiled as a DLL.
+ * New feature: fused source files are included.
+ * New feature: prints help when encountering unrecognized Google Test flags.
+ * Experimental feature: CMake build script (requires CMake 2.6.4+).
+ * Experimental feature: the Pump script for meta programming.
+ * double values streamed to an assertion are printed with enough precision
+ to differentiate any two different values.
+ * Google Test now works on Solaris and AIX.
+ * Build and test script improvements.
+ * Bug fixes and implementation clean-ups.
+
+ Potentially breaking changes:
+
+ * Stopped supporting VC++ 7.1 with exceptions disabled.
+ * Dropped support for 'make install'.
+
Changes for 1.4.0:
* New feature: the event listener API
diff --git a/gtest/CMakeLists.txt b/gtest/CMakeLists.txt
new file mode 100644
index 0000000..7910b5d
--- /dev/null
+++ b/gtest/CMakeLists.txt
@@ -0,0 +1,384 @@
+########################################################################
+# Experimental CMake build script for Google Test.
+#
+# Consider this a prototype. It will change drastically. For now,
+# this is only for people on the cutting edge.
+#
+# To run the tests for Google Test itself on Linux, use 'make test' or
+# ctest. You can select which tests to run using 'ctest -R regex'.
+# For more options, run 'ctest --help'.
+
+# For hermetic builds, we may need to tell CMake to use compiler in a
+# specific location.
+if (gtest_compiler)
+ include(CMakeForceCompiler)
+ cmake_force_c_compiler("${gtest_compiler}" "")
+ cmake_force_cxx_compiler("${gtest_compiler}" "")
+endif()
+
+########################################################################
+#
+# Project-wide settings
+
+# Name of the project.
+#
+# CMake files in this project can refer to the root source directory
+# as ${gtest_SOURCE_DIR} and to the root binary directory as
+# ${gtest_BINARY_DIR}.
+# Language "C" is required for find_package(Threads).
+project(gtest CXX C)
+cmake_minimum_required(VERSION 2.6.4)
+
+if (MSVC)
+ # For MSVC, CMake sets certain flags to defaults we want to override.
+ # This replacement code is taken from sample in the CMake Wiki at
+ # http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace.
+ foreach (flag_var
+ CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
+ CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
+ # In hermetic build environments, tests may not have access to MS runtime
+ # DLLs, so this replaces /MD (CRT libraries in DLLs) with /MT (static CRT
+ # libraries).
+ string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}")
+ # We prefer more strict warning checking for building Google Test.
+ # Replaces /W3 with /W4 in defaults.
+ string(REPLACE "/W3" "-W4" ${flag_var} "${${flag_var}}")
+ endforeach()
+endif()
+
+# Where gtest's .h files can be found.
+include_directories(
+ ${gtest_SOURCE_DIR}/include
+ ${gtest_SOURCE_DIR})
+
+# Where the gtest libraries can be found.
+link_directories(
+ ${gtest_BINARY_DIR}/src)
+
+# Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT.
+find_package(Threads)
+
+# Defines the compiler/linker flags used to build gtest. You can
+# tweak these definitions to suit your need. A variable's value is
+# empty before it's explicitly assigned to.
+
+if (MSVC)
+ # Newlines inside flags variables break CMake's NMake generator.
+ set(cxx_base_flags "-GS -W4 -WX -wd4275 -nologo -J -Zi")
+ set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32")
+ set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN")
+ set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1")
+ set(cxx_no_exception_flags "-D_HAS_EXCEPTIONS=0")
+ set(cxx_no_rtti_flags "-GR-")
+elseif (CMAKE_COMPILER_IS_GNUCXX)
+ set(cxx_base_flags "-Wall -Wshadow")
+ set(cxx_exception_flags "-fexceptions")
+ set(cxx_no_exception_flags "-fno-exceptions")
+ # Until version 4.3.2, GCC doesn't define a macro to indicate
+ # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
+ # explicitly.
+ set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
+ set(cxx_strict_flags "-Wextra")
+elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
+ set(cxx_exception_flags "-features=except")
+ # Sun Pro doesn't provide macros to indicate whether exceptions and
+ # RTTI are enabled, so we define GTEST_HAS_* explicitly.
+ set(cxx_no_exception_flags "-features=no%except -DGTEST_HAS_EXCEPTIONS=0")
+ set(cxx_no_rtti_flags "-features=no%rtti -DGTEST_HAS_RTTI=0")
+elseif (CMAKE_CXX_COMPILER_ID STREQUAL "VisualAge" OR
+ CMAKE_CXX_COMPILER_ID STREQUAL "XL")
+ # CMake 2.8 changes Visual Age's compiler ID to "XL".
+ set(cxx_exception_flags "-qeh")
+ set(cxx_no_exception_flags "-qnoeh")
+ # Until version 9.0, Visual Age doesn't define a macro to indicate
+ # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
+ # explicitly.
+ set(cxx_no_rtti_flags "-qnortti -DGTEST_HAS_RTTI=0")
+endif()
+
+if (CMAKE_USE_PTHREADS_INIT) # The pthreads library is available.
+ set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=1")
+endif()
+
+# For building gtest's own tests and samples.
+set(cxx_exception "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_exception_flags}")
+set(cxx_no_exception
+ "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}")
+set(cxx_default "${cxx_exception}")
+set(cxx_no_rtti "${cxx_default} ${cxx_no_rtti_flags}")
+set(cxx_use_own_tuple "${cxx_default} -DGTEST_USE_OWN_TR1_TUPLE=1")
+
+# For building the gtest libraries.
+set(cxx_strict "${cxx_default} ${cxx_strict_flags}")
+
+########################################################################
+#
+# Defines the gtest & gtest_main libraries. User tests should link
+# with one of them.
+function(cxx_library_with_type name type cxx_flags)
+ # type can be either STATIC or SHARED to denote a static or shared library.
+ # ARGN refers to additional arguments after 'cxx_flags'.
+ add_library(${name} ${type} ${ARGN})
+ set_target_properties(${name}
+ PROPERTIES
+ COMPILE_FLAGS "${cxx_flags}")
+ if (CMAKE_USE_PTHREADS_INIT)
+ target_link_libraries(${name} ${CMAKE_THREAD_LIBS_INIT})
+ endif()
+endfunction()
+
+function(cxx_static_library name cxx_flags)
+ cxx_library_with_type(${name} STATIC "${cxx_flags}" ${ARGN})
+endfunction()
+
+function(cxx_shared_library name cxx_flags)
+ cxx_library_with_type(${name} SHARED "${cxx_flags}" ${ARGN})
+endfunction()
+
+function(cxx_library name cxx_flags)
+ # TODO(vladl@google.com): Make static/shared a user option.
+ cxx_static_library(${name} "${cxx_flags}" ${ARGN})
+endfunction()
+
+# Static versions of Google Test libraries. We build them using more
+# strict warnings than what are used for other targets, to ensure that
+# gtest can be compiled by a user aggressive about warnings.
+cxx_static_library(gtest "${cxx_strict}" src/gtest-all.cc)
+cxx_static_library(gtest_main "${cxx_strict}" src/gtest_main.cc)
+target_link_libraries(gtest_main gtest)
+
+########################################################################
+#
+# Samples on how to link user tests with gtest or gtest_main.
+#
+# They are not built by default. To build them, set the
+# build_gtest_samples option to ON. You can do it by running ccmake
+# or specifying the -Dbuild_gtest_samples=ON flag when running cmake.
+
+option(build_gtest_samples "Build gtest's sample programs." OFF)
+
+# cxx_executable_with_flags(name cxx_flags lib srcs...)
+#
+# creates a named C++ executable that depends on the given library and
+# is built from the given source files with the given compiler flags.
+function(cxx_executable_with_flags name cxx_flags lib)
+ add_executable(${name} ${ARGN})
+ if (cxx_flags)
+ set_target_properties(${name}
+ PROPERTIES
+ COMPILE_FLAGS "${cxx_flags}")
+ endif()
+ target_link_libraries(${name} ${lib})
+endfunction()
+
+# cxx_executable(name dir lib srcs...)
+#
+# creates a named target that depends on the given lib and is built
+# from the given source files. dir/name.cc is implicitly included in
+# the source file list.
+function(cxx_executable name dir lib)
+ cxx_executable_with_flags(
+ ${name} "${cxx_default}" ${lib} "${dir}/${name}.cc" ${ARGN})
+endfunction()
+
+if (build_gtest_samples)
+ cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc)
+ cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc)
+ cxx_executable(sample3_unittest samples gtest_main)
+ cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc)
+ cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc)
+ cxx_executable(sample6_unittest samples gtest_main)
+ cxx_executable(sample7_unittest samples gtest_main)
+ cxx_executable(sample8_unittest samples gtest_main)
+ cxx_executable(sample9_unittest samples gtest)
+ cxx_executable(sample10_unittest samples gtest)
+endif()
+
+########################################################################
+#
+# Google Test's own tests.
+#
+# You can skip this section if you aren't interested in testing
+# Google Test itself.
+#
+# Most of the tests are not built by default. To build them, set the
+# build_all_gtest_tests option to ON. You can do it by running ccmake
+# or specifying the -Dbuild_all_gtest_tests=ON flag when running cmake.
+
+option(build_all_gtest_tests "Build all of gtest's own tests." OFF)
+
+# This must be set in the root directory for the tests to be run by
+# 'make test' or ctest.
+enable_testing()
+
+# Sets PYTHONINTERP_FOUND and PYTHON_EXECUTABLE.
+find_package(PythonInterp)
+
+############################################################
+# C++ tests built with standard compiler flags.
+
+# cxx_test_with_flags(name cxx_flags libs srcs...)
+#
+# creates a named C++ test that depends on the given libs and is built
+# from the given source files with the given compiler flags.
+function(cxx_test_with_flags name cxx_flags libs)
+ add_executable(${name} ${ARGN})
+ set_target_properties(${name}
+ PROPERTIES
+ COMPILE_FLAGS "${cxx_flags}")
+ # To support mixing linking in static and dynamic libraries, link each
+ # library in with an extra call to target_link_libraries.
+ foreach (lib "${libs}")
+ target_link_libraries(${name} ${lib})
+ endforeach()
+ add_test(${name} ${name})
+endfunction()
+
+# cxx_test(name libs srcs...)
+#
+# creates a named test target that depends on the given libs and is
+# built from the given source files. Unlike cxx_test_with_flags,
+# test/name.cc is already implicitly included in the source file list.
+function(cxx_test name libs)
+ cxx_test_with_flags("${name}" "${cxx_default}" "${libs}"
+ "test/${name}.cc" ${ARGN})
+endfunction()
+
+cxx_test(gtest_unittest gtest_main)
+
+if (build_all_gtest_tests)
+ cxx_test(gtest-death-test_test gtest_main)
+ cxx_test(gtest_environment_test gtest)
+ cxx_test(gtest-filepath_test gtest_main)
+ cxx_test(gtest-linked_ptr_test gtest_main)
+ cxx_test(gtest-listener_test gtest_main)
+ cxx_test(gtest_main_unittest gtest_main)
+ cxx_test(gtest-message_test gtest_main)
+ cxx_test(gtest_no_test_unittest gtest)
+ cxx_test(gtest-options_test gtest_main)
+ cxx_test(gtest-param-test_test gtest
+ test/gtest-param-test2_test.cc)
+ cxx_test(gtest-port_test gtest_main)
+ cxx_test(gtest_pred_impl_unittest gtest_main)
+ cxx_test(gtest_prod_test gtest_main
+ test/production.cc)
+ cxx_test(gtest_repeat_test gtest)
+ cxx_test(gtest_sole_header_test gtest_main)
+ cxx_test(gtest_stress_test gtest)
+ cxx_test(gtest-test-part_test gtest_main)
+ cxx_test(gtest_throw_on_failure_ex_test gtest)
+ cxx_test(gtest-typed-test_test gtest_main
+ test/gtest-typed-test2_test.cc)
+ cxx_test(gtest-unittest-api_test gtest)
+endif()
+
+############################################################
+# C++ tests built with non-standard compiler flags.
+
+if (build_all_gtest_tests)
+ cxx_library(gtest_no_exception "${cxx_no_exception}"
+ src/gtest-all.cc)
+ cxx_library(gtest_main_no_rtti "${cxx_no_rtti}"
+ src/gtest-all.cc src/gtest_main.cc)
+
+ cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}"
+ gtest_main_no_rtti test/gtest_unittest.cc)
+
+ set(cxx_use_shared_gtest "${cxx_default} -DGTEST_LINKED_AS_SHARED_LIBRARY=1")
+ set(cxx_build_shared_gtest "${cxx_default} -DGTEST_CREATE_SHARED_LIBRARY=1")
+ if (MSVC)
+ # Disables the "class 'X' needs to have dll-interface to be used
+ # by clients of class 'Y'" warning. This particularly concerns generic
+ # classes like vector that MS doesn't mark as exported.
+ set(cxx_use_shared_gtest "${cxx_use_shared_gtest} -wd4251")
+ set(cxx_build_shared_gtest "${cxx_build_shared_gtest} -wd4251")
+ endif()
+
+ cxx_shared_library(gtest_dll "${cxx_build_shared_gtest}"
+ src/gtest-all.cc)
+
+ # TODO(vladl): This and the next tests may not run in the hermetic
+ # environment on Windows. Re-evaluate and possibly make them
+ # platform-conditional after implementing hermetic builds.
+ cxx_executable_with_flags(gtest_dll_test_ "${cxx_use_shared_gtest}"
+ gtest_dll test/gtest_all_test.cc)
+
+ if (NOT(MSVC AND (MSVC_VERSION EQUAL 1600)))
+ # The C++ Standard specifies tuple_element<int, class>.
+ # Yet MSVC 10's <utility> declares tuple_element<size_t, class>.
+ # That declaration conflicts with our own standard-conforming
+ # tuple implementation. Therefore using our own tuple with
+ # MSVC 10 doesn't compile.
+ cxx_library(gtest_main_use_own_tuple "${cxx_use_own_tuple}"
+ src/gtest-all.cc src/gtest_main.cc)
+
+ cxx_test_with_flags(gtest-tuple_test "${cxx_use_own_tuple}"
+ gtest_main_use_own_tuple test/gtest-tuple_test.cc)
+
+ cxx_test_with_flags(gtest_use_own_tuple_test "${cxx_use_own_tuple}"
+ gtest_main_use_own_tuple
+ test/gtest-param-test_test.cc test/gtest-param-test2_test.cc)
+ endif()
+
+endif()
+
+############################################################
+# Python tests.
+
+# py_test(name)
+#
+# creates a Python test with the given name whose main module is in
+# test/name.py. It does nothing if Python is not installed.
+function(py_test name)
+ if (PYTHONINTERP_FOUND)
+ # ${gtest_BINARY_DIR} is known at configuration time, so we can
+ # directly bind it from cmake. ${CTEST_CONFIGURATION_TYPE} is known
+ # only at ctest runtime (by calling ctest -c <Configuration>), so
+ # we have to escape $ to delay variable substitution here.
+ add_test(${name}
+ ${PYTHON_EXECUTABLE} ${gtest_SOURCE_DIR}/test/${name}.py
+ --gtest_build_dir=${gtest_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE})
+ endif()
+endfunction()
+
+if (build_all_gtest_tests)
+ cxx_executable(gtest_break_on_failure_unittest_ test gtest)
+ py_test(gtest_break_on_failure_unittest)
+
+ cxx_executable(gtest_color_test_ test gtest)
+ py_test(gtest_color_test)
+
+ cxx_executable(gtest_env_var_test_ test gtest)
+ py_test(gtest_env_var_test)
+
+ cxx_executable(gtest_filter_unittest_ test gtest)
+ py_test(gtest_filter_unittest)
+
+ cxx_executable(gtest_help_test_ test gtest_main)
+ py_test(gtest_help_test)
+
+ cxx_executable(gtest_list_tests_unittest_ test gtest)
+ py_test(gtest_list_tests_unittest)
+
+ cxx_executable(gtest_output_test_ test gtest)
+ py_test(gtest_output_test)
+
+ cxx_executable(gtest_shuffle_test_ test gtest)
+ py_test(gtest_shuffle_test)
+
+ cxx_executable(gtest_throw_on_failure_test_ test gtest_no_exception)
+ set_target_properties(gtest_throw_on_failure_test_
+ PROPERTIES
+ COMPILE_FLAGS "${cxx_no_exception}")
+ py_test(gtest_throw_on_failure_test)
+
+ cxx_executable(gtest_uninitialized_test_ test gtest)
+ py_test(gtest_uninitialized_test)
+
+ cxx_executable(gtest_xml_outfile1_test_ test gtest_main)
+ cxx_executable(gtest_xml_outfile2_test_ test gtest_main)
+ py_test(gtest_xml_outfiles_test)
+
+ cxx_executable(gtest_xml_output_unittest_ test gtest)
+ py_test(gtest_xml_output_unittest)
+endif()
diff --git a/gtest/CONTRIBUTORS b/gtest/CONTRIBUTORS
index 40ce6c8..0934ae1 100644
--- a/gtest/CONTRIBUTORS
+++ b/gtest/CONTRIBUTORS
@@ -11,13 +11,16 @@ Chris Prince <cprince@google.com>
Chris Taylor <taylorc@google.com>
Dan Egnor <egnor@google.com>
Eric Roman <eroman@chromium.org>
+Hady Zalek <hady.zalek@gmail.com>
Jeffrey Yasskin <jyasskin@google.com>
Jói Sigurðsson <joi@google.com>
Keir Mierle <mierle@gmail.com>
Keith Ray <keith.ray@gmail.com>
Kenton Varda <kenton@google.com>
+Manuel Klimek <klimek@google.com>
Markus Heule <markus.heule@gmail.com>
Mika Raento <mikie@iki.fi>
+Miklós Fazekas <mfazekas@szemafor.com>
Patrick Hanna <phanna@google.com>
Patrick Riley <pfr@google.com>
Peter Kaminski <piotrk@google.com>
diff --git a/gtest/Makefile.am b/gtest/Makefile.am
index 3a9233d..8d75e32 100644
--- a/gtest/Makefile.am
+++ b/gtest/Makefile.am
@@ -1,7 +1,5 @@
# Automake file
-# TODO(chandlerc@google.com): automate the generation of *.h from *.h.pump.
-
# Nonstandard package files for distribution
EXTRA_DIST = \
CHANGES \
@@ -11,13 +9,107 @@ EXTRA_DIST = \
include/gtest/internal/gtest-type-util.h.pump \
include/gtest/internal/gtest-param-util-generated.h.pump \
make/Makefile \
- scons/SConscript \
- scons/SConstruct \
- scons/SConstruct.common \
scripts/fuse_gtest_files.py \
scripts/gen_gtest_pred_impl.py \
- scripts/test/Makefile \
- test/gtest_all_test.cc
+ scripts/pump.py \
+ scripts/test/Makefile
+
+# gtest source files that we don't compile directly. They are
+# #included by gtest-all.cc.
+GTEST_SRC = \
+ src/gtest.cc \
+ src/gtest-death-test.cc \
+ src/gtest-filepath.cc \
+ src/gtest-internal-inl.h \
+ src/gtest-port.cc \
+ src/gtest-test-part.cc \
+ src/gtest-typed-test.cc
+
+EXTRA_DIST += $(GTEST_SRC)
+
+# Sample files that we don't compile.
+EXTRA_DIST += \
+ samples/prime_tables.h \
+ samples/sample2_unittest.cc \
+ samples/sample3_unittest.cc \
+ samples/sample4_unittest.cc \
+ samples/sample5_unittest.cc \
+ samples/sample6_unittest.cc \
+ samples/sample7_unittest.cc \
+ samples/sample8_unittest.cc \
+ samples/sample9_unittest.cc
+
+# C++ test files that we don't compile directly.
+EXTRA_DIST += \
+ test/gtest-death-test_test.cc \
+ test/gtest_environment_test.cc \
+ test/gtest-filepath_test.cc \
+ test/gtest-linked_ptr_test.cc \
+ test/gtest-message_test.cc \
+ test/gtest_no_test_unittest.cc \
+ test/gtest-options_test.cc \
+ test/gtest-param-test_test.cc \
+ test/gtest-param-test2_test.cc \
+ test/gtest-param-test_test.h \
+ test/gtest-port_test.cc \
+ test/gtest_pred_impl_unittest.cc \
+ test/gtest_prod_test.cc \
+ test/production.cc \
+ test/production.h \
+ test/gtest_repeat_test.cc \
+ test/gtest_sole_header_test.cc \
+ test/gtest_stress_test.cc \
+ test/gtest-test-part_test.cc \
+ test/gtest_throw_on_failure_ex_test.cc \
+ test/gtest-typed-test_test.cc \
+ test/gtest-typed-test2_test.cc \
+ test/gtest-typed-test_test.h \
+ test/gtest_unittest.cc \
+ test/gtest-unittest-api_test.cc \
+ test/gtest-listener_test.cc \
+ test/gtest_main_unittest.cc \
+ test/gtest_unittest.cc \
+ test/gtest-tuple_test.cc \
+ test/gtest-param-test_test.cc \
+ test/gtest-param-test2_test.cc \
+ test/gtest_break_on_failure_unittest_.cc \
+ test/gtest_color_test_.cc \
+ test/gtest_env_var_test_.cc \
+ test/gtest_filter_unittest_.cc \
+ test/gtest_help_test_.cc \
+ test/gtest_list_tests_unittest_.cc \
+ test/gtest_output_test_.cc \
+ test/gtest_shuffle_test_.cc \
+ test/gtest_throw_on_failure_test_.cc \
+ test/gtest_uninitialized_test_.cc \
+ test/gtest_xml_outfile1_test_.cc \
+ test/gtest_xml_outfile2_test_.cc \
+ test/gtest_xml_output_unittest_.cc
+
+# Python tests that we don't run.
+EXTRA_DIST += \
+ test/gtest_test_utils.py \
+ test/gtest_xml_test_utils.py \
+ test/gtest_break_on_failure_unittest.py \
+ test/gtest_color_test.py \
+ test/gtest_env_var_test.py \
+ test/gtest_filter_unittest.py \
+ test/gtest_help_test.py \
+ test/gtest_list_tests_unittest.py \
+ test/gtest_output_test.py \
+ test/gtest_output_test_golden_lin.txt \
+ test/gtest_output_test_golden_win.txt \
+ test/gtest_shuffle_test.py \
+ test/gtest_throw_on_failure_test.py \
+ test/gtest_uninitialized_test.py \
+ test/gtest_xml_outfiles_test.py \
+ test/gtest_xml_output_unittest.py \
+ test/run_tests_util.py \
+ test/run_tests_util_test.py
+
+# CMake script
+EXTRA_DIST += \
+ CMakeLists.txt
# MSVC project files
EXTRA_DIST += \
@@ -48,6 +140,7 @@ EXTRA_DIST += \
# xcode sample files
EXTRA_DIST += \
xcode/Samples/FrameworkSample/Info.plist \
+ xcode/Samples/FrameworkSample/runtests.sh \
xcode/Samples/FrameworkSample/widget_test.cc \
xcode/Samples/FrameworkSample/widget.cc \
xcode/Samples/FrameworkSample/widget.h \
@@ -62,11 +155,6 @@ EXTRA_DIST += \
codegear/gtest_unittest.cbproj \
codegear/gtest.groupproj
-# TODO(wan@google.com): integrate scripts/gen_gtest_pred_impl.py into
-# the build system such that a user can specify the maximum predicate
-# arity here and have the script automatically generate the
-# corresponding .h and .cc files.
-
# Scripts and utilities
bin_SCRIPTS = scripts/gtest-config
CLEANFILES = $(bin_SCRIPTS)
@@ -80,16 +168,18 @@ EXTRA_DIST += $(m4data_DATA)
# directories.
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include
+# Modifies compiler and linker flags for pthreads compatibility.
+if HAVE_PTHREADS
+ AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1
+ AM_LIBS = @PTHREAD_LIBS@
+else
+ AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0
+endif
+
# Build rules for libraries.
lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la
-lib_libgtest_la_SOURCES = src/gtest.cc \
- src/gtest-death-test.cc \
- src/gtest-filepath.cc \
- src/gtest-internal-inl.h \
- src/gtest-port.cc \
- src/gtest-test-part.cc \
- src/gtest-typed-test.cc
+lib_libgtest_la_SOURCES = src/gtest-all.cc
pkginclude_HEADERS = include/gtest/gtest.h \
include/gtest/gtest-death-test.h \
@@ -139,303 +229,56 @@ TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \
GTEST_BUILD_DIR="$(top_builddir)/test"
check_PROGRAMS=
+# A simple sample on using gtest.
TESTS += samples/sample1_unittest
check_PROGRAMS += samples/sample1_unittest
samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc
samples_sample1_unittest_LDADD = lib/libgtest_main.la \
samples/libsamples.la
-TESTS += samples/sample2_unittest
-check_PROGRAMS += samples/sample2_unittest
-samples_sample2_unittest_SOURCES = samples/sample2_unittest.cc
-samples_sample2_unittest_LDADD = lib/libgtest_main.la \
- samples/libsamples.la
-
-TESTS += samples/sample3_unittest
-check_PROGRAMS += samples/sample3_unittest
-samples_sample3_unittest_SOURCES = samples/sample3_unittest.cc
-samples_sample3_unittest_LDADD = lib/libgtest_main.la \
- samples/libsamples.la
-
-TESTS += samples/sample4_unittest
-check_PROGRAMS += samples/sample4_unittest
-samples_sample4_unittest_SOURCES = samples/sample4_unittest.cc
-samples_sample4_unittest_LDADD = lib/libgtest_main.la \
- samples/libsamples.la
-
-TESTS += samples/sample5_unittest
-check_PROGRAMS += samples/sample5_unittest
-samples_sample5_unittest_SOURCES = samples/sample5_unittest.cc
-samples_sample5_unittest_LDADD = lib/libgtest_main.la \
- samples/libsamples.la
-
-TESTS += samples/sample6_unittest
-check_PROGRAMS += samples/sample6_unittest
-samples_sample6_unittest_SOURCES = samples/prime_tables.h \
- samples/sample6_unittest.cc
-samples_sample6_unittest_LDADD = lib/libgtest_main.la
-
-TESTS += samples/sample7_unittest
-check_PROGRAMS += samples/sample7_unittest
-samples_sample7_unittest_SOURCES = samples/prime_tables.h \
- samples/sample7_unittest.cc
-samples_sample7_unittest_LDADD = lib/libgtest_main.la
-
-TESTS += samples/sample8_unittest
-check_PROGRAMS += samples/sample8_unittest
-samples_sample8_unittest_SOURCES = samples/prime_tables.h \
- samples/sample8_unittest.cc
-samples_sample8_unittest_LDADD = lib/libgtest_main.la
-
-TESTS += samples/sample9_unittest
-check_PROGRAMS += samples/sample9_unittest
-samples_sample9_unittest_SOURCES = samples/sample9_unittest.cc
-samples_sample9_unittest_LDADD = lib/libgtest.la
-
+# Another sample. It also verifies that libgtest works.
TESTS += samples/sample10_unittest
check_PROGRAMS += samples/sample10_unittest
samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc
samples_sample10_unittest_LDADD = lib/libgtest.la
-TESTS += test/gtest-death-test_test
-check_PROGRAMS += test/gtest-death-test_test
-test_gtest_death_test_test_SOURCES = test/gtest-death-test_test.cc
-test_gtest_death_test_test_CXXFLAGS = $(AM_CXXFLAGS) $(PTHREAD_CFLAGS)
-test_gtest_death_test_test_LDADD = $(PTHREAD_LIBS) $(PTHREAD_CFLAGS) \
- lib/libgtest_main.la
-
-TESTS += test/gtest_environment_test
-check_PROGRAMS += test/gtest_environment_test
-test_gtest_environment_test_SOURCES = test/gtest_environment_test.cc
-test_gtest_environment_test_LDADD = lib/libgtest.la
-
-TESTS += test/gtest-filepath_test
-check_PROGRAMS += test/gtest-filepath_test
-test_gtest_filepath_test_SOURCES = test/gtest-filepath_test.cc
-test_gtest_filepath_test_LDADD = lib/libgtest_main.la
-
-TESTS += test/gtest-linked_ptr_test
-check_PROGRAMS += test/gtest-linked_ptr_test
-test_gtest_linked_ptr_test_SOURCES = test/gtest-linked_ptr_test.cc
-test_gtest_linked_ptr_test_LDADD = lib/libgtest_main.la
-
-TESTS += test/gtest_main_unittest
-check_PROGRAMS += test/gtest_main_unittest
-test_gtest_main_unittest_SOURCES = test/gtest_main_unittest.cc
-test_gtest_main_unittest_LDADD = lib/libgtest_main.la
-
-TESTS += test/gtest-message_test
-check_PROGRAMS += test/gtest-message_test
-test_gtest_message_test_SOURCES = test/gtest-message_test.cc
-test_gtest_message_test_LDADD = lib/libgtest_main.la
-
-TESTS += test/gtest_no_test_unittest
-check_PROGRAMS += test/gtest_no_test_unittest
-test_gtest_no_test_unittest_SOURCES = test/gtest_no_test_unittest.cc
-test_gtest_no_test_unittest_LDADD = lib/libgtest.la
-
-TESTS += test/gtest-options_test
-check_PROGRAMS += test/gtest-options_test
-test_gtest_options_test_SOURCES = test/gtest-options_test.cc
-test_gtest_options_test_LDADD = lib/libgtest_main.la
-
-TESTS += test/gtest-param-test_test
-check_PROGRAMS += test/gtest-param-test_test
-test_gtest_param_test_test_SOURCES = test/gtest-param-test_test.cc \
- test/gtest-param-test2_test.cc \
- test/gtest-param-test_test.h
-test_gtest_param_test_test_LDADD = lib/libgtest.la
-
-TESTS += test/gtest-port_test
-check_PROGRAMS += test/gtest-port_test
-test_gtest_port_test_SOURCES = test/gtest-port_test.cc
-test_gtest_port_test_LDADD = lib/libgtest_main.la
-
-TESTS += test/gtest_pred_impl_unittest
-check_PROGRAMS += test/gtest_pred_impl_unittest
-test_gtest_pred_impl_unittest_SOURCES = test/gtest_pred_impl_unittest.cc
-test_gtest_pred_impl_unittest_LDADD = lib/libgtest_main.la
-
-TESTS += test/gtest_prod_test
-check_PROGRAMS += test/gtest_prod_test
-test_gtest_prod_test_SOURCES = test/gtest_prod_test.cc \
- test/production.cc \
- test/production.h
-test_gtest_prod_test_LDADD = lib/libgtest_main.la
-
-TESTS += test/gtest_repeat_test
-check_PROGRAMS += test/gtest_repeat_test
-test_gtest_repeat_test_SOURCES = test/gtest_repeat_test.cc
-test_gtest_repeat_test_LDADD = lib/libgtest.la
-
-TESTS += test/gtest_sole_header_test
-check_PROGRAMS += test/gtest_sole_header_test
-test_gtest_sole_header_test_SOURCES = test/gtest_sole_header_test.cc
-test_gtest_sole_header_test_LDADD = lib/libgtest_main.la
-
-TESTS += test/gtest_stress_test
-check_PROGRAMS += test/gtest_stress_test
-test_gtest_stress_test_SOURCES = test/gtest_stress_test.cc
-test_gtest_stress_test_LDADD = lib/libgtest.la
-
-TESTS += test/gtest-test-part_test
-check_PROGRAMS += test/gtest-test-part_test
-test_gtest_test_part_test_SOURCES = test/gtest-test-part_test.cc
-test_gtest_test_part_test_LDADD = lib/libgtest_main.la
-
-TESTS += test/gtest_throw_on_failure_ex_test
-check_PROGRAMS += test/gtest_throw_on_failure_ex_test
-test_gtest_throw_on_failure_ex_test_SOURCES = \
- test/gtest_throw_on_failure_ex_test.cc \
- src/gtest-all.cc
-test_gtest_throw_on_failure_ex_test_CXXFLAGS = $(AM_CXXFLAGS) -fexceptions
-
-TESTS += test/gtest-typed-test_test
-check_PROGRAMS += test/gtest-typed-test_test
-test_gtest_typed_test_test_SOURCES = test/gtest-typed-test_test.cc \
- test/gtest-typed-test2_test.cc \
- test/gtest-typed-test_test.h
-test_gtest_typed_test_test_LDADD = lib/libgtest_main.la
-
-TESTS += test/gtest_unittest
-check_PROGRAMS += test/gtest_unittest
-test_gtest_unittest_SOURCES = test/gtest_unittest.cc
-test_gtest_unittest_LDADD = lib/libgtest_main.la
-
-TESTS += test/gtest-unittest-api_test
-check_PROGRAMS += test/gtest-unittest-api_test
-test_gtest_unittest_api_test_SOURCES = test/gtest-unittest-api_test.cc
-test_gtest_unittest_api_test_LDADD = lib/libgtest_main.la
-
-TESTS += test/gtest-listener_test
-check_PROGRAMS += test/gtest-listener_test
-test_gtest_listener_test_SOURCES = test/gtest-listener_test.cc
-test_gtest_listener_test_LDADD = lib/libgtest_main.la
-
-# Verifies that Google Test works when RTTI is disabled.
-TESTS += test/gtest_no_rtti_test
-check_PROGRAMS += test/gtest_no_rtti_test
-test_gtest_no_rtti_test_SOURCES = test/gtest_unittest.cc \
- src/gtest-all.cc \
- src/gtest_main.cc
-test_gtest_no_rtti_test_CXXFLAGS = $(AM_CXXFLAGS) -fno-rtti -DGTEST_HAS_RTTI=0
-
-# Verifies that Google Test's own TR1 tuple implementation works.
-TESTS += test/gtest-tuple_test
-check_PROGRAMS += test/gtest-tuple_test
-test_gtest_tuple_test_SOURCES = test/gtest-tuple_test.cc \
- src/gtest-all.cc \
- src/gtest_main.cc
-test_gtest_tuple_test_CXXFLAGS = $(AM_CXXFLAGS) -DGTEST_USE_OWN_TR1_TUPLE=1
-
-# Verifies that Google Test's features that use its own TR1 tuple work.
-TESTS += test/gtest_use_own_tuple_test
-check_PROGRAMS += test/gtest_use_own_tuple_test
-test_gtest_use_own_tuple_test_SOURCES = test/gtest-param-test_test.cc \
- test/gtest-param-test2_test.cc \
- src/gtest-all.cc
-test_gtest_use_own_tuple_test_CXXFLAGS = \
- $(AM_CXXFLAGS) -DGTEST_USE_OWN_TR1_TUPLE=1
-
-# The following tests depend on the presence of a Python installation and are
-# keyed off of it. TODO(chandlerc@google.com): While we currently only attempt
-# to build and execute these tests if Autoconf has found Python v2.4 on the
-# system, we don't use the PYTHON variable it specified as the valid
-# interpreter. The problem is that TESTS_ENVIRONMENT is a global variable, and
-# thus we cannot distinguish between C++ unit tests and Python unit tests.
-if HAVE_PYTHON
-check_SCRIPTS =
-
-# These two Python modules are used by multiple Python tests below.
-check_SCRIPTS += test/gtest_test_utils.py \
- test/gtest_xml_test_utils.py
-
-check_PROGRAMS += test/gtest_break_on_failure_unittest_
-test_gtest_break_on_failure_unittest__SOURCES = \
- test/gtest_break_on_failure_unittest_.cc
-test_gtest_break_on_failure_unittest__LDADD = lib/libgtest.la
-check_SCRIPTS += test/gtest_break_on_failure_unittest.py
-TESTS += test/gtest_break_on_failure_unittest.py
-
-check_PROGRAMS += test/gtest_color_test_
-test_gtest_color_test__SOURCES = test/gtest_color_test_.cc
-test_gtest_color_test__LDADD = lib/libgtest.la
-check_SCRIPTS += test/gtest_color_test.py
-TESTS += test/gtest_color_test.py
-
-check_PROGRAMS += test/gtest_env_var_test_
-test_gtest_env_var_test__SOURCES = test/gtest_env_var_test_.cc
-test_gtest_env_var_test__LDADD = lib/libgtest.la
-check_SCRIPTS += test/gtest_env_var_test.py
-TESTS += test/gtest_env_var_test.py
-
-check_PROGRAMS += test/gtest_filter_unittest_
-test_gtest_filter_unittest__SOURCES = test/gtest_filter_unittest_.cc
-test_gtest_filter_unittest__LDADD = lib/libgtest.la
-check_SCRIPTS += test/gtest_filter_unittest.py
-TESTS += test/gtest_filter_unittest.py
-
-check_PROGRAMS += test/gtest_help_test_
-test_gtest_help_test__SOURCES = test/gtest_help_test_.cc
-test_gtest_help_test__LDADD = lib/libgtest_main.la
-check_SCRIPTS += test/gtest_help_test.py
-TESTS += test/gtest_help_test.py
-
-check_PROGRAMS += test/gtest_list_tests_unittest_
-test_gtest_list_tests_unittest__SOURCES = test/gtest_list_tests_unittest_.cc
-test_gtest_list_tests_unittest__LDADD = lib/libgtest.la
-check_SCRIPTS += test/gtest_list_tests_unittest.py
-TESTS += test/gtest_list_tests_unittest.py
-
-check_PROGRAMS += test/gtest_output_test_
-test_gtest_output_test__SOURCES = test/gtest_output_test_.cc
-test_gtest_output_test__LDADD = lib/libgtest.la
-check_SCRIPTS += test/gtest_output_test.py
-EXTRA_DIST += test/gtest_output_test_golden_lin.txt \
- test/gtest_output_test_golden_win.txt
-TESTS += test/gtest_output_test.py
-
-check_PROGRAMS += test/gtest_shuffle_test_
-test_gtest_shuffle_test__SOURCES = test/gtest_shuffle_test_.cc
-test_gtest_shuffle_test__LDADD = lib/libgtest.la
-check_SCRIPTS += test/gtest_shuffle_test.py
-TESTS += test/gtest_shuffle_test.py
-
-check_PROGRAMS += test/gtest_throw_on_failure_test_
-test_gtest_throw_on_failure_test__SOURCES = \
- test/gtest_throw_on_failure_test_.cc \
- src/gtest-all.cc
-test_gtest_throw_on_failure_test__CXXFLAGS = $(AM_CXXFLAGS) -fno-exceptions
-check_SCRIPTS += test/gtest_throw_on_failure_test.py
-TESTS += test/gtest_throw_on_failure_test.py
-
-check_PROGRAMS += test/gtest_uninitialized_test_
-test_gtest_uninitialized_test__SOURCES = test/gtest_uninitialized_test_.cc
-test_gtest_uninitialized_test__LDADD = lib/libgtest.la
-check_SCRIPTS += test/gtest_uninitialized_test.py
-TESTS += test/gtest_uninitialized_test.py
-
-check_PROGRAMS += test/gtest_xml_outfile1_test_
-test_gtest_xml_outfile1_test__SOURCES = test/gtest_xml_outfile1_test_.cc
-test_gtest_xml_outfile1_test__LDADD = lib/libgtest_main.la
-check_PROGRAMS += test/gtest_xml_outfile2_test_
-test_gtest_xml_outfile2_test__SOURCES = test/gtest_xml_outfile2_test_.cc
-test_gtest_xml_outfile2_test__LDADD = lib/libgtest_main.la
-check_SCRIPTS += test/gtest_xml_outfiles_test.py
-TESTS += test/gtest_xml_outfiles_test.py
-
-check_PROGRAMS += test/gtest_xml_output_unittest_
-test_gtest_xml_output_unittest__SOURCES = test/gtest_xml_output_unittest_.cc
-test_gtest_xml_output_unittest__LDADD = lib/libgtest.la
-check_SCRIPTS += test/gtest_xml_output_unittest.py
-TESTS += test/gtest_xml_output_unittest.py
-
-# TODO(wan@google.com): make the build script compile and run the
-# negative-compilation tests. (The test/gtest_nc* files are unfinished
-# implementation of tests for verifying that certain kinds of misuse
-# of Google Test don't compile.)
-EXTRA_DIST += $(check_SCRIPTS) \
- test/gtest_nc.cc \
- test/gtest_nc_test.py
-
-endif
+# This tests most constructs of gtest and verifies that libgtest_main
+# works.
+TESTS += test/gtest_all_test
+check_PROGRAMS += test/gtest_all_test
+test_gtest_all_test_SOURCES = test/gtest_all_test.cc
+test_gtest_all_test_LDADD = lib/libgtest_main.la
+
+# Tests that fused gtest files compile and work.
+FUSED_GTEST_SRC = \
+ fused-src/gtest/gtest-all.cc \
+ fused-src/gtest/gtest_main.cc \
+ fused-src/gtest/gtest.h
+
+TESTS += test/fused_gtest_test
+check_PROGRAMS += test/fused_gtest_test
+test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \
+ samples/sample1.cc samples/sample1_unittest.cc
+test_fused_gtest_test_CPPFLAGS = -I"$(srcdir)/fused-src"
+
+# Build rules for putting fused Google Test files into the distribution
+# package. The user can also create those files by manually running
+# scripts/fuse_gtest_files.py.
+$(test_fused_gtest_test_SOURCES): fused-gtest
+
+fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \
+ $(GTEST_SRC) src/gtest-all.cc src/gtest_main.cc \
+ scripts/fuse_gtest_files.py
+ mkdir -p "$(srcdir)/fused-src"
+ chmod -R u+w "$(srcdir)/fused-src"
+ rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc"
+ rm -f "$(srcdir)/fused-src/gtest/gtest.h"
+ "$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src"
+ cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest/"
+
+maintainer-clean-local:
+ rm -rf "$(srcdir)/fused-src"
+
+# Death tests may produce core dumps in the build directory. In case
+# this happens, clean them to keep distcleancheck happy.
+CLEANFILES += core
diff --git a/gtest/Makefile.in b/gtest/Makefile.in
index 3ef8d85..c62fd54 100644
--- a/gtest/Makefile.in
+++ b/gtest/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -17,12 +16,55 @@
# Automake file
-# TODO(chandlerc@google.com): automate the generation of *.h from *.h.pump.
-
VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -42,116 +84,27 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
TESTS = samples/sample1_unittest$(EXEEXT) \
- samples/sample2_unittest$(EXEEXT) \
- samples/sample3_unittest$(EXEEXT) \
- samples/sample4_unittest$(EXEEXT) \
- samples/sample5_unittest$(EXEEXT) \
- samples/sample6_unittest$(EXEEXT) \
- samples/sample7_unittest$(EXEEXT) \
- samples/sample8_unittest$(EXEEXT) \
- samples/sample9_unittest$(EXEEXT) \
samples/sample10_unittest$(EXEEXT) \
- test/gtest-death-test_test$(EXEEXT) \
- test/gtest_environment_test$(EXEEXT) \
- test/gtest-filepath_test$(EXEEXT) \
- test/gtest-linked_ptr_test$(EXEEXT) \
- test/gtest_main_unittest$(EXEEXT) \
- test/gtest-message_test$(EXEEXT) \
- test/gtest_no_test_unittest$(EXEEXT) \
- test/gtest-options_test$(EXEEXT) \
- test/gtest-param-test_test$(EXEEXT) \
- test/gtest-port_test$(EXEEXT) \
- test/gtest_pred_impl_unittest$(EXEEXT) \
- test/gtest_prod_test$(EXEEXT) test/gtest_repeat_test$(EXEEXT) \
- test/gtest_sole_header_test$(EXEEXT) \
- test/gtest_stress_test$(EXEEXT) \
- test/gtest-test-part_test$(EXEEXT) \
- test/gtest_throw_on_failure_ex_test$(EXEEXT) \
- test/gtest-typed-test_test$(EXEEXT) \
- test/gtest_unittest$(EXEEXT) \
- test/gtest-unittest-api_test$(EXEEXT) \
- test/gtest-listener_test$(EXEEXT) \
- test/gtest_no_rtti_test$(EXEEXT) \
- test/gtest-tuple_test$(EXEEXT) \
- test/gtest_use_own_tuple_test$(EXEEXT) $(am__append_2)
+ test/gtest_all_test$(EXEEXT) test/fused_gtest_test$(EXEEXT)
check_PROGRAMS = samples/sample1_unittest$(EXEEXT) \
- samples/sample2_unittest$(EXEEXT) \
- samples/sample3_unittest$(EXEEXT) \
- samples/sample4_unittest$(EXEEXT) \
- samples/sample5_unittest$(EXEEXT) \
- samples/sample6_unittest$(EXEEXT) \
- samples/sample7_unittest$(EXEEXT) \
- samples/sample8_unittest$(EXEEXT) \
- samples/sample9_unittest$(EXEEXT) \
samples/sample10_unittest$(EXEEXT) \
- test/gtest-death-test_test$(EXEEXT) \
- test/gtest_environment_test$(EXEEXT) \
- test/gtest-filepath_test$(EXEEXT) \
- test/gtest-linked_ptr_test$(EXEEXT) \
- test/gtest_main_unittest$(EXEEXT) \
- test/gtest-message_test$(EXEEXT) \
- test/gtest_no_test_unittest$(EXEEXT) \
- test/gtest-options_test$(EXEEXT) \
- test/gtest-param-test_test$(EXEEXT) \
- test/gtest-port_test$(EXEEXT) \
- test/gtest_pred_impl_unittest$(EXEEXT) \
- test/gtest_prod_test$(EXEEXT) test/gtest_repeat_test$(EXEEXT) \
- test/gtest_sole_header_test$(EXEEXT) \
- test/gtest_stress_test$(EXEEXT) \
- test/gtest-test-part_test$(EXEEXT) \
- test/gtest_throw_on_failure_ex_test$(EXEEXT) \
- test/gtest-typed-test_test$(EXEEXT) \
- test/gtest_unittest$(EXEEXT) \
- test/gtest-unittest-api_test$(EXEEXT) \
- test/gtest-listener_test$(EXEEXT) \
- test/gtest_no_rtti_test$(EXEEXT) \
- test/gtest-tuple_test$(EXEEXT) \
- test/gtest_use_own_tuple_test$(EXEEXT) $(am__EXEEXT_1)
-@HAVE_PYTHON_TRUE@am__append_1 = \
-@HAVE_PYTHON_TRUE@ test/gtest_break_on_failure_unittest_ \
-@HAVE_PYTHON_TRUE@ test/gtest_color_test_ \
-@HAVE_PYTHON_TRUE@ test/gtest_env_var_test_ \
-@HAVE_PYTHON_TRUE@ test/gtest_filter_unittest_ \
-@HAVE_PYTHON_TRUE@ test/gtest_help_test_ \
-@HAVE_PYTHON_TRUE@ test/gtest_list_tests_unittest_ \
-@HAVE_PYTHON_TRUE@ test/gtest_output_test_ \
-@HAVE_PYTHON_TRUE@ test/gtest_shuffle_test_ \
-@HAVE_PYTHON_TRUE@ test/gtest_throw_on_failure_test_ \
-@HAVE_PYTHON_TRUE@ test/gtest_uninitialized_test_ \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_outfile1_test_ \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_outfile2_test_ \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_output_unittest_
-@HAVE_PYTHON_TRUE@am__append_2 = \
-@HAVE_PYTHON_TRUE@ test/gtest_break_on_failure_unittest.py \
-@HAVE_PYTHON_TRUE@ test/gtest_color_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_env_var_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_filter_unittest.py \
-@HAVE_PYTHON_TRUE@ test/gtest_help_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_list_tests_unittest.py \
-@HAVE_PYTHON_TRUE@ test/gtest_output_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_shuffle_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_throw_on_failure_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_uninitialized_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_outfiles_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_output_unittest.py
-
-# TODO(wan@google.com): make the build script compile and run the
-# negative-compilation tests. (The test/gtest_nc* files are unfinished
-# implementation of tests for verifying that certain kinds of misuse
-# of Google Test don't compile.)
-@HAVE_PYTHON_TRUE@am__append_3 = \
-@HAVE_PYTHON_TRUE@ test/gtest_output_test_golden_lin.txt \
-@HAVE_PYTHON_TRUE@ test/gtest_output_test_golden_win.txt \
-@HAVE_PYTHON_TRUE@ $(check_SCRIPTS) test/gtest_nc.cc \
-@HAVE_PYTHON_TRUE@ test/gtest_nc_test.py
+ test/gtest_all_test$(EXEEXT) test/fused_gtest_test$(EXEEXT)
subdir = .
-DIST_COMMON = README $(am__configure_deps) $(pkginclude_HEADERS) \
- $(pkginclude_internal_HEADERS) $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in $(top_srcdir)/build-aux/config.h.in \
- $(top_srcdir)/configure $(top_srcdir)/scripts/gtest-config.in \
- COPYING build-aux/config.guess build-aux/config.sub \
- build-aux/depcomp build-aux/install-sh build-aux/ltmain.sh \
- build-aux/missing
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/configure $(am__configure_deps) \
+ $(top_srcdir)/build-aux/config.h.in \
+ $(top_srcdir)/scripts/gtest-config.in \
+ $(top_srcdir)/build-aux/depcomp $(pkginclude_HEADERS) \
+ $(pkginclude_internal_HEADERS) \
+ $(top_srcdir)/build-aux/test-driver COPYING README \
+ build-aux/compile build-aux/config.guess build-aux/config.sub \
+ build-aux/depcomp build-aux/install-sh build-aux/missing \
+ build-aux/ltmain.sh $(top_srcdir)/build-aux/compile \
+ $(top_srcdir)/build-aux/config.guess \
+ $(top_srcdir)/build-aux/config.sub \
+ $(top_srcdir)/build-aux/install-sh \
+ $(top_srcdir)/build-aux/ltmain.sh \
+ $(top_srcdir)/build-aux/missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \
$(top_srcdir)/configure.ac
@@ -196,10 +149,12 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
lib_libgtest_la_LIBADD =
am__dirstamp = $(am__leading_dot)dirstamp
-am_lib_libgtest_la_OBJECTS = src/gtest.lo src/gtest-death-test.lo \
- src/gtest-filepath.lo src/gtest-port.lo src/gtest-test-part.lo \
- src/gtest-typed-test.lo
+am_lib_libgtest_la_OBJECTS = src/gtest-all.lo
lib_libgtest_la_OBJECTS = $(am_lib_libgtest_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
lib_libgtest_main_la_DEPENDENCIES = lib/libgtest.la
am_lib_libgtest_main_la_OBJECTS = src/gtest_main.lo
lib_libgtest_main_la_OBJECTS = $(am_lib_libgtest_main_la_OBJECTS)
@@ -207,19 +162,6 @@ samples_libsamples_la_LIBADD =
am_samples_libsamples_la_OBJECTS = samples/sample1.lo \
samples/sample2.lo samples/sample4.lo
samples_libsamples_la_OBJECTS = $(am_samples_libsamples_la_OBJECTS)
-@HAVE_PYTHON_TRUE@am__EXEEXT_1 = test/gtest_break_on_failure_unittest_$(EXEEXT) \
-@HAVE_PYTHON_TRUE@ test/gtest_color_test_$(EXEEXT) \
-@HAVE_PYTHON_TRUE@ test/gtest_env_var_test_$(EXEEXT) \
-@HAVE_PYTHON_TRUE@ test/gtest_filter_unittest_$(EXEEXT) \
-@HAVE_PYTHON_TRUE@ test/gtest_help_test_$(EXEEXT) \
-@HAVE_PYTHON_TRUE@ test/gtest_list_tests_unittest_$(EXEEXT) \
-@HAVE_PYTHON_TRUE@ test/gtest_output_test_$(EXEEXT) \
-@HAVE_PYTHON_TRUE@ test/gtest_shuffle_test_$(EXEEXT) \
-@HAVE_PYTHON_TRUE@ test/gtest_throw_on_failure_test_$(EXEEXT) \
-@HAVE_PYTHON_TRUE@ test/gtest_uninitialized_test_$(EXEEXT) \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_outfile1_test_$(EXEEXT) \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_outfile2_test_$(EXEEXT) \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_output_unittest_$(EXEEXT)
am_samples_sample10_unittest_OBJECTS = \
samples/sample10_unittest.$(OBJEXT)
samples_sample10_unittest_OBJECTS = \
@@ -231,417 +173,287 @@ samples_sample1_unittest_OBJECTS = \
$(am_samples_sample1_unittest_OBJECTS)
samples_sample1_unittest_DEPENDENCIES = lib/libgtest_main.la \
samples/libsamples.la
-am_samples_sample2_unittest_OBJECTS = \
- samples/sample2_unittest.$(OBJEXT)
-samples_sample2_unittest_OBJECTS = \
- $(am_samples_sample2_unittest_OBJECTS)
-samples_sample2_unittest_DEPENDENCIES = lib/libgtest_main.la \
- samples/libsamples.la
-am_samples_sample3_unittest_OBJECTS = \
- samples/sample3_unittest.$(OBJEXT)
-samples_sample3_unittest_OBJECTS = \
- $(am_samples_sample3_unittest_OBJECTS)
-samples_sample3_unittest_DEPENDENCIES = lib/libgtest_main.la \
- samples/libsamples.la
-am_samples_sample4_unittest_OBJECTS = \
- samples/sample4_unittest.$(OBJEXT)
-samples_sample4_unittest_OBJECTS = \
- $(am_samples_sample4_unittest_OBJECTS)
-samples_sample4_unittest_DEPENDENCIES = lib/libgtest_main.la \
- samples/libsamples.la
-am_samples_sample5_unittest_OBJECTS = \
- samples/sample5_unittest.$(OBJEXT)
-samples_sample5_unittest_OBJECTS = \
- $(am_samples_sample5_unittest_OBJECTS)
-samples_sample5_unittest_DEPENDENCIES = lib/libgtest_main.la \
- samples/libsamples.la
-am_samples_sample6_unittest_OBJECTS = \
- samples/sample6_unittest.$(OBJEXT)
-samples_sample6_unittest_OBJECTS = \
- $(am_samples_sample6_unittest_OBJECTS)
-samples_sample6_unittest_DEPENDENCIES = lib/libgtest_main.la
-am_samples_sample7_unittest_OBJECTS = \
- samples/sample7_unittest.$(OBJEXT)
-samples_sample7_unittest_OBJECTS = \
- $(am_samples_sample7_unittest_OBJECTS)
-samples_sample7_unittest_DEPENDENCIES = lib/libgtest_main.la
-am_samples_sample8_unittest_OBJECTS = \
- samples/sample8_unittest.$(OBJEXT)
-samples_sample8_unittest_OBJECTS = \
- $(am_samples_sample8_unittest_OBJECTS)
-samples_sample8_unittest_DEPENDENCIES = lib/libgtest_main.la
-am_samples_sample9_unittest_OBJECTS = \
- samples/sample9_unittest.$(OBJEXT)
-samples_sample9_unittest_OBJECTS = \
- $(am_samples_sample9_unittest_OBJECTS)
-samples_sample9_unittest_DEPENDENCIES = lib/libgtest.la
-am_test_gtest_death_test_test_OBJECTS = test/test_gtest_death_test_test-gtest-death-test_test.$(OBJEXT)
-test_gtest_death_test_test_OBJECTS = \
- $(am_test_gtest_death_test_test_OBJECTS)
-am__DEPENDENCIES_1 =
-test_gtest_death_test_test_DEPENDENCIES = $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1) lib/libgtest_main.la
-test_gtest_death_test_test_LINK = $(LIBTOOL) --tag=CXX \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
- $(test_gtest_death_test_test_CXXFLAGS) $(CXXFLAGS) \
- $(AM_LDFLAGS) $(LDFLAGS) -o $@
-am_test_gtest_filepath_test_OBJECTS = \
- test/gtest-filepath_test.$(OBJEXT)
-test_gtest_filepath_test_OBJECTS = \
- $(am_test_gtest_filepath_test_OBJECTS)
-test_gtest_filepath_test_DEPENDENCIES = lib/libgtest_main.la
-am_test_gtest_linked_ptr_test_OBJECTS = \
- test/gtest-linked_ptr_test.$(OBJEXT)
-test_gtest_linked_ptr_test_OBJECTS = \
- $(am_test_gtest_linked_ptr_test_OBJECTS)
-test_gtest_linked_ptr_test_DEPENDENCIES = lib/libgtest_main.la
-am_test_gtest_listener_test_OBJECTS = \
- test/gtest-listener_test.$(OBJEXT)
-test_gtest_listener_test_OBJECTS = \
- $(am_test_gtest_listener_test_OBJECTS)
-test_gtest_listener_test_DEPENDENCIES = lib/libgtest_main.la
-am_test_gtest_message_test_OBJECTS = \
- test/gtest-message_test.$(OBJEXT)
-test_gtest_message_test_OBJECTS = \
- $(am_test_gtest_message_test_OBJECTS)
-test_gtest_message_test_DEPENDENCIES = lib/libgtest_main.la
-am_test_gtest_options_test_OBJECTS = \
- test/gtest-options_test.$(OBJEXT)
-test_gtest_options_test_OBJECTS = \
- $(am_test_gtest_options_test_OBJECTS)
-test_gtest_options_test_DEPENDENCIES = lib/libgtest_main.la
-am_test_gtest_param_test_test_OBJECTS = \
- test/gtest-param-test_test.$(OBJEXT) \
- test/gtest-param-test2_test.$(OBJEXT)
-test_gtest_param_test_test_OBJECTS = \
- $(am_test_gtest_param_test_test_OBJECTS)
-test_gtest_param_test_test_DEPENDENCIES = lib/libgtest.la
-am_test_gtest_port_test_OBJECTS = test/gtest-port_test.$(OBJEXT)
-test_gtest_port_test_OBJECTS = $(am_test_gtest_port_test_OBJECTS)
-test_gtest_port_test_DEPENDENCIES = lib/libgtest_main.la
-am_test_gtest_test_part_test_OBJECTS = \
- test/gtest-test-part_test.$(OBJEXT)
-test_gtest_test_part_test_OBJECTS = \
- $(am_test_gtest_test_part_test_OBJECTS)
-test_gtest_test_part_test_DEPENDENCIES = lib/libgtest_main.la
-am_test_gtest_tuple_test_OBJECTS = \
- test/test_gtest_tuple_test-gtest-tuple_test.$(OBJEXT) \
- src/test_gtest_tuple_test-gtest-all.$(OBJEXT) \
- src/test_gtest_tuple_test-gtest_main.$(OBJEXT)
-test_gtest_tuple_test_OBJECTS = $(am_test_gtest_tuple_test_OBJECTS)
-test_gtest_tuple_test_LDADD = $(LDADD)
-test_gtest_tuple_test_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
- $(test_gtest_tuple_test_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
-am_test_gtest_typed_test_test_OBJECTS = \
- test/gtest-typed-test_test.$(OBJEXT) \
- test/gtest-typed-test2_test.$(OBJEXT)
-test_gtest_typed_test_test_OBJECTS = \
- $(am_test_gtest_typed_test_test_OBJECTS)
-test_gtest_typed_test_test_DEPENDENCIES = lib/libgtest_main.la
-am_test_gtest_unittest_api_test_OBJECTS = \
- test/gtest-unittest-api_test.$(OBJEXT)
-test_gtest_unittest_api_test_OBJECTS = \
- $(am_test_gtest_unittest_api_test_OBJECTS)
-test_gtest_unittest_api_test_DEPENDENCIES = lib/libgtest_main.la
-am__test_gtest_break_on_failure_unittest__SOURCES_DIST = \
- test/gtest_break_on_failure_unittest_.cc
-@HAVE_PYTHON_TRUE@am_test_gtest_break_on_failure_unittest__OBJECTS = test/gtest_break_on_failure_unittest_.$(OBJEXT)
-test_gtest_break_on_failure_unittest__OBJECTS = \
- $(am_test_gtest_break_on_failure_unittest__OBJECTS)
-@HAVE_PYTHON_TRUE@test_gtest_break_on_failure_unittest__DEPENDENCIES = \
-@HAVE_PYTHON_TRUE@ lib/libgtest.la
-am__test_gtest_color_test__SOURCES_DIST = test/gtest_color_test_.cc
-@HAVE_PYTHON_TRUE@am_test_gtest_color_test__OBJECTS = \
-@HAVE_PYTHON_TRUE@ test/gtest_color_test_.$(OBJEXT)
-test_gtest_color_test__OBJECTS = $(am_test_gtest_color_test__OBJECTS)
-@HAVE_PYTHON_TRUE@test_gtest_color_test__DEPENDENCIES = \
-@HAVE_PYTHON_TRUE@ lib/libgtest.la
-am__test_gtest_env_var_test__SOURCES_DIST = \
- test/gtest_env_var_test_.cc
-@HAVE_PYTHON_TRUE@am_test_gtest_env_var_test__OBJECTS = \
-@HAVE_PYTHON_TRUE@ test/gtest_env_var_test_.$(OBJEXT)
-test_gtest_env_var_test__OBJECTS = \
- $(am_test_gtest_env_var_test__OBJECTS)
-@HAVE_PYTHON_TRUE@test_gtest_env_var_test__DEPENDENCIES = \
-@HAVE_PYTHON_TRUE@ lib/libgtest.la
-am_test_gtest_environment_test_OBJECTS = \
- test/gtest_environment_test.$(OBJEXT)
-test_gtest_environment_test_OBJECTS = \
- $(am_test_gtest_environment_test_OBJECTS)
-test_gtest_environment_test_DEPENDENCIES = lib/libgtest.la
-am__test_gtest_filter_unittest__SOURCES_DIST = \
- test/gtest_filter_unittest_.cc
-@HAVE_PYTHON_TRUE@am_test_gtest_filter_unittest__OBJECTS = \
-@HAVE_PYTHON_TRUE@ test/gtest_filter_unittest_.$(OBJEXT)
-test_gtest_filter_unittest__OBJECTS = \
- $(am_test_gtest_filter_unittest__OBJECTS)
-@HAVE_PYTHON_TRUE@test_gtest_filter_unittest__DEPENDENCIES = \
-@HAVE_PYTHON_TRUE@ lib/libgtest.la
-am__test_gtest_help_test__SOURCES_DIST = test/gtest_help_test_.cc
-@HAVE_PYTHON_TRUE@am_test_gtest_help_test__OBJECTS = \
-@HAVE_PYTHON_TRUE@ test/gtest_help_test_.$(OBJEXT)
-test_gtest_help_test__OBJECTS = $(am_test_gtest_help_test__OBJECTS)
-@HAVE_PYTHON_TRUE@test_gtest_help_test__DEPENDENCIES = \
-@HAVE_PYTHON_TRUE@ lib/libgtest_main.la
-am__test_gtest_list_tests_unittest__SOURCES_DIST = \
- test/gtest_list_tests_unittest_.cc
-@HAVE_PYTHON_TRUE@am_test_gtest_list_tests_unittest__OBJECTS = \
-@HAVE_PYTHON_TRUE@ test/gtest_list_tests_unittest_.$(OBJEXT)
-test_gtest_list_tests_unittest__OBJECTS = \
- $(am_test_gtest_list_tests_unittest__OBJECTS)
-@HAVE_PYTHON_TRUE@test_gtest_list_tests_unittest__DEPENDENCIES = \
-@HAVE_PYTHON_TRUE@ lib/libgtest.la
-am_test_gtest_main_unittest_OBJECTS = \
- test/gtest_main_unittest.$(OBJEXT)
-test_gtest_main_unittest_OBJECTS = \
- $(am_test_gtest_main_unittest_OBJECTS)
-test_gtest_main_unittest_DEPENDENCIES = lib/libgtest_main.la
-am_test_gtest_no_rtti_test_OBJECTS = \
- test/test_gtest_no_rtti_test-gtest_unittest.$(OBJEXT) \
- src/test_gtest_no_rtti_test-gtest-all.$(OBJEXT) \
- src/test_gtest_no_rtti_test-gtest_main.$(OBJEXT)
-test_gtest_no_rtti_test_OBJECTS = \
- $(am_test_gtest_no_rtti_test_OBJECTS)
-test_gtest_no_rtti_test_LDADD = $(LDADD)
-test_gtest_no_rtti_test_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
- $(test_gtest_no_rtti_test_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
-am_test_gtest_no_test_unittest_OBJECTS = \
- test/gtest_no_test_unittest.$(OBJEXT)
-test_gtest_no_test_unittest_OBJECTS = \
- $(am_test_gtest_no_test_unittest_OBJECTS)
-test_gtest_no_test_unittest_DEPENDENCIES = lib/libgtest.la
-am__test_gtest_output_test__SOURCES_DIST = test/gtest_output_test_.cc
-@HAVE_PYTHON_TRUE@am_test_gtest_output_test__OBJECTS = \
-@HAVE_PYTHON_TRUE@ test/gtest_output_test_.$(OBJEXT)
-test_gtest_output_test__OBJECTS = \
- $(am_test_gtest_output_test__OBJECTS)
-@HAVE_PYTHON_TRUE@test_gtest_output_test__DEPENDENCIES = \
-@HAVE_PYTHON_TRUE@ lib/libgtest.la
-am_test_gtest_pred_impl_unittest_OBJECTS = \
- test/gtest_pred_impl_unittest.$(OBJEXT)
-test_gtest_pred_impl_unittest_OBJECTS = \
- $(am_test_gtest_pred_impl_unittest_OBJECTS)
-test_gtest_pred_impl_unittest_DEPENDENCIES = lib/libgtest_main.la
-am_test_gtest_prod_test_OBJECTS = test/gtest_prod_test.$(OBJEXT) \
- test/production.$(OBJEXT)
-test_gtest_prod_test_OBJECTS = $(am_test_gtest_prod_test_OBJECTS)
-test_gtest_prod_test_DEPENDENCIES = lib/libgtest_main.la
-am_test_gtest_repeat_test_OBJECTS = test/gtest_repeat_test.$(OBJEXT)
-test_gtest_repeat_test_OBJECTS = $(am_test_gtest_repeat_test_OBJECTS)
-test_gtest_repeat_test_DEPENDENCIES = lib/libgtest.la
-am__test_gtest_shuffle_test__SOURCES_DIST = \
- test/gtest_shuffle_test_.cc
-@HAVE_PYTHON_TRUE@am_test_gtest_shuffle_test__OBJECTS = \
-@HAVE_PYTHON_TRUE@ test/gtest_shuffle_test_.$(OBJEXT)
-test_gtest_shuffle_test__OBJECTS = \
- $(am_test_gtest_shuffle_test__OBJECTS)
-@HAVE_PYTHON_TRUE@test_gtest_shuffle_test__DEPENDENCIES = \
-@HAVE_PYTHON_TRUE@ lib/libgtest.la
-am_test_gtest_sole_header_test_OBJECTS = \
- test/gtest_sole_header_test.$(OBJEXT)
-test_gtest_sole_header_test_OBJECTS = \
- $(am_test_gtest_sole_header_test_OBJECTS)
-test_gtest_sole_header_test_DEPENDENCIES = lib/libgtest_main.la
-am_test_gtest_stress_test_OBJECTS = test/gtest_stress_test.$(OBJEXT)
-test_gtest_stress_test_OBJECTS = $(am_test_gtest_stress_test_OBJECTS)
-test_gtest_stress_test_DEPENDENCIES = lib/libgtest.la
-am_test_gtest_throw_on_failure_ex_test_OBJECTS = test/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.$(OBJEXT) \
- src/test_gtest_throw_on_failure_ex_test-gtest-all.$(OBJEXT)
-test_gtest_throw_on_failure_ex_test_OBJECTS = \
- $(am_test_gtest_throw_on_failure_ex_test_OBJECTS)
-test_gtest_throw_on_failure_ex_test_LDADD = $(LDADD)
-test_gtest_throw_on_failure_ex_test_LINK = $(LIBTOOL) --tag=CXX \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
- $(test_gtest_throw_on_failure_ex_test_CXXFLAGS) $(CXXFLAGS) \
- $(AM_LDFLAGS) $(LDFLAGS) -o $@
-am__test_gtest_throw_on_failure_test__SOURCES_DIST = \
- test/gtest_throw_on_failure_test_.cc src/gtest-all.cc
-@HAVE_PYTHON_TRUE@am_test_gtest_throw_on_failure_test__OBJECTS = test/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.$(OBJEXT) \
-@HAVE_PYTHON_TRUE@ src/test_gtest_throw_on_failure_test_-gtest-all.$(OBJEXT)
-test_gtest_throw_on_failure_test__OBJECTS = \
- $(am_test_gtest_throw_on_failure_test__OBJECTS)
-test_gtest_throw_on_failure_test__LDADD = $(LDADD)
-test_gtest_throw_on_failure_test__LINK = $(LIBTOOL) --tag=CXX \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
- $(test_gtest_throw_on_failure_test__CXXFLAGS) $(CXXFLAGS) \
- $(AM_LDFLAGS) $(LDFLAGS) -o $@
-am__test_gtest_uninitialized_test__SOURCES_DIST = \
- test/gtest_uninitialized_test_.cc
-@HAVE_PYTHON_TRUE@am_test_gtest_uninitialized_test__OBJECTS = \
-@HAVE_PYTHON_TRUE@ test/gtest_uninitialized_test_.$(OBJEXT)
-test_gtest_uninitialized_test__OBJECTS = \
- $(am_test_gtest_uninitialized_test__OBJECTS)
-@HAVE_PYTHON_TRUE@test_gtest_uninitialized_test__DEPENDENCIES = \
-@HAVE_PYTHON_TRUE@ lib/libgtest.la
-am_test_gtest_unittest_OBJECTS = test/gtest_unittest.$(OBJEXT)
-test_gtest_unittest_OBJECTS = $(am_test_gtest_unittest_OBJECTS)
-test_gtest_unittest_DEPENDENCIES = lib/libgtest_main.la
-am_test_gtest_use_own_tuple_test_OBJECTS = test/test_gtest_use_own_tuple_test-gtest-param-test_test.$(OBJEXT) \
- test/test_gtest_use_own_tuple_test-gtest-param-test2_test.$(OBJEXT) \
- src/test_gtest_use_own_tuple_test-gtest-all.$(OBJEXT)
-test_gtest_use_own_tuple_test_OBJECTS = \
- $(am_test_gtest_use_own_tuple_test_OBJECTS)
-test_gtest_use_own_tuple_test_LDADD = $(LDADD)
-test_gtest_use_own_tuple_test_LINK = $(LIBTOOL) --tag=CXX \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
- $(test_gtest_use_own_tuple_test_CXXFLAGS) $(CXXFLAGS) \
- $(AM_LDFLAGS) $(LDFLAGS) -o $@
-am__test_gtest_xml_outfile1_test__SOURCES_DIST = \
- test/gtest_xml_outfile1_test_.cc
-@HAVE_PYTHON_TRUE@am_test_gtest_xml_outfile1_test__OBJECTS = \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_outfile1_test_.$(OBJEXT)
-test_gtest_xml_outfile1_test__OBJECTS = \
- $(am_test_gtest_xml_outfile1_test__OBJECTS)
-@HAVE_PYTHON_TRUE@test_gtest_xml_outfile1_test__DEPENDENCIES = \
-@HAVE_PYTHON_TRUE@ lib/libgtest_main.la
-am__test_gtest_xml_outfile2_test__SOURCES_DIST = \
- test/gtest_xml_outfile2_test_.cc
-@HAVE_PYTHON_TRUE@am_test_gtest_xml_outfile2_test__OBJECTS = \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_outfile2_test_.$(OBJEXT)
-test_gtest_xml_outfile2_test__OBJECTS = \
- $(am_test_gtest_xml_outfile2_test__OBJECTS)
-@HAVE_PYTHON_TRUE@test_gtest_xml_outfile2_test__DEPENDENCIES = \
-@HAVE_PYTHON_TRUE@ lib/libgtest_main.la
-am__test_gtest_xml_output_unittest__SOURCES_DIST = \
- test/gtest_xml_output_unittest_.cc
-@HAVE_PYTHON_TRUE@am_test_gtest_xml_output_unittest__OBJECTS = \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_output_unittest_.$(OBJEXT)
-test_gtest_xml_output_unittest__OBJECTS = \
- $(am_test_gtest_xml_output_unittest__OBJECTS)
-@HAVE_PYTHON_TRUE@test_gtest_xml_output_unittest__DEPENDENCIES = \
-@HAVE_PYTHON_TRUE@ lib/libgtest.la
+am__objects_1 = \
+ fused-src/gtest/test_fused_gtest_test-gtest-all.$(OBJEXT) \
+ fused-src/gtest/test_fused_gtest_test-gtest_main.$(OBJEXT)
+am_test_fused_gtest_test_OBJECTS = $(am__objects_1) \
+ samples/test_fused_gtest_test-sample1.$(OBJEXT) \
+ samples/test_fused_gtest_test-sample1_unittest.$(OBJEXT)
+test_fused_gtest_test_OBJECTS = $(am_test_fused_gtest_test_OBJECTS)
+test_fused_gtest_test_LDADD = $(LDADD)
+am_test_gtest_all_test_OBJECTS = test/gtest_all_test.$(OBJEXT)
+test_gtest_all_test_OBJECTS = $(am_test_gtest_all_test_OBJECTS)
+test_gtest_all_test_DEPENDENCIES = lib/libgtest_main.la
SCRIPTS = $(bin_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/build-aux
depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
SOURCES = $(lib_libgtest_la_SOURCES) $(lib_libgtest_main_la_SOURCES) \
$(samples_libsamples_la_SOURCES) \
$(samples_sample10_unittest_SOURCES) \
$(samples_sample1_unittest_SOURCES) \
- $(samples_sample2_unittest_SOURCES) \
- $(samples_sample3_unittest_SOURCES) \
- $(samples_sample4_unittest_SOURCES) \
- $(samples_sample5_unittest_SOURCES) \
- $(samples_sample6_unittest_SOURCES) \
- $(samples_sample7_unittest_SOURCES) \
- $(samples_sample8_unittest_SOURCES) \
- $(samples_sample9_unittest_SOURCES) \
- $(test_gtest_death_test_test_SOURCES) \
- $(test_gtest_filepath_test_SOURCES) \
- $(test_gtest_linked_ptr_test_SOURCES) \
- $(test_gtest_listener_test_SOURCES) \
- $(test_gtest_message_test_SOURCES) \
- $(test_gtest_options_test_SOURCES) \
- $(test_gtest_param_test_test_SOURCES) \
- $(test_gtest_port_test_SOURCES) \
- $(test_gtest_test_part_test_SOURCES) \
- $(test_gtest_tuple_test_SOURCES) \
- $(test_gtest_typed_test_test_SOURCES) \
- $(test_gtest_unittest_api_test_SOURCES) \
- $(test_gtest_break_on_failure_unittest__SOURCES) \
- $(test_gtest_color_test__SOURCES) \
- $(test_gtest_env_var_test__SOURCES) \
- $(test_gtest_environment_test_SOURCES) \
- $(test_gtest_filter_unittest__SOURCES) \
- $(test_gtest_help_test__SOURCES) \
- $(test_gtest_list_tests_unittest__SOURCES) \
- $(test_gtest_main_unittest_SOURCES) \
- $(test_gtest_no_rtti_test_SOURCES) \
- $(test_gtest_no_test_unittest_SOURCES) \
- $(test_gtest_output_test__SOURCES) \
- $(test_gtest_pred_impl_unittest_SOURCES) \
- $(test_gtest_prod_test_SOURCES) \
- $(test_gtest_repeat_test_SOURCES) \
- $(test_gtest_shuffle_test__SOURCES) \
- $(test_gtest_sole_header_test_SOURCES) \
- $(test_gtest_stress_test_SOURCES) \
- $(test_gtest_throw_on_failure_ex_test_SOURCES) \
- $(test_gtest_throw_on_failure_test__SOURCES) \
- $(test_gtest_uninitialized_test__SOURCES) \
- $(test_gtest_unittest_SOURCES) \
- $(test_gtest_use_own_tuple_test_SOURCES) \
- $(test_gtest_xml_outfile1_test__SOURCES) \
- $(test_gtest_xml_outfile2_test__SOURCES) \
- $(test_gtest_xml_output_unittest__SOURCES)
+ $(test_fused_gtest_test_SOURCES) \
+ $(test_gtest_all_test_SOURCES)
DIST_SOURCES = $(lib_libgtest_la_SOURCES) \
$(lib_libgtest_main_la_SOURCES) \
$(samples_libsamples_la_SOURCES) \
$(samples_sample10_unittest_SOURCES) \
$(samples_sample1_unittest_SOURCES) \
- $(samples_sample2_unittest_SOURCES) \
- $(samples_sample3_unittest_SOURCES) \
- $(samples_sample4_unittest_SOURCES) \
- $(samples_sample5_unittest_SOURCES) \
- $(samples_sample6_unittest_SOURCES) \
- $(samples_sample7_unittest_SOURCES) \
- $(samples_sample8_unittest_SOURCES) \
- $(samples_sample9_unittest_SOURCES) \
- $(test_gtest_death_test_test_SOURCES) \
- $(test_gtest_filepath_test_SOURCES) \
- $(test_gtest_linked_ptr_test_SOURCES) \
- $(test_gtest_listener_test_SOURCES) \
- $(test_gtest_message_test_SOURCES) \
- $(test_gtest_options_test_SOURCES) \
- $(test_gtest_param_test_test_SOURCES) \
- $(test_gtest_port_test_SOURCES) \
- $(test_gtest_test_part_test_SOURCES) \
- $(test_gtest_tuple_test_SOURCES) \
- $(test_gtest_typed_test_test_SOURCES) \
- $(test_gtest_unittest_api_test_SOURCES) \
- $(am__test_gtest_break_on_failure_unittest__SOURCES_DIST) \
- $(am__test_gtest_color_test__SOURCES_DIST) \
- $(am__test_gtest_env_var_test__SOURCES_DIST) \
- $(test_gtest_environment_test_SOURCES) \
- $(am__test_gtest_filter_unittest__SOURCES_DIST) \
- $(am__test_gtest_help_test__SOURCES_DIST) \
- $(am__test_gtest_list_tests_unittest__SOURCES_DIST) \
- $(test_gtest_main_unittest_SOURCES) \
- $(test_gtest_no_rtti_test_SOURCES) \
- $(test_gtest_no_test_unittest_SOURCES) \
- $(am__test_gtest_output_test__SOURCES_DIST) \
- $(test_gtest_pred_impl_unittest_SOURCES) \
- $(test_gtest_prod_test_SOURCES) \
- $(test_gtest_repeat_test_SOURCES) \
- $(am__test_gtest_shuffle_test__SOURCES_DIST) \
- $(test_gtest_sole_header_test_SOURCES) \
- $(test_gtest_stress_test_SOURCES) \
- $(test_gtest_throw_on_failure_ex_test_SOURCES) \
- $(am__test_gtest_throw_on_failure_test__SOURCES_DIST) \
- $(am__test_gtest_uninitialized_test__SOURCES_DIST) \
- $(test_gtest_unittest_SOURCES) \
- $(test_gtest_use_own_tuple_test_SOURCES) \
- $(am__test_gtest_xml_outfile1_test__SOURCES_DIST) \
- $(am__test_gtest_xml_outfile2_test__SOURCES_DIST) \
- $(am__test_gtest_xml_output_unittest__SOURCES_DIST)
+ $(test_fused_gtest_test_SOURCES) \
+ $(test_gtest_all_test_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
DATA = $(m4data_DATA)
HEADERS = $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
-am__tty_colors = \
-red=; grn=; lgn=; blu=; std=
+CSCOPE = cscope
+AM_RECURSIVE_TARGETS = cscope check recheck
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -651,14 +463,17 @@ am__remove_distdir = \
&& rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip
GZIP_ENV = --best
+DIST_TARGETS = dist-bzip2 dist-gzip dist-zip
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
@@ -783,6 +598,14 @@ top_srcdir = @top_srcdir@
# Nonstandard package files for distribution
+# Sample files that we don't compile.
+
+# C++ test files that we don't compile directly.
+
+# Python tests that we don't run.
+
+# CMake script
+
# MSVC project files
# xcode project files
@@ -795,11 +618,52 @@ EXTRA_DIST = CHANGES CONTRIBUTORS \
include/gtest/internal/gtest-tuple.h.pump \
include/gtest/internal/gtest-type-util.h.pump \
include/gtest/internal/gtest-param-util-generated.h.pump \
- make/Makefile scons/SConscript scons/SConstruct \
- scons/SConstruct.common scripts/fuse_gtest_files.py \
- scripts/gen_gtest_pred_impl.py scripts/test/Makefile \
- test/gtest_all_test.cc msvc/gtest-md.sln msvc/gtest.sln \
- msvc/gtest-md.vcproj msvc/gtest.vcproj \
+ make/Makefile scripts/fuse_gtest_files.py \
+ scripts/gen_gtest_pred_impl.py scripts/pump.py \
+ scripts/test/Makefile $(GTEST_SRC) samples/prime_tables.h \
+ samples/sample2_unittest.cc samples/sample3_unittest.cc \
+ samples/sample4_unittest.cc samples/sample5_unittest.cc \
+ samples/sample6_unittest.cc samples/sample7_unittest.cc \
+ samples/sample8_unittest.cc samples/sample9_unittest.cc \
+ test/gtest-death-test_test.cc test/gtest_environment_test.cc \
+ test/gtest-filepath_test.cc test/gtest-linked_ptr_test.cc \
+ test/gtest-message_test.cc test/gtest_no_test_unittest.cc \
+ test/gtest-options_test.cc test/gtest-param-test_test.cc \
+ test/gtest-param-test2_test.cc test/gtest-param-test_test.h \
+ test/gtest-port_test.cc test/gtest_pred_impl_unittest.cc \
+ test/gtest_prod_test.cc test/production.cc test/production.h \
+ test/gtest_repeat_test.cc test/gtest_sole_header_test.cc \
+ test/gtest_stress_test.cc test/gtest-test-part_test.cc \
+ test/gtest_throw_on_failure_ex_test.cc \
+ test/gtest-typed-test_test.cc test/gtest-typed-test2_test.cc \
+ test/gtest-typed-test_test.h test/gtest_unittest.cc \
+ test/gtest-unittest-api_test.cc test/gtest-listener_test.cc \
+ test/gtest_main_unittest.cc test/gtest_unittest.cc \
+ test/gtest-tuple_test.cc test/gtest-param-test_test.cc \
+ test/gtest-param-test2_test.cc \
+ test/gtest_break_on_failure_unittest_.cc \
+ test/gtest_color_test_.cc test/gtest_env_var_test_.cc \
+ test/gtest_filter_unittest_.cc test/gtest_help_test_.cc \
+ test/gtest_list_tests_unittest_.cc test/gtest_output_test_.cc \
+ test/gtest_shuffle_test_.cc \
+ test/gtest_throw_on_failure_test_.cc \
+ test/gtest_uninitialized_test_.cc \
+ test/gtest_xml_outfile1_test_.cc \
+ test/gtest_xml_outfile2_test_.cc \
+ test/gtest_xml_output_unittest_.cc test/gtest_test_utils.py \
+ test/gtest_xml_test_utils.py \
+ test/gtest_break_on_failure_unittest.py \
+ test/gtest_color_test.py test/gtest_env_var_test.py \
+ test/gtest_filter_unittest.py test/gtest_help_test.py \
+ test/gtest_list_tests_unittest.py test/gtest_output_test.py \
+ test/gtest_output_test_golden_lin.txt \
+ test/gtest_output_test_golden_win.txt \
+ test/gtest_shuffle_test.py test/gtest_throw_on_failure_test.py \
+ test/gtest_uninitialized_test.py \
+ test/gtest_xml_outfiles_test.py \
+ test/gtest_xml_output_unittest.py test/run_tests_util.py \
+ test/run_tests_util_test.py CMakeLists.txt msvc/gtest-md.sln \
+ msvc/gtest.sln msvc/gtest-md.vcproj msvc/gtest.vcproj \
msvc/gtest_main-md.vcproj msvc/gtest_main.vcproj \
msvc/gtest_prod_test-md.vcproj msvc/gtest_prod_test.vcproj \
msvc/gtest_unittest-md.vcproj msvc/gtest_unittest.vcproj \
@@ -812,6 +676,7 @@ EXTRA_DIST = CHANGES CONTRIBUTORS \
xcode/Scripts/versiongenerate.py xcode/Scripts/runtests.sh \
xcode/gtest.xcodeproj/project.pbxproj \
xcode/Samples/FrameworkSample/Info.plist \
+ xcode/Samples/FrameworkSample/runtests.sh \
xcode/Samples/FrameworkSample/widget_test.cc \
xcode/Samples/FrameworkSample/widget.cc \
xcode/Samples/FrameworkSample/widget.h \
@@ -819,16 +684,26 @@ EXTRA_DIST = CHANGES CONTRIBUTORS \
codegear/gtest_all.cc codegear/gtest_link.cc \
codegear/gtest.cbproj codegear/gtest_main.cbproj \
codegear/gtest_unittest.cbproj codegear/gtest.groupproj \
- $(m4data_DATA) $(am__append_3)
+ $(m4data_DATA)
+
+# gtest source files that we don't compile directly. They are
+# #included by gtest-all.cc.
+GTEST_SRC = \
+ src/gtest.cc \
+ src/gtest-death-test.cc \
+ src/gtest-filepath.cc \
+ src/gtest-internal-inl.h \
+ src/gtest-port.cc \
+ src/gtest-test-part.cc \
+ src/gtest-typed-test.cc
-# TODO(wan@google.com): integrate scripts/gen_gtest_pred_impl.py into
-# the build system such that a user can specify the maximum predicate
-# arity here and have the script automatically generate the
-# corresponding .h and .cc files.
# Scripts and utilities
bin_SCRIPTS = scripts/gtest-config
-CLEANFILES = $(bin_SCRIPTS)
+
+# Death tests may produce core dumps in the build directory. In case
+# this happens, clean them to keep distcleancheck happy.
+CLEANFILES = $(bin_SCRIPTS) core
# Distribute and install M4 macro
m4datadir = $(datadir)/aclocal
@@ -837,17 +712,15 @@ m4data_DATA = m4/gtest.m4
# We define the global AM_CPPFLAGS as everything we compile includes from these
# directories.
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include
+@HAVE_PTHREADS_FALSE@AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0
+
+# Modifies compiler and linker flags for pthreads compatibility.
+@HAVE_PTHREADS_TRUE@AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1
+@HAVE_PTHREADS_TRUE@AM_LIBS = @PTHREAD_LIBS@
# Build rules for libraries.
lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la
-lib_libgtest_la_SOURCES = src/gtest.cc \
- src/gtest-death-test.cc \
- src/gtest-filepath.cc \
- src/gtest-internal-inl.h \
- src/gtest-port.cc \
- src/gtest-test-part.cc \
- src/gtest-typed-test.cc
-
+lib_libgtest_la_SOURCES = src/gtest-all.cc
pkginclude_HEADERS = include/gtest/gtest.h \
include/gtest/gtest-death-test.h \
include/gtest/gtest-message.h \
@@ -896,170 +769,25 @@ samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc
samples_sample1_unittest_LDADD = lib/libgtest_main.la \
samples/libsamples.la
-samples_sample2_unittest_SOURCES = samples/sample2_unittest.cc
-samples_sample2_unittest_LDADD = lib/libgtest_main.la \
- samples/libsamples.la
-
-samples_sample3_unittest_SOURCES = samples/sample3_unittest.cc
-samples_sample3_unittest_LDADD = lib/libgtest_main.la \
- samples/libsamples.la
-
-samples_sample4_unittest_SOURCES = samples/sample4_unittest.cc
-samples_sample4_unittest_LDADD = lib/libgtest_main.la \
- samples/libsamples.la
-
-samples_sample5_unittest_SOURCES = samples/sample5_unittest.cc
-samples_sample5_unittest_LDADD = lib/libgtest_main.la \
- samples/libsamples.la
-
-samples_sample6_unittest_SOURCES = samples/prime_tables.h \
- samples/sample6_unittest.cc
+samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc
+samples_sample10_unittest_LDADD = lib/libgtest.la
+test_gtest_all_test_SOURCES = test/gtest_all_test.cc
+test_gtest_all_test_LDADD = lib/libgtest_main.la
-samples_sample6_unittest_LDADD = lib/libgtest_main.la
-samples_sample7_unittest_SOURCES = samples/prime_tables.h \
- samples/sample7_unittest.cc
+# Tests that fused gtest files compile and work.
+FUSED_GTEST_SRC = \
+ fused-src/gtest/gtest-all.cc \
+ fused-src/gtest/gtest_main.cc \
+ fused-src/gtest/gtest.h
-samples_sample7_unittest_LDADD = lib/libgtest_main.la
-samples_sample8_unittest_SOURCES = samples/prime_tables.h \
- samples/sample8_unittest.cc
+test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \
+ samples/sample1.cc samples/sample1_unittest.cc
-samples_sample8_unittest_LDADD = lib/libgtest_main.la
-samples_sample9_unittest_SOURCES = samples/sample9_unittest.cc
-samples_sample9_unittest_LDADD = lib/libgtest.la
-samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc
-samples_sample10_unittest_LDADD = lib/libgtest.la
-test_gtest_death_test_test_SOURCES = test/gtest-death-test_test.cc
-test_gtest_death_test_test_CXXFLAGS = $(AM_CXXFLAGS) $(PTHREAD_CFLAGS)
-test_gtest_death_test_test_LDADD = $(PTHREAD_LIBS) $(PTHREAD_CFLAGS) \
- lib/libgtest_main.la
-
-test_gtest_environment_test_SOURCES = test/gtest_environment_test.cc
-test_gtest_environment_test_LDADD = lib/libgtest.la
-test_gtest_filepath_test_SOURCES = test/gtest-filepath_test.cc
-test_gtest_filepath_test_LDADD = lib/libgtest_main.la
-test_gtest_linked_ptr_test_SOURCES = test/gtest-linked_ptr_test.cc
-test_gtest_linked_ptr_test_LDADD = lib/libgtest_main.la
-test_gtest_main_unittest_SOURCES = test/gtest_main_unittest.cc
-test_gtest_main_unittest_LDADD = lib/libgtest_main.la
-test_gtest_message_test_SOURCES = test/gtest-message_test.cc
-test_gtest_message_test_LDADD = lib/libgtest_main.la
-test_gtest_no_test_unittest_SOURCES = test/gtest_no_test_unittest.cc
-test_gtest_no_test_unittest_LDADD = lib/libgtest.la
-test_gtest_options_test_SOURCES = test/gtest-options_test.cc
-test_gtest_options_test_LDADD = lib/libgtest_main.la
-test_gtest_param_test_test_SOURCES = test/gtest-param-test_test.cc \
- test/gtest-param-test2_test.cc \
- test/gtest-param-test_test.h
-
-test_gtest_param_test_test_LDADD = lib/libgtest.la
-test_gtest_port_test_SOURCES = test/gtest-port_test.cc
-test_gtest_port_test_LDADD = lib/libgtest_main.la
-test_gtest_pred_impl_unittest_SOURCES = test/gtest_pred_impl_unittest.cc
-test_gtest_pred_impl_unittest_LDADD = lib/libgtest_main.la
-test_gtest_prod_test_SOURCES = test/gtest_prod_test.cc \
- test/production.cc \
- test/production.h
-
-test_gtest_prod_test_LDADD = lib/libgtest_main.la
-test_gtest_repeat_test_SOURCES = test/gtest_repeat_test.cc
-test_gtest_repeat_test_LDADD = lib/libgtest.la
-test_gtest_sole_header_test_SOURCES = test/gtest_sole_header_test.cc
-test_gtest_sole_header_test_LDADD = lib/libgtest_main.la
-test_gtest_stress_test_SOURCES = test/gtest_stress_test.cc
-test_gtest_stress_test_LDADD = lib/libgtest.la
-test_gtest_test_part_test_SOURCES = test/gtest-test-part_test.cc
-test_gtest_test_part_test_LDADD = lib/libgtest_main.la
-test_gtest_throw_on_failure_ex_test_SOURCES = \
- test/gtest_throw_on_failure_ex_test.cc \
- src/gtest-all.cc
-
-test_gtest_throw_on_failure_ex_test_CXXFLAGS = $(AM_CXXFLAGS) -fexceptions
-test_gtest_typed_test_test_SOURCES = test/gtest-typed-test_test.cc \
- test/gtest-typed-test2_test.cc \
- test/gtest-typed-test_test.h
-
-test_gtest_typed_test_test_LDADD = lib/libgtest_main.la
-test_gtest_unittest_SOURCES = test/gtest_unittest.cc
-test_gtest_unittest_LDADD = lib/libgtest_main.la
-test_gtest_unittest_api_test_SOURCES = test/gtest-unittest-api_test.cc
-test_gtest_unittest_api_test_LDADD = lib/libgtest_main.la
-test_gtest_listener_test_SOURCES = test/gtest-listener_test.cc
-test_gtest_listener_test_LDADD = lib/libgtest_main.la
-test_gtest_no_rtti_test_SOURCES = test/gtest_unittest.cc \
- src/gtest-all.cc \
- src/gtest_main.cc
-
-test_gtest_no_rtti_test_CXXFLAGS = $(AM_CXXFLAGS) -fno-rtti -DGTEST_HAS_RTTI=0
-test_gtest_tuple_test_SOURCES = test/gtest-tuple_test.cc \
- src/gtest-all.cc \
- src/gtest_main.cc
-
-test_gtest_tuple_test_CXXFLAGS = $(AM_CXXFLAGS) -DGTEST_USE_OWN_TR1_TUPLE=1
-test_gtest_use_own_tuple_test_SOURCES = test/gtest-param-test_test.cc \
- test/gtest-param-test2_test.cc \
- src/gtest-all.cc
-
-test_gtest_use_own_tuple_test_CXXFLAGS = \
- $(AM_CXXFLAGS) -DGTEST_USE_OWN_TR1_TUPLE=1
-
-
-# The following tests depend on the presence of a Python installation and are
-# keyed off of it. TODO(chandlerc@google.com): While we currently only attempt
-# to build and execute these tests if Autoconf has found Python v2.4 on the
-# system, we don't use the PYTHON variable it specified as the valid
-# interpreter. The problem is that TESTS_ENVIRONMENT is a global variable, and
-# thus we cannot distinguish between C++ unit tests and Python unit tests.
-
-# These two Python modules are used by multiple Python tests below.
-@HAVE_PYTHON_TRUE@check_SCRIPTS = test/gtest_test_utils.py \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_test_utils.py \
-@HAVE_PYTHON_TRUE@ test/gtest_break_on_failure_unittest.py \
-@HAVE_PYTHON_TRUE@ test/gtest_color_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_env_var_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_filter_unittest.py \
-@HAVE_PYTHON_TRUE@ test/gtest_help_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_list_tests_unittest.py \
-@HAVE_PYTHON_TRUE@ test/gtest_output_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_shuffle_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_throw_on_failure_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_uninitialized_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_outfiles_test.py \
-@HAVE_PYTHON_TRUE@ test/gtest_xml_output_unittest.py
-@HAVE_PYTHON_TRUE@test_gtest_break_on_failure_unittest__SOURCES = \
-@HAVE_PYTHON_TRUE@ test/gtest_break_on_failure_unittest_.cc
-
-@HAVE_PYTHON_TRUE@test_gtest_break_on_failure_unittest__LDADD = lib/libgtest.la
-@HAVE_PYTHON_TRUE@test_gtest_color_test__SOURCES = test/gtest_color_test_.cc
-@HAVE_PYTHON_TRUE@test_gtest_color_test__LDADD = lib/libgtest.la
-@HAVE_PYTHON_TRUE@test_gtest_env_var_test__SOURCES = test/gtest_env_var_test_.cc
-@HAVE_PYTHON_TRUE@test_gtest_env_var_test__LDADD = lib/libgtest.la
-@HAVE_PYTHON_TRUE@test_gtest_filter_unittest__SOURCES = test/gtest_filter_unittest_.cc
-@HAVE_PYTHON_TRUE@test_gtest_filter_unittest__LDADD = lib/libgtest.la
-@HAVE_PYTHON_TRUE@test_gtest_help_test__SOURCES = test/gtest_help_test_.cc
-@HAVE_PYTHON_TRUE@test_gtest_help_test__LDADD = lib/libgtest_main.la
-@HAVE_PYTHON_TRUE@test_gtest_list_tests_unittest__SOURCES = test/gtest_list_tests_unittest_.cc
-@HAVE_PYTHON_TRUE@test_gtest_list_tests_unittest__LDADD = lib/libgtest.la
-@HAVE_PYTHON_TRUE@test_gtest_output_test__SOURCES = test/gtest_output_test_.cc
-@HAVE_PYTHON_TRUE@test_gtest_output_test__LDADD = lib/libgtest.la
-@HAVE_PYTHON_TRUE@test_gtest_shuffle_test__SOURCES = test/gtest_shuffle_test_.cc
-@HAVE_PYTHON_TRUE@test_gtest_shuffle_test__LDADD = lib/libgtest.la
-@HAVE_PYTHON_TRUE@test_gtest_throw_on_failure_test__SOURCES = \
-@HAVE_PYTHON_TRUE@ test/gtest_throw_on_failure_test_.cc \
-@HAVE_PYTHON_TRUE@ src/gtest-all.cc
-
-@HAVE_PYTHON_TRUE@test_gtest_throw_on_failure_test__CXXFLAGS = $(AM_CXXFLAGS) -fno-exceptions
-@HAVE_PYTHON_TRUE@test_gtest_uninitialized_test__SOURCES = test/gtest_uninitialized_test_.cc
-@HAVE_PYTHON_TRUE@test_gtest_uninitialized_test__LDADD = lib/libgtest.la
-@HAVE_PYTHON_TRUE@test_gtest_xml_outfile1_test__SOURCES = test/gtest_xml_outfile1_test_.cc
-@HAVE_PYTHON_TRUE@test_gtest_xml_outfile1_test__LDADD = lib/libgtest_main.la
-@HAVE_PYTHON_TRUE@test_gtest_xml_outfile2_test__SOURCES = test/gtest_xml_outfile2_test_.cc
-@HAVE_PYTHON_TRUE@test_gtest_xml_outfile2_test__LDADD = lib/libgtest_main.la
-@HAVE_PYTHON_TRUE@test_gtest_xml_output_unittest__SOURCES = test/gtest_xml_output_unittest_.cc
-@HAVE_PYTHON_TRUE@test_gtest_xml_output_unittest__LDADD = lib/libgtest.la
+test_fused_gtest_test_CPPFLAGS = -I"$(srcdir)/fused-src"
all: all-am
.SUFFIXES:
-.SUFFIXES: .cc .lo .o .obj
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
am--refresh: Makefile
@:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@@ -1096,8 +824,8 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
build-aux/config.h: build-aux/stamp-h1
- @if test ! -f $@; then rm -f build-aux/stamp-h1; else :; fi
- @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) build-aux/stamp-h1; else :; fi
+ @test -f $@ || rm -f build-aux/stamp-h1
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) build-aux/stamp-h1
build-aux/stamp-h1: $(top_srcdir)/build-aux/config.h.in $(top_builddir)/config.status
@rm -f build-aux/stamp-h1
@@ -1111,9 +839,9 @@ distclean-hdr:
-rm -f build-aux/config.h build-aux/stamp-h1
scripts/gtest-config: $(top_builddir)/config.status $(top_srcdir)/scripts/gtest-config.in
cd $(top_builddir) && $(SHELL) ./config.status $@
+
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
@@ -1121,6 +849,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES)
else :; fi; \
done; \
test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
@@ -1136,45 +866,42 @@ uninstall-libLTLIBRARIES:
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
- test "$$dir" != "$$p" || dir=.; \
- echo "rm -f \"$${dir}/so_locations\""; \
- rm -f "$${dir}/so_locations"; \
- done
+ @list='$(lib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
- @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
- dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
- test "$$dir" != "$$p" || dir=.; \
- echo "rm -f \"$${dir}/so_locations\""; \
- rm -f "$${dir}/so_locations"; \
- done
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
src/$(am__dirstamp):
@$(MKDIR_P) src
@: > src/$(am__dirstamp)
src/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) src/$(DEPDIR)
@: > src/$(DEPDIR)/$(am__dirstamp)
-src/gtest.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
-src/gtest-death-test.lo: src/$(am__dirstamp) \
- src/$(DEPDIR)/$(am__dirstamp)
-src/gtest-filepath.lo: src/$(am__dirstamp) \
- src/$(DEPDIR)/$(am__dirstamp)
-src/gtest-port.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
-src/gtest-test-part.lo: src/$(am__dirstamp) \
- src/$(DEPDIR)/$(am__dirstamp)
-src/gtest-typed-test.lo: src/$(am__dirstamp) \
- src/$(DEPDIR)/$(am__dirstamp)
+src/gtest-all.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
lib/$(am__dirstamp):
@$(MKDIR_P) lib
@: > lib/$(am__dirstamp)
+
lib/libgtest.la: $(lib_libgtest_la_OBJECTS) $(lib_libgtest_la_DEPENDENCIES) $(EXTRA_lib_libgtest_la_DEPENDENCIES) lib/$(am__dirstamp)
- $(CXXLINK) -rpath $(libdir) $(lib_libgtest_la_OBJECTS) $(lib_libgtest_la_LIBADD) $(LIBS)
+ $(AM_V_CXXLD)$(CXXLINK) -rpath $(libdir) $(lib_libgtest_la_OBJECTS) $(lib_libgtest_la_LIBADD) $(LIBS)
src/gtest_main.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
+
lib/libgtest_main.la: $(lib_libgtest_main_la_OBJECTS) $(lib_libgtest_main_la_DEPENDENCIES) $(EXTRA_lib_libgtest_main_la_DEPENDENCIES) lib/$(am__dirstamp)
- $(CXXLINK) -rpath $(libdir) $(lib_libgtest_main_la_OBJECTS) $(lib_libgtest_main_la_LIBADD) $(LIBS)
+ $(AM_V_CXXLD)$(CXXLINK) -rpath $(libdir) $(lib_libgtest_main_la_OBJECTS) $(lib_libgtest_main_la_LIBADD) $(LIBS)
samples/$(am__dirstamp):
@$(MKDIR_P) samples
@: > samples/$(am__dirstamp)
@@ -1187,8 +914,9 @@ samples/sample2.lo: samples/$(am__dirstamp) \
samples/$(DEPDIR)/$(am__dirstamp)
samples/sample4.lo: samples/$(am__dirstamp) \
samples/$(DEPDIR)/$(am__dirstamp)
+
samples/libsamples.la: $(samples_libsamples_la_OBJECTS) $(samples_libsamples_la_DEPENDENCIES) $(EXTRA_samples_libsamples_la_DEPENDENCIES) samples/$(am__dirstamp)
- $(CXXLINK) $(samples_libsamples_la_OBJECTS) $(samples_libsamples_la_LIBADD) $(LIBS)
+ $(AM_V_CXXLD)$(CXXLINK) $(samples_libsamples_la_OBJECTS) $(samples_libsamples_la_LIBADD) $(LIBS)
clean-checkPROGRAMS:
@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
@@ -1200,271 +928,55 @@ clean-checkPROGRAMS:
rm -f $$list
samples/sample10_unittest.$(OBJEXT): samples/$(am__dirstamp) \
samples/$(DEPDIR)/$(am__dirstamp)
+
samples/sample10_unittest$(EXEEXT): $(samples_sample10_unittest_OBJECTS) $(samples_sample10_unittest_DEPENDENCIES) $(EXTRA_samples_sample10_unittest_DEPENDENCIES) samples/$(am__dirstamp)
@rm -f samples/sample10_unittest$(EXEEXT)
- $(CXXLINK) $(samples_sample10_unittest_OBJECTS) $(samples_sample10_unittest_LDADD) $(LIBS)
+ $(AM_V_CXXLD)$(CXXLINK) $(samples_sample10_unittest_OBJECTS) $(samples_sample10_unittest_LDADD) $(LIBS)
samples/sample1_unittest.$(OBJEXT): samples/$(am__dirstamp) \
samples/$(DEPDIR)/$(am__dirstamp)
+
samples/sample1_unittest$(EXEEXT): $(samples_sample1_unittest_OBJECTS) $(samples_sample1_unittest_DEPENDENCIES) $(EXTRA_samples_sample1_unittest_DEPENDENCIES) samples/$(am__dirstamp)
@rm -f samples/sample1_unittest$(EXEEXT)
- $(CXXLINK) $(samples_sample1_unittest_OBJECTS) $(samples_sample1_unittest_LDADD) $(LIBS)
-samples/sample2_unittest.$(OBJEXT): samples/$(am__dirstamp) \
- samples/$(DEPDIR)/$(am__dirstamp)
-samples/sample2_unittest$(EXEEXT): $(samples_sample2_unittest_OBJECTS) $(samples_sample2_unittest_DEPENDENCIES) $(EXTRA_samples_sample2_unittest_DEPENDENCIES) samples/$(am__dirstamp)
- @rm -f samples/sample2_unittest$(EXEEXT)
- $(CXXLINK) $(samples_sample2_unittest_OBJECTS) $(samples_sample2_unittest_LDADD) $(LIBS)
-samples/sample3_unittest.$(OBJEXT): samples/$(am__dirstamp) \
- samples/$(DEPDIR)/$(am__dirstamp)
-samples/sample3_unittest$(EXEEXT): $(samples_sample3_unittest_OBJECTS) $(samples_sample3_unittest_DEPENDENCIES) $(EXTRA_samples_sample3_unittest_DEPENDENCIES) samples/$(am__dirstamp)
- @rm -f samples/sample3_unittest$(EXEEXT)
- $(CXXLINK) $(samples_sample3_unittest_OBJECTS) $(samples_sample3_unittest_LDADD) $(LIBS)
-samples/sample4_unittest.$(OBJEXT): samples/$(am__dirstamp) \
- samples/$(DEPDIR)/$(am__dirstamp)
-samples/sample4_unittest$(EXEEXT): $(samples_sample4_unittest_OBJECTS) $(samples_sample4_unittest_DEPENDENCIES) $(EXTRA_samples_sample4_unittest_DEPENDENCIES) samples/$(am__dirstamp)
- @rm -f samples/sample4_unittest$(EXEEXT)
- $(CXXLINK) $(samples_sample4_unittest_OBJECTS) $(samples_sample4_unittest_LDADD) $(LIBS)
-samples/sample5_unittest.$(OBJEXT): samples/$(am__dirstamp) \
- samples/$(DEPDIR)/$(am__dirstamp)
-samples/sample5_unittest$(EXEEXT): $(samples_sample5_unittest_OBJECTS) $(samples_sample5_unittest_DEPENDENCIES) $(EXTRA_samples_sample5_unittest_DEPENDENCIES) samples/$(am__dirstamp)
- @rm -f samples/sample5_unittest$(EXEEXT)
- $(CXXLINK) $(samples_sample5_unittest_OBJECTS) $(samples_sample5_unittest_LDADD) $(LIBS)
-samples/sample6_unittest.$(OBJEXT): samples/$(am__dirstamp) \
- samples/$(DEPDIR)/$(am__dirstamp)
-samples/sample6_unittest$(EXEEXT): $(samples_sample6_unittest_OBJECTS) $(samples_sample6_unittest_DEPENDENCIES) $(EXTRA_samples_sample6_unittest_DEPENDENCIES) samples/$(am__dirstamp)
- @rm -f samples/sample6_unittest$(EXEEXT)
- $(CXXLINK) $(samples_sample6_unittest_OBJECTS) $(samples_sample6_unittest_LDADD) $(LIBS)
-samples/sample7_unittest.$(OBJEXT): samples/$(am__dirstamp) \
- samples/$(DEPDIR)/$(am__dirstamp)
-samples/sample7_unittest$(EXEEXT): $(samples_sample7_unittest_OBJECTS) $(samples_sample7_unittest_DEPENDENCIES) $(EXTRA_samples_sample7_unittest_DEPENDENCIES) samples/$(am__dirstamp)
- @rm -f samples/sample7_unittest$(EXEEXT)
- $(CXXLINK) $(samples_sample7_unittest_OBJECTS) $(samples_sample7_unittest_LDADD) $(LIBS)
-samples/sample8_unittest.$(OBJEXT): samples/$(am__dirstamp) \
- samples/$(DEPDIR)/$(am__dirstamp)
-samples/sample8_unittest$(EXEEXT): $(samples_sample8_unittest_OBJECTS) $(samples_sample8_unittest_DEPENDENCIES) $(EXTRA_samples_sample8_unittest_DEPENDENCIES) samples/$(am__dirstamp)
- @rm -f samples/sample8_unittest$(EXEEXT)
- $(CXXLINK) $(samples_sample8_unittest_OBJECTS) $(samples_sample8_unittest_LDADD) $(LIBS)
-samples/sample9_unittest.$(OBJEXT): samples/$(am__dirstamp) \
- samples/$(DEPDIR)/$(am__dirstamp)
-samples/sample9_unittest$(EXEEXT): $(samples_sample9_unittest_OBJECTS) $(samples_sample9_unittest_DEPENDENCIES) $(EXTRA_samples_sample9_unittest_DEPENDENCIES) samples/$(am__dirstamp)
- @rm -f samples/sample9_unittest$(EXEEXT)
- $(CXXLINK) $(samples_sample9_unittest_OBJECTS) $(samples_sample9_unittest_LDADD) $(LIBS)
+ $(AM_V_CXXLD)$(CXXLINK) $(samples_sample1_unittest_OBJECTS) $(samples_sample1_unittest_LDADD) $(LIBS)
+fused-src/gtest/$(am__dirstamp):
+ @$(MKDIR_P) fused-src/gtest
+ @: > fused-src/gtest/$(am__dirstamp)
+fused-src/gtest/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) fused-src/gtest/$(DEPDIR)
+ @: > fused-src/gtest/$(DEPDIR)/$(am__dirstamp)
+fused-src/gtest/test_fused_gtest_test-gtest-all.$(OBJEXT): \
+ fused-src/gtest/$(am__dirstamp) \
+ fused-src/gtest/$(DEPDIR)/$(am__dirstamp)
+fused-src/gtest/test_fused_gtest_test-gtest_main.$(OBJEXT): \
+ fused-src/gtest/$(am__dirstamp) \
+ fused-src/gtest/$(DEPDIR)/$(am__dirstamp)
+samples/test_fused_gtest_test-sample1.$(OBJEXT): \
+ samples/$(am__dirstamp) samples/$(DEPDIR)/$(am__dirstamp)
+samples/test_fused_gtest_test-sample1_unittest.$(OBJEXT): \
+ samples/$(am__dirstamp) samples/$(DEPDIR)/$(am__dirstamp)
test/$(am__dirstamp):
@$(MKDIR_P) test
@: > test/$(am__dirstamp)
+
+test/fused_gtest_test$(EXEEXT): $(test_fused_gtest_test_OBJECTS) $(test_fused_gtest_test_DEPENDENCIES) $(EXTRA_test_fused_gtest_test_DEPENDENCIES) test/$(am__dirstamp)
+ @rm -f test/fused_gtest_test$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_fused_gtest_test_OBJECTS) $(test_fused_gtest_test_LDADD) $(LIBS)
test/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) test/$(DEPDIR)
@: > test/$(DEPDIR)/$(am__dirstamp)
-test/test_gtest_death_test_test-gtest-death-test_test.$(OBJEXT): \
- test/$(am__dirstamp) test/$(DEPDIR)/$(am__dirstamp)
-test/gtest-death-test_test$(EXEEXT): $(test_gtest_death_test_test_OBJECTS) $(test_gtest_death_test_test_DEPENDENCIES) $(EXTRA_test_gtest_death_test_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest-death-test_test$(EXEEXT)
- $(test_gtest_death_test_test_LINK) $(test_gtest_death_test_test_OBJECTS) $(test_gtest_death_test_test_LDADD) $(LIBS)
-test/gtest-filepath_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest-filepath_test$(EXEEXT): $(test_gtest_filepath_test_OBJECTS) $(test_gtest_filepath_test_DEPENDENCIES) $(EXTRA_test_gtest_filepath_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest-filepath_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_filepath_test_OBJECTS) $(test_gtest_filepath_test_LDADD) $(LIBS)
-test/gtest-linked_ptr_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest-linked_ptr_test$(EXEEXT): $(test_gtest_linked_ptr_test_OBJECTS) $(test_gtest_linked_ptr_test_DEPENDENCIES) $(EXTRA_test_gtest_linked_ptr_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest-linked_ptr_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_linked_ptr_test_OBJECTS) $(test_gtest_linked_ptr_test_LDADD) $(LIBS)
-test/gtest-listener_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest-listener_test$(EXEEXT): $(test_gtest_listener_test_OBJECTS) $(test_gtest_listener_test_DEPENDENCIES) $(EXTRA_test_gtest_listener_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest-listener_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_listener_test_OBJECTS) $(test_gtest_listener_test_LDADD) $(LIBS)
-test/gtest-message_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest-message_test$(EXEEXT): $(test_gtest_message_test_OBJECTS) $(test_gtest_message_test_DEPENDENCIES) $(EXTRA_test_gtest_message_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest-message_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_message_test_OBJECTS) $(test_gtest_message_test_LDADD) $(LIBS)
-test/gtest-options_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest-options_test$(EXEEXT): $(test_gtest_options_test_OBJECTS) $(test_gtest_options_test_DEPENDENCIES) $(EXTRA_test_gtest_options_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest-options_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_options_test_OBJECTS) $(test_gtest_options_test_LDADD) $(LIBS)
-test/gtest-param-test_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest-param-test2_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest-param-test_test$(EXEEXT): $(test_gtest_param_test_test_OBJECTS) $(test_gtest_param_test_test_DEPENDENCIES) $(EXTRA_test_gtest_param_test_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest-param-test_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_param_test_test_OBJECTS) $(test_gtest_param_test_test_LDADD) $(LIBS)
-test/gtest-port_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest-port_test$(EXEEXT): $(test_gtest_port_test_OBJECTS) $(test_gtest_port_test_DEPENDENCIES) $(EXTRA_test_gtest_port_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest-port_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_port_test_OBJECTS) $(test_gtest_port_test_LDADD) $(LIBS)
-test/gtest-test-part_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest-test-part_test$(EXEEXT): $(test_gtest_test_part_test_OBJECTS) $(test_gtest_test_part_test_DEPENDENCIES) $(EXTRA_test_gtest_test_part_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest-test-part_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_test_part_test_OBJECTS) $(test_gtest_test_part_test_LDADD) $(LIBS)
-test/test_gtest_tuple_test-gtest-tuple_test.$(OBJEXT): \
- test/$(am__dirstamp) test/$(DEPDIR)/$(am__dirstamp)
-src/test_gtest_tuple_test-gtest-all.$(OBJEXT): src/$(am__dirstamp) \
- src/$(DEPDIR)/$(am__dirstamp)
-src/test_gtest_tuple_test-gtest_main.$(OBJEXT): src/$(am__dirstamp) \
- src/$(DEPDIR)/$(am__dirstamp)
-test/gtest-tuple_test$(EXEEXT): $(test_gtest_tuple_test_OBJECTS) $(test_gtest_tuple_test_DEPENDENCIES) $(EXTRA_test_gtest_tuple_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest-tuple_test$(EXEEXT)
- $(test_gtest_tuple_test_LINK) $(test_gtest_tuple_test_OBJECTS) $(test_gtest_tuple_test_LDADD) $(LIBS)
-test/gtest-typed-test_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest-typed-test2_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest-typed-test_test$(EXEEXT): $(test_gtest_typed_test_test_OBJECTS) $(test_gtest_typed_test_test_DEPENDENCIES) $(EXTRA_test_gtest_typed_test_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest-typed-test_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_typed_test_test_OBJECTS) $(test_gtest_typed_test_test_LDADD) $(LIBS)
-test/gtest-unittest-api_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest-unittest-api_test$(EXEEXT): $(test_gtest_unittest_api_test_OBJECTS) $(test_gtest_unittest_api_test_DEPENDENCIES) $(EXTRA_test_gtest_unittest_api_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest-unittest-api_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_unittest_api_test_OBJECTS) $(test_gtest_unittest_api_test_LDADD) $(LIBS)
-test/gtest_break_on_failure_unittest_.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_break_on_failure_unittest_$(EXEEXT): $(test_gtest_break_on_failure_unittest__OBJECTS) $(test_gtest_break_on_failure_unittest__DEPENDENCIES) $(EXTRA_test_gtest_break_on_failure_unittest__DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_break_on_failure_unittest_$(EXEEXT)
- $(CXXLINK) $(test_gtest_break_on_failure_unittest__OBJECTS) $(test_gtest_break_on_failure_unittest__LDADD) $(LIBS)
-test/gtest_color_test_.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_color_test_$(EXEEXT): $(test_gtest_color_test__OBJECTS) $(test_gtest_color_test__DEPENDENCIES) $(EXTRA_test_gtest_color_test__DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_color_test_$(EXEEXT)
- $(CXXLINK) $(test_gtest_color_test__OBJECTS) $(test_gtest_color_test__LDADD) $(LIBS)
-test/gtest_env_var_test_.$(OBJEXT): test/$(am__dirstamp) \
+test/gtest_all_test.$(OBJEXT): test/$(am__dirstamp) \
test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_env_var_test_$(EXEEXT): $(test_gtest_env_var_test__OBJECTS) $(test_gtest_env_var_test__DEPENDENCIES) $(EXTRA_test_gtest_env_var_test__DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_env_var_test_$(EXEEXT)
- $(CXXLINK) $(test_gtest_env_var_test__OBJECTS) $(test_gtest_env_var_test__LDADD) $(LIBS)
-test/gtest_environment_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_environment_test$(EXEEXT): $(test_gtest_environment_test_OBJECTS) $(test_gtest_environment_test_DEPENDENCIES) $(EXTRA_test_gtest_environment_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_environment_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_environment_test_OBJECTS) $(test_gtest_environment_test_LDADD) $(LIBS)
-test/gtest_filter_unittest_.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_filter_unittest_$(EXEEXT): $(test_gtest_filter_unittest__OBJECTS) $(test_gtest_filter_unittest__DEPENDENCIES) $(EXTRA_test_gtest_filter_unittest__DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_filter_unittest_$(EXEEXT)
- $(CXXLINK) $(test_gtest_filter_unittest__OBJECTS) $(test_gtest_filter_unittest__LDADD) $(LIBS)
-test/gtest_help_test_.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_help_test_$(EXEEXT): $(test_gtest_help_test__OBJECTS) $(test_gtest_help_test__DEPENDENCIES) $(EXTRA_test_gtest_help_test__DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_help_test_$(EXEEXT)
- $(CXXLINK) $(test_gtest_help_test__OBJECTS) $(test_gtest_help_test__LDADD) $(LIBS)
-test/gtest_list_tests_unittest_.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_list_tests_unittest_$(EXEEXT): $(test_gtest_list_tests_unittest__OBJECTS) $(test_gtest_list_tests_unittest__DEPENDENCIES) $(EXTRA_test_gtest_list_tests_unittest__DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_list_tests_unittest_$(EXEEXT)
- $(CXXLINK) $(test_gtest_list_tests_unittest__OBJECTS) $(test_gtest_list_tests_unittest__LDADD) $(LIBS)
-test/gtest_main_unittest.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_main_unittest$(EXEEXT): $(test_gtest_main_unittest_OBJECTS) $(test_gtest_main_unittest_DEPENDENCIES) $(EXTRA_test_gtest_main_unittest_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_main_unittest$(EXEEXT)
- $(CXXLINK) $(test_gtest_main_unittest_OBJECTS) $(test_gtest_main_unittest_LDADD) $(LIBS)
-test/test_gtest_no_rtti_test-gtest_unittest.$(OBJEXT): \
- test/$(am__dirstamp) test/$(DEPDIR)/$(am__dirstamp)
-src/test_gtest_no_rtti_test-gtest-all.$(OBJEXT): src/$(am__dirstamp) \
- src/$(DEPDIR)/$(am__dirstamp)
-src/test_gtest_no_rtti_test-gtest_main.$(OBJEXT): src/$(am__dirstamp) \
- src/$(DEPDIR)/$(am__dirstamp)
-test/gtest_no_rtti_test$(EXEEXT): $(test_gtest_no_rtti_test_OBJECTS) $(test_gtest_no_rtti_test_DEPENDENCIES) $(EXTRA_test_gtest_no_rtti_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_no_rtti_test$(EXEEXT)
- $(test_gtest_no_rtti_test_LINK) $(test_gtest_no_rtti_test_OBJECTS) $(test_gtest_no_rtti_test_LDADD) $(LIBS)
-test/gtest_no_test_unittest.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_no_test_unittest$(EXEEXT): $(test_gtest_no_test_unittest_OBJECTS) $(test_gtest_no_test_unittest_DEPENDENCIES) $(EXTRA_test_gtest_no_test_unittest_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_no_test_unittest$(EXEEXT)
- $(CXXLINK) $(test_gtest_no_test_unittest_OBJECTS) $(test_gtest_no_test_unittest_LDADD) $(LIBS)
-test/gtest_output_test_.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_output_test_$(EXEEXT): $(test_gtest_output_test__OBJECTS) $(test_gtest_output_test__DEPENDENCIES) $(EXTRA_test_gtest_output_test__DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_output_test_$(EXEEXT)
- $(CXXLINK) $(test_gtest_output_test__OBJECTS) $(test_gtest_output_test__LDADD) $(LIBS)
-test/gtest_pred_impl_unittest.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_pred_impl_unittest$(EXEEXT): $(test_gtest_pred_impl_unittest_OBJECTS) $(test_gtest_pred_impl_unittest_DEPENDENCIES) $(EXTRA_test_gtest_pred_impl_unittest_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_pred_impl_unittest$(EXEEXT)
- $(CXXLINK) $(test_gtest_pred_impl_unittest_OBJECTS) $(test_gtest_pred_impl_unittest_LDADD) $(LIBS)
-test/gtest_prod_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/production.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_prod_test$(EXEEXT): $(test_gtest_prod_test_OBJECTS) $(test_gtest_prod_test_DEPENDENCIES) $(EXTRA_test_gtest_prod_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_prod_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_prod_test_OBJECTS) $(test_gtest_prod_test_LDADD) $(LIBS)
-test/gtest_repeat_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_repeat_test$(EXEEXT): $(test_gtest_repeat_test_OBJECTS) $(test_gtest_repeat_test_DEPENDENCIES) $(EXTRA_test_gtest_repeat_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_repeat_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_repeat_test_OBJECTS) $(test_gtest_repeat_test_LDADD) $(LIBS)
-test/gtest_shuffle_test_.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_shuffle_test_$(EXEEXT): $(test_gtest_shuffle_test__OBJECTS) $(test_gtest_shuffle_test__DEPENDENCIES) $(EXTRA_test_gtest_shuffle_test__DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_shuffle_test_$(EXEEXT)
- $(CXXLINK) $(test_gtest_shuffle_test__OBJECTS) $(test_gtest_shuffle_test__LDADD) $(LIBS)
-test/gtest_sole_header_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_sole_header_test$(EXEEXT): $(test_gtest_sole_header_test_OBJECTS) $(test_gtest_sole_header_test_DEPENDENCIES) $(EXTRA_test_gtest_sole_header_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_sole_header_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_sole_header_test_OBJECTS) $(test_gtest_sole_header_test_LDADD) $(LIBS)
-test/gtest_stress_test.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_stress_test$(EXEEXT): $(test_gtest_stress_test_OBJECTS) $(test_gtest_stress_test_DEPENDENCIES) $(EXTRA_test_gtest_stress_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_stress_test$(EXEEXT)
- $(CXXLINK) $(test_gtest_stress_test_OBJECTS) $(test_gtest_stress_test_LDADD) $(LIBS)
-test/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.$(OBJEXT): \
- test/$(am__dirstamp) test/$(DEPDIR)/$(am__dirstamp)
-src/test_gtest_throw_on_failure_ex_test-gtest-all.$(OBJEXT): \
- src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
-test/gtest_throw_on_failure_ex_test$(EXEEXT): $(test_gtest_throw_on_failure_ex_test_OBJECTS) $(test_gtest_throw_on_failure_ex_test_DEPENDENCIES) $(EXTRA_test_gtest_throw_on_failure_ex_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_throw_on_failure_ex_test$(EXEEXT)
- $(test_gtest_throw_on_failure_ex_test_LINK) $(test_gtest_throw_on_failure_ex_test_OBJECTS) $(test_gtest_throw_on_failure_ex_test_LDADD) $(LIBS)
-test/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.$(OBJEXT): \
- test/$(am__dirstamp) test/$(DEPDIR)/$(am__dirstamp)
-src/test_gtest_throw_on_failure_test_-gtest-all.$(OBJEXT): \
- src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
-test/gtest_throw_on_failure_test_$(EXEEXT): $(test_gtest_throw_on_failure_test__OBJECTS) $(test_gtest_throw_on_failure_test__DEPENDENCIES) $(EXTRA_test_gtest_throw_on_failure_test__DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_throw_on_failure_test_$(EXEEXT)
- $(test_gtest_throw_on_failure_test__LINK) $(test_gtest_throw_on_failure_test__OBJECTS) $(test_gtest_throw_on_failure_test__LDADD) $(LIBS)
-test/gtest_uninitialized_test_.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_uninitialized_test_$(EXEEXT): $(test_gtest_uninitialized_test__OBJECTS) $(test_gtest_uninitialized_test__DEPENDENCIES) $(EXTRA_test_gtest_uninitialized_test__DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_uninitialized_test_$(EXEEXT)
- $(CXXLINK) $(test_gtest_uninitialized_test__OBJECTS) $(test_gtest_uninitialized_test__LDADD) $(LIBS)
-test/gtest_unittest.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_unittest$(EXEEXT): $(test_gtest_unittest_OBJECTS) $(test_gtest_unittest_DEPENDENCIES) $(EXTRA_test_gtest_unittest_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_unittest$(EXEEXT)
- $(CXXLINK) $(test_gtest_unittest_OBJECTS) $(test_gtest_unittest_LDADD) $(LIBS)
-test/test_gtest_use_own_tuple_test-gtest-param-test_test.$(OBJEXT): \
- test/$(am__dirstamp) test/$(DEPDIR)/$(am__dirstamp)
-test/test_gtest_use_own_tuple_test-gtest-param-test2_test.$(OBJEXT): \
- test/$(am__dirstamp) test/$(DEPDIR)/$(am__dirstamp)
-src/test_gtest_use_own_tuple_test-gtest-all.$(OBJEXT): \
- src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
-test/gtest_use_own_tuple_test$(EXEEXT): $(test_gtest_use_own_tuple_test_OBJECTS) $(test_gtest_use_own_tuple_test_DEPENDENCIES) $(EXTRA_test_gtest_use_own_tuple_test_DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_use_own_tuple_test$(EXEEXT)
- $(test_gtest_use_own_tuple_test_LINK) $(test_gtest_use_own_tuple_test_OBJECTS) $(test_gtest_use_own_tuple_test_LDADD) $(LIBS)
-test/gtest_xml_outfile1_test_.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_xml_outfile1_test_$(EXEEXT): $(test_gtest_xml_outfile1_test__OBJECTS) $(test_gtest_xml_outfile1_test__DEPENDENCIES) $(EXTRA_test_gtest_xml_outfile1_test__DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_xml_outfile1_test_$(EXEEXT)
- $(CXXLINK) $(test_gtest_xml_outfile1_test__OBJECTS) $(test_gtest_xml_outfile1_test__LDADD) $(LIBS)
-test/gtest_xml_outfile2_test_.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_xml_outfile2_test_$(EXEEXT): $(test_gtest_xml_outfile2_test__OBJECTS) $(test_gtest_xml_outfile2_test__DEPENDENCIES) $(EXTRA_test_gtest_xml_outfile2_test__DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_xml_outfile2_test_$(EXEEXT)
- $(CXXLINK) $(test_gtest_xml_outfile2_test__OBJECTS) $(test_gtest_xml_outfile2_test__LDADD) $(LIBS)
-test/gtest_xml_output_unittest_.$(OBJEXT): test/$(am__dirstamp) \
- test/$(DEPDIR)/$(am__dirstamp)
-test/gtest_xml_output_unittest_$(EXEEXT): $(test_gtest_xml_output_unittest__OBJECTS) $(test_gtest_xml_output_unittest__DEPENDENCIES) $(EXTRA_test_gtest_xml_output_unittest__DEPENDENCIES) test/$(am__dirstamp)
- @rm -f test/gtest_xml_output_unittest_$(EXEEXT)
- $(CXXLINK) $(test_gtest_xml_output_unittest__OBJECTS) $(test_gtest_xml_output_unittest__LDADD) $(LIBS)
+
+test/gtest_all_test$(EXEEXT): $(test_gtest_all_test_OBJECTS) $(test_gtest_all_test_DEPENDENCIES) $(EXTRA_test_gtest_all_test_DEPENDENCIES) test/$(am__dirstamp)
+ @rm -f test/gtest_all_test$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_gtest_all_test_OBJECTS) $(test_gtest_all_test_LDADD) $(LIBS)
install-binSCRIPTS: $(bin_SCRIPTS)
@$(NORMAL_INSTALL)
- test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
@@ -1496,376 +1008,108 @@ uninstall-binSCRIPTS:
mostlyclean-compile:
-rm -f *.$(OBJEXT)
- -rm -f samples/sample1.$(OBJEXT)
- -rm -f samples/sample1.lo
- -rm -f samples/sample10_unittest.$(OBJEXT)
- -rm -f samples/sample1_unittest.$(OBJEXT)
- -rm -f samples/sample2.$(OBJEXT)
- -rm -f samples/sample2.lo
- -rm -f samples/sample2_unittest.$(OBJEXT)
- -rm -f samples/sample3_unittest.$(OBJEXT)
- -rm -f samples/sample4.$(OBJEXT)
- -rm -f samples/sample4.lo
- -rm -f samples/sample4_unittest.$(OBJEXT)
- -rm -f samples/sample5_unittest.$(OBJEXT)
- -rm -f samples/sample6_unittest.$(OBJEXT)
- -rm -f samples/sample7_unittest.$(OBJEXT)
- -rm -f samples/sample8_unittest.$(OBJEXT)
- -rm -f samples/sample9_unittest.$(OBJEXT)
- -rm -f src/gtest-death-test.$(OBJEXT)
- -rm -f src/gtest-death-test.lo
- -rm -f src/gtest-filepath.$(OBJEXT)
- -rm -f src/gtest-filepath.lo
- -rm -f src/gtest-port.$(OBJEXT)
- -rm -f src/gtest-port.lo
- -rm -f src/gtest-test-part.$(OBJEXT)
- -rm -f src/gtest-test-part.lo
- -rm -f src/gtest-typed-test.$(OBJEXT)
- -rm -f src/gtest-typed-test.lo
- -rm -f src/gtest.$(OBJEXT)
- -rm -f src/gtest.lo
- -rm -f src/gtest_main.$(OBJEXT)
- -rm -f src/gtest_main.lo
- -rm -f src/test_gtest_no_rtti_test-gtest-all.$(OBJEXT)
- -rm -f src/test_gtest_no_rtti_test-gtest_main.$(OBJEXT)
- -rm -f src/test_gtest_throw_on_failure_ex_test-gtest-all.$(OBJEXT)
- -rm -f src/test_gtest_throw_on_failure_test_-gtest-all.$(OBJEXT)
- -rm -f src/test_gtest_tuple_test-gtest-all.$(OBJEXT)
- -rm -f src/test_gtest_tuple_test-gtest_main.$(OBJEXT)
- -rm -f src/test_gtest_use_own_tuple_test-gtest-all.$(OBJEXT)
- -rm -f test/gtest-filepath_test.$(OBJEXT)
- -rm -f test/gtest-linked_ptr_test.$(OBJEXT)
- -rm -f test/gtest-listener_test.$(OBJEXT)
- -rm -f test/gtest-message_test.$(OBJEXT)
- -rm -f test/gtest-options_test.$(OBJEXT)
- -rm -f test/gtest-param-test2_test.$(OBJEXT)
- -rm -f test/gtest-param-test_test.$(OBJEXT)
- -rm -f test/gtest-port_test.$(OBJEXT)
- -rm -f test/gtest-test-part_test.$(OBJEXT)
- -rm -f test/gtest-typed-test2_test.$(OBJEXT)
- -rm -f test/gtest-typed-test_test.$(OBJEXT)
- -rm -f test/gtest-unittest-api_test.$(OBJEXT)
- -rm -f test/gtest_break_on_failure_unittest_.$(OBJEXT)
- -rm -f test/gtest_color_test_.$(OBJEXT)
- -rm -f test/gtest_env_var_test_.$(OBJEXT)
- -rm -f test/gtest_environment_test.$(OBJEXT)
- -rm -f test/gtest_filter_unittest_.$(OBJEXT)
- -rm -f test/gtest_help_test_.$(OBJEXT)
- -rm -f test/gtest_list_tests_unittest_.$(OBJEXT)
- -rm -f test/gtest_main_unittest.$(OBJEXT)
- -rm -f test/gtest_no_test_unittest.$(OBJEXT)
- -rm -f test/gtest_output_test_.$(OBJEXT)
- -rm -f test/gtest_pred_impl_unittest.$(OBJEXT)
- -rm -f test/gtest_prod_test.$(OBJEXT)
- -rm -f test/gtest_repeat_test.$(OBJEXT)
- -rm -f test/gtest_shuffle_test_.$(OBJEXT)
- -rm -f test/gtest_sole_header_test.$(OBJEXT)
- -rm -f test/gtest_stress_test.$(OBJEXT)
- -rm -f test/gtest_uninitialized_test_.$(OBJEXT)
- -rm -f test/gtest_unittest.$(OBJEXT)
- -rm -f test/gtest_xml_outfile1_test_.$(OBJEXT)
- -rm -f test/gtest_xml_outfile2_test_.$(OBJEXT)
- -rm -f test/gtest_xml_output_unittest_.$(OBJEXT)
- -rm -f test/production.$(OBJEXT)
- -rm -f test/test_gtest_death_test_test-gtest-death-test_test.$(OBJEXT)
- -rm -f test/test_gtest_no_rtti_test-gtest_unittest.$(OBJEXT)
- -rm -f test/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.$(OBJEXT)
- -rm -f test/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.$(OBJEXT)
- -rm -f test/test_gtest_tuple_test-gtest-tuple_test.$(OBJEXT)
- -rm -f test/test_gtest_use_own_tuple_test-gtest-param-test2_test.$(OBJEXT)
- -rm -f test/test_gtest_use_own_tuple_test-gtest-param-test_test.$(OBJEXT)
+ -rm -f fused-src/gtest/*.$(OBJEXT)
+ -rm -f samples/*.$(OBJEXT)
+ -rm -f samples/*.lo
+ -rm -f src/*.$(OBJEXT)
+ -rm -f src/*.lo
+ -rm -f test/*.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample1.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample10_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample1_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample2.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample2_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample3_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample4.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample4_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample5_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample6_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample7_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample8_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample9_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest-death-test.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest-filepath.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest-port.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest-test-part.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest-typed-test.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest-all.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest_main.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_gtest_no_rtti_test-gtest-all.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_gtest_no_rtti_test-gtest_main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest-all.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest-all.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_gtest_tuple_test-gtest-all.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_gtest_tuple_test-gtest_main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-all.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-filepath_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-linked_ptr_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-listener_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-message_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-options_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-param-test2_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-param-test_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-port_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-test-part_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-typed-test2_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-typed-test_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-unittest-api_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_break_on_failure_unittest_.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_color_test_.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_env_var_test_.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_environment_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_filter_unittest_.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_help_test_.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_list_tests_unittest_.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_main_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_no_test_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_output_test_.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_pred_impl_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_prod_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_repeat_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_shuffle_test_.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_sole_header_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_stress_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_uninitialized_test_.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_xml_outfile1_test_.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_xml_outfile2_test_.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_xml_output_unittest_.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/production.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_gtest_death_test_test-gtest-death-test_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_gtest_no_rtti_test-gtest_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_gtest_tuple_test-gtest-tuple_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test2_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test_test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_all_test.Po@am__quote@
.cc.o:
-@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cc.obj:
-@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cc.lo:
-@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
-test/test_gtest_death_test_test-gtest-death-test_test.o: test/gtest-death-test_test.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_death_test_test_CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_death_test_test-gtest-death-test_test.o -MD -MP -MF test/$(DEPDIR)/test_gtest_death_test_test-gtest-death-test_test.Tpo -c -o test/test_gtest_death_test_test-gtest-death-test_test.o `test -f 'test/gtest-death-test_test.cc' || echo '$(srcdir)/'`test/gtest-death-test_test.cc
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_death_test_test-gtest-death-test_test.Tpo test/$(DEPDIR)/test_gtest_death_test_test-gtest-death-test_test.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest-death-test_test.cc' object='test/test_gtest_death_test_test-gtest-death-test_test.o' libtool=no @AMDEPBACKSLASH@
+fused-src/gtest/test_fused_gtest_test-gtest-all.o: fused-src/gtest/gtest-all.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest-all.o -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.o `test -f 'fused-src/gtest/gtest-all.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest-all.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fused-src/gtest/gtest-all.cc' object='fused-src/gtest/test_fused_gtest_test-gtest-all.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_death_test_test_CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_death_test_test-gtest-death-test_test.o `test -f 'test/gtest-death-test_test.cc' || echo '$(srcdir)/'`test/gtest-death-test_test.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.o `test -f 'fused-src/gtest/gtest-all.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest-all.cc
-test/test_gtest_death_test_test-gtest-death-test_test.obj: test/gtest-death-test_test.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_death_test_test_CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_death_test_test-gtest-death-test_test.obj -MD -MP -MF test/$(DEPDIR)/test_gtest_death_test_test-gtest-death-test_test.Tpo -c -o test/test_gtest_death_test_test-gtest-death-test_test.obj `if test -f 'test/gtest-death-test_test.cc'; then $(CYGPATH_W) 'test/gtest-death-test_test.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest-death-test_test.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_death_test_test-gtest-death-test_test.Tpo test/$(DEPDIR)/test_gtest_death_test_test-gtest-death-test_test.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest-death-test_test.cc' object='test/test_gtest_death_test_test-gtest-death-test_test.obj' libtool=no @AMDEPBACKSLASH@
+fused-src/gtest/test_fused_gtest_test-gtest-all.obj: fused-src/gtest/gtest-all.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest-all.obj -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.obj `if test -f 'fused-src/gtest/gtest-all.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest-all.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fused-src/gtest/gtest-all.cc' object='fused-src/gtest/test_fused_gtest_test-gtest-all.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_death_test_test_CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_death_test_test-gtest-death-test_test.obj `if test -f 'test/gtest-death-test_test.cc'; then $(CYGPATH_W) 'test/gtest-death-test_test.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest-death-test_test.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.obj `if test -f 'fused-src/gtest/gtest-all.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest-all.cc'; fi`
-test/test_gtest_tuple_test-gtest-tuple_test.o: test/gtest-tuple_test.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_tuple_test_CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_tuple_test-gtest-tuple_test.o -MD -MP -MF test/$(DEPDIR)/test_gtest_tuple_test-gtest-tuple_test.Tpo -c -o test/test_gtest_tuple_test-gtest-tuple_test.o `test -f 'test/gtest-tuple_test.cc' || echo '$(srcdir)/'`test/gtest-tuple_test.cc
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_tuple_test-gtest-tuple_test.Tpo test/$(DEPDIR)/test_gtest_tuple_test-gtest-tuple_test.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest-tuple_test.cc' object='test/test_gtest_tuple_test-gtest-tuple_test.o' libtool=no @AMDEPBACKSLASH@
+fused-src/gtest/test_fused_gtest_test-gtest_main.o: fused-src/gtest/gtest_main.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest_main.o -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.o `test -f 'fused-src/gtest/gtest_main.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest_main.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fused-src/gtest/gtest_main.cc' object='fused-src/gtest/test_fused_gtest_test-gtest_main.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_tuple_test_CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_tuple_test-gtest-tuple_test.o `test -f 'test/gtest-tuple_test.cc' || echo '$(srcdir)/'`test/gtest-tuple_test.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.o `test -f 'fused-src/gtest/gtest_main.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest_main.cc
-test/test_gtest_tuple_test-gtest-tuple_test.obj: test/gtest-tuple_test.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_tuple_test_CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_tuple_test-gtest-tuple_test.obj -MD -MP -MF test/$(DEPDIR)/test_gtest_tuple_test-gtest-tuple_test.Tpo -c -o test/test_gtest_tuple_test-gtest-tuple_test.obj `if test -f 'test/gtest-tuple_test.cc'; then $(CYGPATH_W) 'test/gtest-tuple_test.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest-tuple_test.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_tuple_test-gtest-tuple_test.Tpo test/$(DEPDIR)/test_gtest_tuple_test-gtest-tuple_test.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest-tuple_test.cc' object='test/test_gtest_tuple_test-gtest-tuple_test.obj' libtool=no @AMDEPBACKSLASH@
+fused-src/gtest/test_fused_gtest_test-gtest_main.obj: fused-src/gtest/gtest_main.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest_main.obj -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.obj `if test -f 'fused-src/gtest/gtest_main.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest_main.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fused-src/gtest/gtest_main.cc' object='fused-src/gtest/test_fused_gtest_test-gtest_main.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_tuple_test_CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_tuple_test-gtest-tuple_test.obj `if test -f 'test/gtest-tuple_test.cc'; then $(CYGPATH_W) 'test/gtest-tuple_test.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest-tuple_test.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.obj `if test -f 'fused-src/gtest/gtest_main.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest_main.cc'; fi`
-src/test_gtest_tuple_test-gtest-all.o: src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_tuple_test_CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_tuple_test-gtest-all.o -MD -MP -MF src/$(DEPDIR)/test_gtest_tuple_test-gtest-all.Tpo -c -o src/test_gtest_tuple_test-gtest-all.o `test -f 'src/gtest-all.cc' || echo '$(srcdir)/'`src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_tuple_test-gtest-all.Tpo src/$(DEPDIR)/test_gtest_tuple_test-gtest-all.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest-all.cc' object='src/test_gtest_tuple_test-gtest-all.o' libtool=no @AMDEPBACKSLASH@
+samples/test_fused_gtest_test-sample1.o: samples/sample1.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1.o -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo -c -o samples/test_fused_gtest_test-sample1.o `test -f 'samples/sample1.cc' || echo '$(srcdir)/'`samples/sample1.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='samples/sample1.cc' object='samples/test_fused_gtest_test-sample1.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_tuple_test_CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_tuple_test-gtest-all.o `test -f 'src/gtest-all.cc' || echo '$(srcdir)/'`src/gtest-all.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1.o `test -f 'samples/sample1.cc' || echo '$(srcdir)/'`samples/sample1.cc
-src/test_gtest_tuple_test-gtest-all.obj: src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_tuple_test_CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_tuple_test-gtest-all.obj -MD -MP -MF src/$(DEPDIR)/test_gtest_tuple_test-gtest-all.Tpo -c -o src/test_gtest_tuple_test-gtest-all.obj `if test -f 'src/gtest-all.cc'; then $(CYGPATH_W) 'src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest-all.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_tuple_test-gtest-all.Tpo src/$(DEPDIR)/test_gtest_tuple_test-gtest-all.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest-all.cc' object='src/test_gtest_tuple_test-gtest-all.obj' libtool=no @AMDEPBACKSLASH@
+samples/test_fused_gtest_test-sample1.obj: samples/sample1.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1.obj -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo -c -o samples/test_fused_gtest_test-sample1.obj `if test -f 'samples/sample1.cc'; then $(CYGPATH_W) 'samples/sample1.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='samples/sample1.cc' object='samples/test_fused_gtest_test-sample1.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_tuple_test_CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_tuple_test-gtest-all.obj `if test -f 'src/gtest-all.cc'; then $(CYGPATH_W) 'src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest-all.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1.obj `if test -f 'samples/sample1.cc'; then $(CYGPATH_W) 'samples/sample1.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1.cc'; fi`
-src/test_gtest_tuple_test-gtest_main.o: src/gtest_main.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_tuple_test_CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_tuple_test-gtest_main.o -MD -MP -MF src/$(DEPDIR)/test_gtest_tuple_test-gtest_main.Tpo -c -o src/test_gtest_tuple_test-gtest_main.o `test -f 'src/gtest_main.cc' || echo '$(srcdir)/'`src/gtest_main.cc
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_tuple_test-gtest_main.Tpo src/$(DEPDIR)/test_gtest_tuple_test-gtest_main.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest_main.cc' object='src/test_gtest_tuple_test-gtest_main.o' libtool=no @AMDEPBACKSLASH@
+samples/test_fused_gtest_test-sample1_unittest.o: samples/sample1_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1_unittest.o -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo -c -o samples/test_fused_gtest_test-sample1_unittest.o `test -f 'samples/sample1_unittest.cc' || echo '$(srcdir)/'`samples/sample1_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='samples/sample1_unittest.cc' object='samples/test_fused_gtest_test-sample1_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_tuple_test_CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_tuple_test-gtest_main.o `test -f 'src/gtest_main.cc' || echo '$(srcdir)/'`src/gtest_main.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1_unittest.o `test -f 'samples/sample1_unittest.cc' || echo '$(srcdir)/'`samples/sample1_unittest.cc
-src/test_gtest_tuple_test-gtest_main.obj: src/gtest_main.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_tuple_test_CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_tuple_test-gtest_main.obj -MD -MP -MF src/$(DEPDIR)/test_gtest_tuple_test-gtest_main.Tpo -c -o src/test_gtest_tuple_test-gtest_main.obj `if test -f 'src/gtest_main.cc'; then $(CYGPATH_W) 'src/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest_main.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_tuple_test-gtest_main.Tpo src/$(DEPDIR)/test_gtest_tuple_test-gtest_main.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest_main.cc' object='src/test_gtest_tuple_test-gtest_main.obj' libtool=no @AMDEPBACKSLASH@
+samples/test_fused_gtest_test-sample1_unittest.obj: samples/sample1_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1_unittest.obj -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo -c -o samples/test_fused_gtest_test-sample1_unittest.obj `if test -f 'samples/sample1_unittest.cc'; then $(CYGPATH_W) 'samples/sample1_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='samples/sample1_unittest.cc' object='samples/test_fused_gtest_test-sample1_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_tuple_test_CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_tuple_test-gtest_main.obj `if test -f 'src/gtest_main.cc'; then $(CYGPATH_W) 'src/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest_main.cc'; fi`
-
-test/test_gtest_no_rtti_test-gtest_unittest.o: test/gtest_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_no_rtti_test_CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_no_rtti_test-gtest_unittest.o -MD -MP -MF test/$(DEPDIR)/test_gtest_no_rtti_test-gtest_unittest.Tpo -c -o test/test_gtest_no_rtti_test-gtest_unittest.o `test -f 'test/gtest_unittest.cc' || echo '$(srcdir)/'`test/gtest_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_no_rtti_test-gtest_unittest.Tpo test/$(DEPDIR)/test_gtest_no_rtti_test-gtest_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest_unittest.cc' object='test/test_gtest_no_rtti_test-gtest_unittest.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_no_rtti_test_CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_no_rtti_test-gtest_unittest.o `test -f 'test/gtest_unittest.cc' || echo '$(srcdir)/'`test/gtest_unittest.cc
-
-test/test_gtest_no_rtti_test-gtest_unittest.obj: test/gtest_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_no_rtti_test_CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_no_rtti_test-gtest_unittest.obj -MD -MP -MF test/$(DEPDIR)/test_gtest_no_rtti_test-gtest_unittest.Tpo -c -o test/test_gtest_no_rtti_test-gtest_unittest.obj `if test -f 'test/gtest_unittest.cc'; then $(CYGPATH_W) 'test/gtest_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_no_rtti_test-gtest_unittest.Tpo test/$(DEPDIR)/test_gtest_no_rtti_test-gtest_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest_unittest.cc' object='test/test_gtest_no_rtti_test-gtest_unittest.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_no_rtti_test_CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_no_rtti_test-gtest_unittest.obj `if test -f 'test/gtest_unittest.cc'; then $(CYGPATH_W) 'test/gtest_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest_unittest.cc'; fi`
-
-src/test_gtest_no_rtti_test-gtest-all.o: src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_no_rtti_test_CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_no_rtti_test-gtest-all.o -MD -MP -MF src/$(DEPDIR)/test_gtest_no_rtti_test-gtest-all.Tpo -c -o src/test_gtest_no_rtti_test-gtest-all.o `test -f 'src/gtest-all.cc' || echo '$(srcdir)/'`src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_no_rtti_test-gtest-all.Tpo src/$(DEPDIR)/test_gtest_no_rtti_test-gtest-all.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest-all.cc' object='src/test_gtest_no_rtti_test-gtest-all.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_no_rtti_test_CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_no_rtti_test-gtest-all.o `test -f 'src/gtest-all.cc' || echo '$(srcdir)/'`src/gtest-all.cc
-
-src/test_gtest_no_rtti_test-gtest-all.obj: src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_no_rtti_test_CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_no_rtti_test-gtest-all.obj -MD -MP -MF src/$(DEPDIR)/test_gtest_no_rtti_test-gtest-all.Tpo -c -o src/test_gtest_no_rtti_test-gtest-all.obj `if test -f 'src/gtest-all.cc'; then $(CYGPATH_W) 'src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest-all.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_no_rtti_test-gtest-all.Tpo src/$(DEPDIR)/test_gtest_no_rtti_test-gtest-all.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest-all.cc' object='src/test_gtest_no_rtti_test-gtest-all.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_no_rtti_test_CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_no_rtti_test-gtest-all.obj `if test -f 'src/gtest-all.cc'; then $(CYGPATH_W) 'src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest-all.cc'; fi`
-
-src/test_gtest_no_rtti_test-gtest_main.o: src/gtest_main.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_no_rtti_test_CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_no_rtti_test-gtest_main.o -MD -MP -MF src/$(DEPDIR)/test_gtest_no_rtti_test-gtest_main.Tpo -c -o src/test_gtest_no_rtti_test-gtest_main.o `test -f 'src/gtest_main.cc' || echo '$(srcdir)/'`src/gtest_main.cc
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_no_rtti_test-gtest_main.Tpo src/$(DEPDIR)/test_gtest_no_rtti_test-gtest_main.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest_main.cc' object='src/test_gtest_no_rtti_test-gtest_main.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_no_rtti_test_CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_no_rtti_test-gtest_main.o `test -f 'src/gtest_main.cc' || echo '$(srcdir)/'`src/gtest_main.cc
-
-src/test_gtest_no_rtti_test-gtest_main.obj: src/gtest_main.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_no_rtti_test_CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_no_rtti_test-gtest_main.obj -MD -MP -MF src/$(DEPDIR)/test_gtest_no_rtti_test-gtest_main.Tpo -c -o src/test_gtest_no_rtti_test-gtest_main.obj `if test -f 'src/gtest_main.cc'; then $(CYGPATH_W) 'src/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest_main.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_no_rtti_test-gtest_main.Tpo src/$(DEPDIR)/test_gtest_no_rtti_test-gtest_main.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest_main.cc' object='src/test_gtest_no_rtti_test-gtest_main.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_no_rtti_test_CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_no_rtti_test-gtest_main.obj `if test -f 'src/gtest_main.cc'; then $(CYGPATH_W) 'src/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest_main.cc'; fi`
-
-test/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.o: test/gtest_throw_on_failure_ex_test.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_ex_test_CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.o -MD -MP -MF test/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.Tpo -c -o test/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.o `test -f 'test/gtest_throw_on_failure_ex_test.cc' || echo '$(srcdir)/'`test/gtest_throw_on_failure_ex_test.cc
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.Tpo test/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest_throw_on_failure_ex_test.cc' object='test/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_ex_test_CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.o `test -f 'test/gtest_throw_on_failure_ex_test.cc' || echo '$(srcdir)/'`test/gtest_throw_on_failure_ex_test.cc
-
-test/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.obj: test/gtest_throw_on_failure_ex_test.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_ex_test_CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.obj -MD -MP -MF test/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.Tpo -c -o test/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.obj `if test -f 'test/gtest_throw_on_failure_ex_test.cc'; then $(CYGPATH_W) 'test/gtest_throw_on_failure_ex_test.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest_throw_on_failure_ex_test.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.Tpo test/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest_throw_on_failure_ex_test.cc' object='test/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_ex_test_CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_throw_on_failure_ex_test-gtest_throw_on_failure_ex_test.obj `if test -f 'test/gtest_throw_on_failure_ex_test.cc'; then $(CYGPATH_W) 'test/gtest_throw_on_failure_ex_test.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest_throw_on_failure_ex_test.cc'; fi`
-
-src/test_gtest_throw_on_failure_ex_test-gtest-all.o: src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_ex_test_CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_throw_on_failure_ex_test-gtest-all.o -MD -MP -MF src/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest-all.Tpo -c -o src/test_gtest_throw_on_failure_ex_test-gtest-all.o `test -f 'src/gtest-all.cc' || echo '$(srcdir)/'`src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest-all.Tpo src/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest-all.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest-all.cc' object='src/test_gtest_throw_on_failure_ex_test-gtest-all.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_ex_test_CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_throw_on_failure_ex_test-gtest-all.o `test -f 'src/gtest-all.cc' || echo '$(srcdir)/'`src/gtest-all.cc
-
-src/test_gtest_throw_on_failure_ex_test-gtest-all.obj: src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_ex_test_CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_throw_on_failure_ex_test-gtest-all.obj -MD -MP -MF src/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest-all.Tpo -c -o src/test_gtest_throw_on_failure_ex_test-gtest-all.obj `if test -f 'src/gtest-all.cc'; then $(CYGPATH_W) 'src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest-all.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest-all.Tpo src/$(DEPDIR)/test_gtest_throw_on_failure_ex_test-gtest-all.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest-all.cc' object='src/test_gtest_throw_on_failure_ex_test-gtest-all.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_ex_test_CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_throw_on_failure_ex_test-gtest-all.obj `if test -f 'src/gtest-all.cc'; then $(CYGPATH_W) 'src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest-all.cc'; fi`
-
-test/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.o: test/gtest_throw_on_failure_test_.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_test__CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.o -MD -MP -MF test/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.Tpo -c -o test/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.o `test -f 'test/gtest_throw_on_failure_test_.cc' || echo '$(srcdir)/'`test/gtest_throw_on_failure_test_.cc
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.Tpo test/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest_throw_on_failure_test_.cc' object='test/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_test__CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.o `test -f 'test/gtest_throw_on_failure_test_.cc' || echo '$(srcdir)/'`test/gtest_throw_on_failure_test_.cc
-
-test/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.obj: test/gtest_throw_on_failure_test_.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_test__CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.obj -MD -MP -MF test/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.Tpo -c -o test/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.obj `if test -f 'test/gtest_throw_on_failure_test_.cc'; then $(CYGPATH_W) 'test/gtest_throw_on_failure_test_.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest_throw_on_failure_test_.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.Tpo test/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest_throw_on_failure_test_.cc' object='test/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_test__CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_throw_on_failure_test_-gtest_throw_on_failure_test_.obj `if test -f 'test/gtest_throw_on_failure_test_.cc'; then $(CYGPATH_W) 'test/gtest_throw_on_failure_test_.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest_throw_on_failure_test_.cc'; fi`
-
-src/test_gtest_throw_on_failure_test_-gtest-all.o: src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_test__CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_throw_on_failure_test_-gtest-all.o -MD -MP -MF src/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest-all.Tpo -c -o src/test_gtest_throw_on_failure_test_-gtest-all.o `test -f 'src/gtest-all.cc' || echo '$(srcdir)/'`src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest-all.Tpo src/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest-all.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest-all.cc' object='src/test_gtest_throw_on_failure_test_-gtest-all.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_test__CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_throw_on_failure_test_-gtest-all.o `test -f 'src/gtest-all.cc' || echo '$(srcdir)/'`src/gtest-all.cc
-
-src/test_gtest_throw_on_failure_test_-gtest-all.obj: src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_test__CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_throw_on_failure_test_-gtest-all.obj -MD -MP -MF src/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest-all.Tpo -c -o src/test_gtest_throw_on_failure_test_-gtest-all.obj `if test -f 'src/gtest-all.cc'; then $(CYGPATH_W) 'src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest-all.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest-all.Tpo src/$(DEPDIR)/test_gtest_throw_on_failure_test_-gtest-all.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest-all.cc' object='src/test_gtest_throw_on_failure_test_-gtest-all.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_throw_on_failure_test__CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_throw_on_failure_test_-gtest-all.obj `if test -f 'src/gtest-all.cc'; then $(CYGPATH_W) 'src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest-all.cc'; fi`
-
-test/test_gtest_use_own_tuple_test-gtest-param-test_test.o: test/gtest-param-test_test.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_use_own_tuple_test_CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_use_own_tuple_test-gtest-param-test_test.o -MD -MP -MF test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test_test.Tpo -c -o test/test_gtest_use_own_tuple_test-gtest-param-test_test.o `test -f 'test/gtest-param-test_test.cc' || echo '$(srcdir)/'`test/gtest-param-test_test.cc
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test_test.Tpo test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test_test.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest-param-test_test.cc' object='test/test_gtest_use_own_tuple_test-gtest-param-test_test.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_use_own_tuple_test_CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_use_own_tuple_test-gtest-param-test_test.o `test -f 'test/gtest-param-test_test.cc' || echo '$(srcdir)/'`test/gtest-param-test_test.cc
-
-test/test_gtest_use_own_tuple_test-gtest-param-test_test.obj: test/gtest-param-test_test.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_use_own_tuple_test_CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_use_own_tuple_test-gtest-param-test_test.obj -MD -MP -MF test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test_test.Tpo -c -o test/test_gtest_use_own_tuple_test-gtest-param-test_test.obj `if test -f 'test/gtest-param-test_test.cc'; then $(CYGPATH_W) 'test/gtest-param-test_test.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest-param-test_test.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test_test.Tpo test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test_test.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest-param-test_test.cc' object='test/test_gtest_use_own_tuple_test-gtest-param-test_test.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_use_own_tuple_test_CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_use_own_tuple_test-gtest-param-test_test.obj `if test -f 'test/gtest-param-test_test.cc'; then $(CYGPATH_W) 'test/gtest-param-test_test.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest-param-test_test.cc'; fi`
-
-test/test_gtest_use_own_tuple_test-gtest-param-test2_test.o: test/gtest-param-test2_test.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_use_own_tuple_test_CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_use_own_tuple_test-gtest-param-test2_test.o -MD -MP -MF test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test2_test.Tpo -c -o test/test_gtest_use_own_tuple_test-gtest-param-test2_test.o `test -f 'test/gtest-param-test2_test.cc' || echo '$(srcdir)/'`test/gtest-param-test2_test.cc
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test2_test.Tpo test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test2_test.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest-param-test2_test.cc' object='test/test_gtest_use_own_tuple_test-gtest-param-test2_test.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_use_own_tuple_test_CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_use_own_tuple_test-gtest-param-test2_test.o `test -f 'test/gtest-param-test2_test.cc' || echo '$(srcdir)/'`test/gtest-param-test2_test.cc
-
-test/test_gtest_use_own_tuple_test-gtest-param-test2_test.obj: test/gtest-param-test2_test.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_use_own_tuple_test_CXXFLAGS) $(CXXFLAGS) -MT test/test_gtest_use_own_tuple_test-gtest-param-test2_test.obj -MD -MP -MF test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test2_test.Tpo -c -o test/test_gtest_use_own_tuple_test-gtest-param-test2_test.obj `if test -f 'test/gtest-param-test2_test.cc'; then $(CYGPATH_W) 'test/gtest-param-test2_test.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest-param-test2_test.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test2_test.Tpo test/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-param-test2_test.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='test/gtest-param-test2_test.cc' object='test/test_gtest_use_own_tuple_test-gtest-param-test2_test.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_use_own_tuple_test_CXXFLAGS) $(CXXFLAGS) -c -o test/test_gtest_use_own_tuple_test-gtest-param-test2_test.obj `if test -f 'test/gtest-param-test2_test.cc'; then $(CYGPATH_W) 'test/gtest-param-test2_test.cc'; else $(CYGPATH_W) '$(srcdir)/test/gtest-param-test2_test.cc'; fi`
-
-src/test_gtest_use_own_tuple_test-gtest-all.o: src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_use_own_tuple_test_CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_use_own_tuple_test-gtest-all.o -MD -MP -MF src/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-all.Tpo -c -o src/test_gtest_use_own_tuple_test-gtest-all.o `test -f 'src/gtest-all.cc' || echo '$(srcdir)/'`src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-all.Tpo src/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-all.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest-all.cc' object='src/test_gtest_use_own_tuple_test-gtest-all.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_use_own_tuple_test_CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_use_own_tuple_test-gtest-all.o `test -f 'src/gtest-all.cc' || echo '$(srcdir)/'`src/gtest-all.cc
-
-src/test_gtest_use_own_tuple_test-gtest-all.obj: src/gtest-all.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_use_own_tuple_test_CXXFLAGS) $(CXXFLAGS) -MT src/test_gtest_use_own_tuple_test-gtest-all.obj -MD -MP -MF src/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-all.Tpo -c -o src/test_gtest_use_own_tuple_test-gtest-all.obj `if test -f 'src/gtest-all.cc'; then $(CYGPATH_W) 'src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest-all.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) src/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-all.Tpo src/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-all.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/gtest-all.cc' object='src/test_gtest_use_own_tuple_test-gtest-all.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gtest_use_own_tuple_test_CXXFLAGS) $(CXXFLAGS) -c -o src/test_gtest_use_own_tuple_test-gtest-all.obj `if test -f 'src/gtest-all.cc'; then $(CYGPATH_W) 'src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/gtest-all.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1_unittest.obj `if test -f 'samples/sample1_unittest.cc'; then $(CYGPATH_W) 'samples/sample1_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1_unittest.cc'; fi`
mostlyclean-libtool:
-rm -f *.lo
@@ -1881,8 +1125,11 @@ distclean-libtool:
-rm -f libtool config.lt
install-m4dataDATA: $(m4data_DATA)
@$(NORMAL_INSTALL)
- test -z "$(m4datadir)" || $(MKDIR_P) "$(DESTDIR)$(m4datadir)"
@list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(m4datadir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(m4datadir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -1899,8 +1146,11 @@ uninstall-m4dataDATA:
dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir)
install-pkgincludeHEADERS: $(pkginclude_HEADERS)
@$(NORMAL_INSTALL)
- test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)"
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -1917,8 +1167,11 @@ uninstall-pkgincludeHEADERS:
dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
install-pkginclude_internalHEADERS: $(pkginclude_internal_HEADERS)
@$(NORMAL_INSTALL)
- test -z "$(pkginclude_internaldir)" || $(MKDIR_P) "$(DESTDIR)$(pkginclude_internaldir)"
@list='$(pkginclude_internal_HEADERS)'; test -n "$(pkginclude_internaldir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkginclude_internaldir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkginclude_internaldir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -1934,26 +1187,15 @@ uninstall-pkginclude_internalHEADERS:
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkginclude_internaldir)'; $(am__uninstall_files_from_dir)
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ $(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
@@ -1965,15 +1207,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$$unique; \
fi; \
fi
-ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
@@ -1982,102 +1220,215 @@ GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+ test ! -s cscope.files \
+ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+ -rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+ -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
-check-TESTS: $(TESTS)
- @failed=0; all=0; xfail=0; xpass=0; skip=0; \
- srcdir=$(srcdir); export srcdir; \
- list=' $(TESTS) '; \
- $(am__tty_colors); \
- if test -n "$$list"; then \
- for tst in $$list; do \
- if test -f ./$$tst; then dir=./; \
- elif test -f $$tst; then dir=; \
- else dir="$(srcdir)/"; fi; \
- if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
- all=`expr $$all + 1`; \
- case " $(XFAIL_TESTS) " in \
- *[\ \ ]$$tst[\ \ ]*) \
- xpass=`expr $$xpass + 1`; \
- failed=`expr $$failed + 1`; \
- col=$$red; res=XPASS; \
- ;; \
- *) \
- col=$$grn; res=PASS; \
- ;; \
- esac; \
- elif test $$? -ne 77; then \
- all=`expr $$all + 1`; \
- case " $(XFAIL_TESTS) " in \
- *[\ \ ]$$tst[\ \ ]*) \
- xfail=`expr $$xfail + 1`; \
- col=$$lgn; res=XFAIL; \
- ;; \
- *) \
- failed=`expr $$failed + 1`; \
- col=$$red; res=FAIL; \
- ;; \
- esac; \
- else \
- skip=`expr $$skip + 1`; \
- col=$$blu; res=SKIP; \
- fi; \
- echo "$${col}$$res$${std}: $$tst"; \
- done; \
- if test "$$all" -eq 1; then \
- tests="test"; \
- All=""; \
- else \
- tests="tests"; \
- All="All "; \
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
fi; \
- if test "$$failed" -eq 0; then \
- if test "$$xfail" -eq 0; then \
- banner="$$All$$all $$tests passed"; \
- else \
- if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
- banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
- fi; \
- else \
- if test "$$xpass" -eq 0; then \
- banner="$$failed of $$all $$tests failed"; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ else \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
else \
- if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
- banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
fi; \
- fi; \
- dashes="$$banner"; \
- skipped=""; \
- if test "$$skip" -ne 0; then \
- if test "$$skip" -eq 1; then \
- skipped="($$skip test was not run)"; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
else \
- skipped="($$skip tests were not run)"; \
+ color_start= color_end=; \
fi; \
- test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
- dashes="$$skipped"; \
- fi; \
- report=""; \
- if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
- report="Please report to $(PACKAGE_BUGREPORT)"; \
- test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
- dashes="$$report"; \
- fi; \
- dashes=`echo "$$dashes" | sed s/./=/g`; \
- if test "$$failed" -eq 0; then \
- col="$$grn"; \
- else \
- col="$$red"; \
- fi; \
- echo "$${col}$$dashes$${std}"; \
- echo "$${col}$$banner$${std}"; \
- test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
- test -z "$$report" || echo "$${col}$$report$${std}"; \
- echo "$${col}$$dashes$${std}"; \
- test "$$failed" -eq 0; \
- else :; fi
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+samples/sample1_unittest.log: samples/sample1_unittest$(EXEEXT)
+ @p='samples/sample1_unittest$(EXEEXT)'; \
+ b='samples/sample1_unittest'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+samples/sample10_unittest.log: samples/sample10_unittest$(EXEEXT)
+ @p='samples/sample10_unittest$(EXEEXT)'; \
+ b='samples/sample10_unittest'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test/gtest_all_test.log: test/gtest_all_test$(EXEEXT)
+ @p='test/gtest_all_test$(EXEEXT)'; \
+ b='test/gtest_all_test'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test/fused_gtest_test.log: test/fused_gtest_test$(EXEEXT)
+ @p='test/fused_gtest_test$(EXEEXT)'; \
+ b='test/fused_gtest_test'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
distdir: $(DISTFILES)
$(am__remove_distdir)
@@ -2120,41 +1471,40 @@ distdir: $(DISTFILES)
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-lzip: distdir
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
- $(am__remove_distdir)
-
-dist-lzma: distdir
- tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-tarZ: distdir
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-shar: distdir
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
-dist dist-all: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
- -rm -f $(distdir).zip
- zip -rq $(distdir).zip $(distdir)
- $(am__remove_distdir)
+dist dist-all:
+ $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+ $(am__post_remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
@@ -2165,8 +1515,6 @@ distcheck: dist
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
- *.tar.lzma*) \
- lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.lz*) \
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \
@@ -2178,18 +1526,19 @@ distcheck: dist
*.zip*) \
unzip $(distdir).zip ;;\
esac
- chmod -R a-w $(distdir); chmod a+w $(distdir)
- mkdir $(distdir)/_build
- mkdir $(distdir)/_inst
+ chmod -R a-w $(distdir)
+ chmod u+w $(distdir)
+ mkdir $(distdir)/_build $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build \
- && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ && ../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
+ --srcdir=.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
@@ -2212,7 +1561,7 @@ distcheck: dist
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
- $(am__remove_distdir)
+ $(am__post_remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
@@ -2243,7 +1592,7 @@ distcleancheck: distclean
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
- $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(DATA) $(HEADERS)
@@ -2271,6 +1620,9 @@ install-strip:
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
@@ -2278,6 +1630,8 @@ clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -rm -f fused-src/gtest/$(DEPDIR)/$(am__dirstamp)
+ -rm -f fused-src/gtest/$(am__dirstamp)
-rm -f lib/$(am__dirstamp)
-rm -f samples/$(DEPDIR)/$(am__dirstamp)
-rm -f samples/$(am__dirstamp)
@@ -2296,7 +1650,7 @@ clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -rf samples/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR)
+ -rm -rf fused-src/gtest/$(DEPDIR) samples/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-libtool distclean-tags
@@ -2345,9 +1699,10 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
- -rm -rf samples/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR)
+ -rm -rf fused-src/gtest/$(DEPDIR) samples/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR)
-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
+maintainer-clean-am: distclean-am maintainer-clean-generic \
+ maintainer-clean-local
mostlyclean: mostlyclean-am
@@ -2368,29 +1723,48 @@ uninstall-am: uninstall-binSCRIPTS uninstall-libLTLIBRARIES \
.MAKE: check-am install-am install-strip
-.PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \
- clean clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \
- clean-libtool clean-noinstLTLIBRARIES ctags dist dist-all \
- dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar dist-tarZ \
- dist-xz dist-zip distcheck distclean distclean-compile \
- distclean-generic distclean-hdr distclean-libtool \
- distclean-tags distcleancheck distdir distuninstallcheck dvi \
- dvi-am html html-am info info-am install install-am \
- install-binSCRIPTS install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am \
- install-libLTLIBRARIES install-m4dataDATA install-man \
- install-pdf install-pdf-am install-pkgincludeHEADERS \
- install-pkginclude_internalHEADERS install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
+.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-cscope clean-generic \
+ clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \
+ cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
+ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
+ distcheck distclean distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags distcleancheck \
+ distdir distuninstallcheck dvi dvi-am html html-am info \
+ info-am install install-am install-binSCRIPTS install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-libLTLIBRARIES install-m4dataDATA \
+ install-man install-pdf install-pdf-am \
+ install-pkgincludeHEADERS install-pkginclude_internalHEADERS \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic maintainer-clean-local mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags uninstall uninstall-am \
- uninstall-binSCRIPTS uninstall-libLTLIBRARIES \
+ pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+ uninstall-am uninstall-binSCRIPTS uninstall-libLTLIBRARIES \
uninstall-m4dataDATA uninstall-pkgincludeHEADERS \
uninstall-pkginclude_internalHEADERS
+# Build rules for putting fused Google Test files into the distribution
+# package. The user can also create those files by manually running
+# scripts/fuse_gtest_files.py.
+$(test_fused_gtest_test_SOURCES): fused-gtest
+
+fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \
+ $(GTEST_SRC) src/gtest-all.cc src/gtest_main.cc \
+ scripts/fuse_gtest_files.py
+ mkdir -p "$(srcdir)/fused-src"
+ chmod -R u+w "$(srcdir)/fused-src"
+ rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc"
+ rm -f "$(srcdir)/fused-src/gtest/gtest.h"
+ "$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src"
+ cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest/"
+
+maintainer-clean-local:
+ rm -rf "$(srcdir)/fused-src"
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/gtest/README b/gtest/README
index a9172c5..ec61190 100644
--- a/gtest/README
+++ b/gtest/README
@@ -1,305 +1,396 @@
Google C++ Testing Framework
============================
+
http://code.google.com/p/googletest/
Overview
--------
-Google's framework for writing C++ tests on a variety of platforms (Linux, Mac
-OS X, Windows, Windows CE, Symbian, and etc). Based on the xUnit architecture.
-Supports automatic test discovery, a rich set of assertions, user-defined
-assertions, death tests, fatal and non-fatal failures, various options for
-running the tests, and XML test report generation.
-
-Please see the project page above for more information as well as mailing lists
-for questions, discussions, and development. There is also an IRC channel on
-OFTC (irc.oftc.net) #gtest available. Please join us!
-
-Requirements
-------------
+
+Google's framework for writing C++ tests on a variety of platforms
+(Linux, Mac OS X, Windows, Windows CE, Symbian, etc). Based on the
+xUnit architecture. Supports automatic test discovery, a rich set of
+assertions, user-defined assertions, death tests, fatal and non-fatal
+failures, various options for running the tests, and XML test report
+generation.
+
+Please see the project page above for more information as well as the
+mailing list for questions, discussions, and development. There is
+also an IRC channel on OFTC (irc.oftc.net) #gtest available. Please
+join us!
+
+Requirements for End Users
+--------------------------
+
Google Test is designed to have fairly minimal requirements to build
-and use with your projects, but there are some. Currently, we support
-building Google Test on Linux, Windows, Mac OS X, and Cygwin. We will
-also make our best effort to support other platforms (e.g. Solaris and
-IBM z/OS). However, since core members of the Google Test project
-have no access to them, Google Test may have outstanding issues on
-these platforms. If you notice any problems on your platform, please
-notify googletestframework@googlegroups.com (patches for fixing them
-are even more welcome!).
+and use with your projects, but there are some. Currently, we support
+Linux, Windows, Mac OS X, and Cygwin. We will also make our best
+effort to support other platforms (e.g. Solaris, AIX, and z/OS).
+However, since core members of the Google Test project have no access
+to these platforms, Google Test may have outstanding issues there. If
+you notice any problems on your platform, please notify
+googletestframework@googlegroups.com. Patches for fixing them are
+even more welcome!
### Linux Requirements ###
+
These are the base requirements to build and use Google Test from a source
package (as described below):
- * GNU-compatible Make or "gmake"
+ * GNU-compatible Make or gmake
* POSIX-standard shell
* POSIX(-2) Regular Expressions (regex.h)
- * A C++98 standards compliant compiler
-
-Furthermore, if you are building Google Test from a VCS Checkout (also
-described below), there are further requirements:
- * Automake version 1.9 or newer
- * Autoconf version 2.59 or newer
- * Libtool / Libtoolize
- * Python version 2.4 or newer
+ * A C++98-standard-compliant compiler
### Windows Requirements ###
- * Microsoft Visual Studio 7.1 or newer
+
+ * Microsoft Visual C++ 7.1 or newer
### Cygwin Requirements ###
+
* Cygwin 1.5.25-14 or newer
### Mac OS X Requirements ###
+
* Mac OS X 10.4 Tiger or newer
* Developer Tools Installed
- * Optional: Xcode 2.5 or later for univeral-binary framework; see note below.
+
+Also, you'll need CMake 2.6.4 or higher if you want to build the
+samples using the provided CMake script, regardless of the platform.
+
+Requirements for Contributors
+-----------------------------
+
+We welcome patches. If you plan to contribute a patch, you need to
+build Google Test and its own tests from an SVN checkout (described
+below), which has further requirements:
+
+ * Python version 2.3 or newer (for running some of the tests and
+ re-generating certain source files from templates)
+ * CMake 2.6.4 or newer
Getting the Source
------------------
-There are two primary ways of getting Google Test's source code: you can
-download a source release in your preferred archive format, or directly check
-out the source from a Version Control System (VCS, we use Google Code's
-Subversion hosting). The VCS checkout requires a few extra steps and some extra
-software packages on your system, but lets you track development, and make
-patches to contribute much more easily, so we highly encourage it.
-
-### VCS Checkout: ###
-The first step is to select whether you want to check out the main line of
-development on Google Test, or one of the released branches. The former will be
-much more active and have the latest features, but the latter provides much
-more stability and predictability. Choose whichever fits your needs best, and
-proceed with the following Subversion commands:
+
+There are two primary ways of getting Google Test's source code: you
+can download a stable source release in your preferred archive format,
+or directly check out the source from our Subversion (SVN) repositary.
+The SVN checkout requires a few extra steps and some extra software
+packages on your system, but lets you track the latest development and
+make patches much more easily, so we highly encourage it.
+
+### Source Package ###
+
+Google Test is released in versioned source packages which can be
+downloaded from the download page [1]. Several different archive
+formats are provided, but the only difference is the tools used to
+manipulate them, and the size of the resulting file. Download
+whichever you are most comfortable with.
+
+ [1] http://code.google.com/p/googletest/downloads/list
+
+Once the package is downloaded, expand it using whichever tools you
+prefer for that type. This will result in a new directory with the
+name "gtest-X.Y.Z" which contains all of the source code. Here are
+some examples on Linux:
+
+ tar -xvzf gtest-X.Y.Z.tar.gz
+ tar -xvjf gtest-X.Y.Z.tar.bz2
+ unzip gtest-X.Y.Z.zip
+
+### SVN Checkout ###
+
+To check out the main branch (also known as the "trunk") of Google
+Test, run the following Subversion command:
svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn
-or for a release version X.Y.*'s branch:
+Setting up the Build
+--------------------
- svn checkout http://googletest.googlecode.com/svn/branches/release-X.Y/ \
- gtest-X.Y-svn
+To build Google Test and your tests that use it, you need to tell your
+build system where to find its headers and source files. The exact
+way to do it depends on which build system you use, and is usually
+straightforward.
-Next you will need to prepare the GNU Autotools build system, if you
-are using Linux, Mac OS X, or Cygwin. Enter the target directory of
-the checkout command you used ('gtest-svn' or 'gtest-X.Y-svn' above)
-and proceed with the following command:
+### Generic Build Instructions ###
- autoreconf -fvi
+Suppose you put Google Test in directory ${GTEST_DIR}. To build it,
+create a library build target (or a project as called by Visual Studio
+and Xcode) to compile
-Once you have completed this step, you are ready to build the library. Note
-that you should only need to complete this step once. The subsequent `make'
-invocations will automatically re-generate the bits of the build system that
-need to be changed.
+ ${GTEST_DIR}/src/gtest-all.cc
-If your system uses older versions of the autotools, the above command will
-fail. You may need to explicitly specify a version to use. For instance, if you
-have both GNU Automake 1.4 and 1.9 installed and `automake' would invoke the
-1.4, use instead:
+with
- AUTOMAKE=automake-1.9 ACLOCAL=aclocal-1.9 autoreconf -fvi
+ ${GTEST_DIR}/include and ${GTEST_DIR}
-Make sure you're using the same version of automake and aclocal.
+in the header search path. Assuming a Linux-like system and gcc,
+something like the following will do:
-### Source Package: ###
-Google Test is also released in source packages which can be downloaded from
-its Google Code download page[1]. Several different archive formats are
-provided, but the only difference is the tools used to manipulate them, and the
-size of the resulting file. Download whichever you are most comfortable with.
+ g++ -I${GTEST_DIR}/include -I${GTEST_DIR} -c ${GTEST_DIR}/src/gtest-all.cc
+ ar -rv libgtest.a gtest-all.o
- [1] Google Test Downloads: http://code.google.com/p/googletest/downloads/list
+Next, you should compile your test source file with
+${GTEST_DIR}/include in the header search path, and link it with gtest
+and any other necessary libraries:
-Once downloaded expand the archive using whichever tools you prefer for that
-type. This will always result in a new directory with the name "gtest-X.Y.Z"
-which contains all of the source code. Here are some examples in Linux:
+ g++ -I${GTEST_DIR}/include path/to/your_test.cc libgtest.a -o your_test
- tar -xvzf gtest-X.Y.Z.tar.gz
- tar -xvjf gtest-X.Y.Z.tar.bz2
- unzip gtest-X.Y.Z.zip
+As an example, the make/ directory contains a Makefile that you can
+use to build Google Test on systems where GNU make is available
+(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google
+Test's own tests. Instead, it just builds the Google Test library and
+a sample test. You can use it as a starting point for your own build
+script.
+
+If the default settings are correct for your environment, the
+following commands should succeed:
+
+ cd ${GTEST_DIR}/make
+ make
+ ./sample1_unittest
+
+If you see errors, try to tweak the contents of make/Makefile to make
+them go away. There are instructions in make/Makefile on how to do
+it.
+
+### Using CMake ###
+
+Google Test comes with a CMake build script (CMakeLists.txt) that can
+be used on a wide range of platforms ("C" stands for cross-platofrm.).
+If you don't have CMake installed already, you can download it for
+free from http://www.cmake.org/.
+
+CMake works by generating native makefiles or build projects that can
+be used in the compiler environment of your choice. The typical
+workflow starts with:
+
+ mkdir mybuild # Create a directory to hold the build output.
+ cd mybuild
+ cmake ${GTEST_DIR} # Generate native build scripts.
+
+If you want to build Google Test's samples, you should replace the
+last command with
+
+ cmake -Dbuild_gtest_samples=ON ${GTEST_DIR}
+
+If you are on a *nix system, you should now see a Makefile in the
+current directory. Just type 'make' to build gtest.
+
+If you use Windows and have Vistual Studio installed, a gtest.sln file
+and several .vcproj files will be created. You can then build them
+using Visual Studio.
+
+On Mac OS X with Xcode installed, a .xcodeproj file will be generated.
+
+### Legacy Build Scripts ###
+
+Before settling on CMake, we have been providing hand-maintained build
+projects/scripts for Visual Studio, Xcode, and Autotools. While we
+continue to provide them for convenience, they are not actively
+maintained any more. We highly recommend that you follow the
+instructions in the previous two sections to integrate Google Test
+with your existing build system.
+
+If you still need to use the legacy build scripts, here's how:
+
+The msvc\ folder contains two solutions with Visual C++ projects.
+Open the gtest.sln or gtest-md.sln file using Visual Studio, and you
+are ready to build Google Test the same way you build any Visual
+Studio project. Files that have names ending with -md use DLL
+versions of Microsoft runtime libraries (the /MD or the /MDd compiler
+option). Files without that suffix use static versions of the runtime
+libraries (the /MT or the /MTd option). Please note that one must use
+the same option to compile both gtest and the test code. If you use
+Visual Studio 2005 or above, we recommend the -md version as /MD is
+the default for new projects in these versions of Visual Studio.
+
+On Mac OS X, open the gtest.xcodeproj in the xcode/ folder using
+Xcode. Build the "gtest" target. The universal binary framework will
+end up in your selected build directory (selected in the Xcode
+"Preferences..." -> "Building" pane and defaults to xcode/build).
+Alternatively, at the command line, enter:
+
+ xcodebuild
+
+This will build the "Release" configuration of gtest.framework in your
+default build location. See the "xcodebuild" man page for more
+information about building different configurations and building in
+different locations.
+
+Tweaking Google Test
+--------------------
+
+Google Test can be used in diverse environments. The default
+configuration may not work (or may not work well) out of the box in
+some environments. However, you can easily tweak Google Test by
+defining control macros on the compiler command line. Generally,
+these macros are named like GTEST_XYZ and you define them to either 1
+or 0 to enable or disable a certain feature.
+
+We list the most frequently used macros below. For a complete list,
+see file include/gtest/internal/gtest-port.h.
+
+### Choosing a TR1 Tuple Library ###
-Choosing a TR1 Tuple Library
-----------------------------
Some Google Test features require the C++ Technical Report 1 (TR1)
-tuple library, which is not yet widely available with all compilers.
-The good news is that Google Test implements a subset of TR1 tuple
-that's enough for its own need, and will automatically use this when
-the compiler doesn't provide TR1 tuple.
+tuple library, which is not yet available with all compilers. The
+good news is that Google Test implements a subset of TR1 tuple that's
+enough for its own need, and will automatically use this when the
+compiler doesn't provide TR1 tuple.
Usually you don't need to care about which tuple library Google Test
uses. However, if your project already uses TR1 tuple, you need to
tell Google Test to use the same TR1 tuple library the rest of your
-project uses (this requirement is new in Google Test 1.4.0, so you may
-need to take care of it when upgrading from an earlier version), or
-the two tuple implementations will clash. To do that, add
+project uses, or the two tuple implementations will clash. To do
+that, add
-DGTEST_USE_OWN_TR1_TUPLE=0
-to the compiler flags while compiling Google Test and your tests.
+to the compiler flags while compiling Google Test and your tests. If
+you want to force Google Test to use its own tuple library, just add
+
+ -DGTEST_USE_OWN_TR1_TUPLE=1
+
+to the compiler flags instead.
If you don't want Google Test to use tuple at all, add
-DGTEST_HAS_TR1_TUPLE=0
-to the compiler flags. All features using tuple will be disabled in
-this mode.
-
-Building the Source
--------------------
-### Linux, Mac OS X (without Xcode), and Cygwin ###
-There are two primary options for building the source at this point: build it
-inside the source code tree, or in a separate directory. We recommend building
-in a separate directory as that tends to produce both more consistent results
-and be easier to clean up should anything go wrong, but both patterns are
-supported. The only hard restriction is that while the build directory can be
-a subdirectory of the source directory, the opposite is not possible and will
-result in errors. Once you have selected where you wish to build Google Test,
-create the directory if necessary, and enter it. The following steps apply for
-either approach by simply substituting the shell variable SRCDIR with "." for
-building inside the source directory, and the relative path to the source
-directory otherwise.
-
- ${SRCDIR}/configure # Standard GNU configure script, --help for more info
- make # Standard makefile following GNU conventions
- make check # Builds and runs all tests - all should pass
-
-Other programs will only be able to use Google Test's functionality if you
-install it in a location which they can access, in Linux this is typically
-under '/usr/local'. The following command will install all of the Google Test
-libraries, public headers, and utilities necessary for other programs and
-libraries to leverage it:
-
- sudo make install # Not necessary, but allows use by other programs
-
-Should you need to remove Google Test from your system after having installed
-it, run the following command, and it will back out its changes. However, note
-carefully that you must run this command on the *same* Google Test build that
-you ran the install from, or the results are not predictable. If you install
-Google Test on your system, and are working from a VCS checkout, make sure you
-run this *before* updating your checkout of the source in order to uninstall
-the same version which you installed.
-
- sudo make uninstall # Must be run against the exact same build as "install"
-
-Your project can build against Google Test simply by leveraging the
-'gtest-config' script. This script can be invoked directly out of the 'scripts'
-subdirectory of the build tree, and it will be installed in the binary
-directory specified during the 'configure'. Here are some examples of its use,
-see 'gtest-config --help' for more detailed information.
-
- gtest-config --min-version=1.0 || echo "Insufficient Google Test version."
-
- g++ $(gtest-config --cppflags --cxxflags) -o foo.o -c foo.cpp
- g++ $(gtest-config --ldflags --libs) -o foo foo.o
-
- # When using a built but not installed Google Test:
- g++ $(../../my_gtest_build/scripts/gtest-config ...) ...
-
-### Windows ###
-The msvc\ folder contains two solutions with Visual C++ projects. Open the
-gtest.sln or gtest-md.sln file using Visual Studio, and you are ready to
-build Google Test the same way you build any Visual Studio project. Files
-that have names ending with -md use DLL versions of Microsoft runtime
-libraries (the /MD or the /MDd compiler option). Files without that suffix
-use static versions of the runtime libraries (the /MT or the /MTd option).
-Please note that one must use the same option to compile both gtest and his
-test code. If you use Visual Studio 2005 or above, we recommend the -md
-version as /MD is the default for new projects in these versions of Visual
-Studio.
-
-### Mac OS X (universal-binary framework) ###
-Open the gtest.xcodeproj in the xcode/ folder using Xcode. Build the "gtest"
-target. The universal binary framework will end up in your selected build
-directory (selected in the Xcode "Preferences..." -> "Building" pane and
-defaults to xcode/build). Alternatively, at the command line, enter:
+and all features using tuple will be disabled.
- xcodebuild
+### Multi-threaded Tests ###
-This will build the "Release" configuration of gtest.framework in your
-default build location. See the "xcodebuild" man page for more information about
-building different configurations and building in different locations.
+Google Test is thread-safe where the pthread library is available.
+After #include <gtest/gtest.h>, you can check the GTEST_IS_THREADSAFE
+macro to see whether this is the case (yes if the macro is #defined to
+1, no if it's undefined.).
-To test the gtest.framework in Xcode, change the active target to "Check" and
-then build. This target builds all of the tests and then runs them. Don't worry
-if you see some errors. Xcode reports all test failures (even the intentional
-ones) as errors. However, you should see a "Build succeeded" message at the end
-of the build log. To run all of the tests from the command line, enter:
+If Google Test doesn't correctly detect whether pthread is available
+in your environment, you can force it with
- xcodebuild -target Check
+ -DGTEST_HAS_PTHREAD=1
-Installation with xcodebuild requires specifying an installation desitination
-directory, known as the DSTROOT. Three items will be installed when using
-xcodebuild:
+or
- $DSTROOT/Library/Frameworks/gtest.framework
- $DSTROOT/usr/local/lib/libgtest.a
- $DSTROOT/usr/local/lib/libgtest_main.a
+ -DGTEST_HAS_PTHREAD=0
-You specify the installation directory on the command line with the other
-xcodebuild options. Here's how you would install in a user-visible location:
+When Google Test uses pthread, you may need to add flags to your
+compiler and/or linker to select the pthread library, or you'll get
+link errors. If you use the CMake script or the deprecated Autotools
+script, this is taken care of for you. If you use your own build
+script, you'll need to read your compiler and linker's manual to
+figure out what flags to add.
- xcodebuild install DSTROOT=~
+### As a Shared Library (DLL) ###
-To perform a system-wide inistall, escalate to an administrator and specify
-the file system root as the DSTROOT:
+Google Test is compact, so most users can build and link it as a
+static library for the simplicity. You can choose to use Google Test
+as a shared library (known as a DLL on Windows) if you prefer.
- sudo xcodebuild install DSTROOT=/
+To compile gtest as a shared library, add
-To uninstall gtest.framework via the command line, you need to delete the three
-items listed above. Remember to escalate to an administrator if deleting these
-from the system-wide location using the commands listed below:
+ -DGTEST_CREATE_SHARED_LIBRARY=1
- sudo rm -r /Library/Frameworks/gtest.framework
- sudo rm /usr/local/lib/libgtest.a
- sudo rm /usr/local/lib/libgtest_main.a
+to the compiler flags. You'll also need to tell the linker to produce
+a shared library instead - consult your linker's manual for how to do
+it.
-It is also possible to build and execute individual tests within Xcode. Each
-test has its own Xcode "Target" and Xcode "Executable". To build any of the
-tests, change the active target and the active executable to the test of
-interest and then build and run.
+To compile your tests that use the gtest shared library, add
-Individual tests can be built from the command line using:
+ -DGTEST_LINKED_AS_SHARED_LIBRARY=1
- xcodebuild -target <test_name>
+to the compiler flags.
-These tests can be executed from the command line by moving to the build
-directory and then (in bash)
+### Avoiding Macro Name Clashes ###
- export DYLD_FRAMEWORK_PATH=`pwd`
- ./<test_name> # (e.g. ./gtest_unittest)
+In C++, macros don't obey namespaces. Therefore two libraries that
+both define a macro of the same name will clash if you #include both
+definitions. In case a Google Test macro clashes with another
+library, you can force Google Test to rename its macro to avoid the
+conflict.
-To use gtest.framework for your own tests, first, install the framework using
-the steps described above. Then add it to your Xcode project by selecting
-Project->Add to Project... from the main menu. Next, add libgtest_main.a from
-gtest.framework/Resources directory using the same menu command. Finally,
-create a new executable target and add gtest.framework and libgtest_main.a to
-the "Link Binary With Libraries" build phase.
+Specifically, if both Google Test and some other code define macro
+FOO, you can add
-### Using GNU Make ###
-The make/ directory contains a Makefile that you can use to build
-Google Test on systems where GNU make is available (e.g. Linux, Mac OS
-X, and Cygwin). It doesn't try to build Google Test's own tests.
-Instead, it just builds the Google Test library and a sample test.
-You can use it as a starting point for your own Makefile.
+ -DGTEST_DONT_DEFINE_FOO=1
-If the default settings are correct for your environment, the
-following commands should succeed:
+to the compiler flags to tell Google Test to change the macro's name
+from FOO to GTEST_FOO. Currently FOO can be FAIL, SUCCEED, or TEST.
+For example, with -DGTEST_DONT_DEFINE_TEST=1, you'll need to write
- cd ${SRCDIR}/make
- make
- ./sample1_unittest
+ GTEST_TEST(SomeTest, DoesThis) { ... }
-If you see errors, try to tweak the contents of make/Makefile to make
-them go away. There are instructions in make/Makefile on how to do
-it.
+instead of
-### Using Your Own Build System ###
-If none of the build solutions we provide works for you, or if you
-prefer your own build system, you just need to compile
-src/gtest-all.cc into a library and link your tests with it. Assuming
-a Linux-like system and gcc, something like the following will do:
+ TEST(SomeTest, DoesThis) { ... }
- cd ${SRCDIR}
- g++ -I. -I./include -c src/gtest-all.cc
- ar -rv libgtest.a gtest-all.o
- g++ -I. -I./include path/to/your_test.cc libgtest.a -o your_test
+in order to define a test.
+
+Upgrating from an Earlier Version
+---------------------------------
+
+We strive to keep Google Test releases backward compatible.
+Sometimes, though, we have to make some breaking changes for the
+users' long-term benefits. This section describes what you'll need to
+do if you are upgrading from an earlier version of Google Test.
+
+### Upgrading from 1.3.0 or Earlier ###
+
+You may need to explicitly enable or disable Google Test's own TR1
+tuple library. See the instructions in section "Choosing a TR1 Tuple
+Library".
+
+### Upgrading from 1.4.0 or Earlier ###
+
+The Autotools build script (configure + make) is no longer officially
+supportted. You are encouraged to migrate to your own build system or
+use CMake. If you still need to use Autotools, you can find
+instructions in the README file from Google Test 1.4.0.
+
+On platforms where the pthread library is available, Google Test uses
+it in order to be thread-safe. See the "Multi-threaded Tests" section
+for what this means to your build script.
+
+If you use Microsoft Visual C++ 7.1 with exceptions disabled, Google
+Test will no longer compile. This should affect very few people, as a
+large portion of STL (including <string>) doesn't compile in this mode
+anyway. We decided to stop supporting it in order to greatly simplify
+Google Test's implementation.
+
+Developing Google Test
+----------------------
+
+This section discusses how to make your own changes to Google Test.
+
+### Testing Google Test Itself ###
+
+To make sure your changes work as intended and don't break existing
+functionality, you'll want to compile and run Google Test's own tests.
+For that you can use CMake:
+
+ mkdir mybuild
+ cd mybuild
+ cmake -Dbuild_all_gtest_tests=ON ${GTEST_DIR}
+
+Make sure you have Python installed, as some of Google Test's tests
+are written in Python. If the cmake command complains about not being
+able to find Python ("Could NOT find PythonInterp (missing:
+PYTHON_EXECUTABLE)"), try telling it explicitly where your Python
+executable can be found:
+
+ cmake -DPYTHON_EXECUTABLE=path/to/python -Dbuild_all_gtest_tests=ON \
+ ${GTEST_DIR}
+
+Next, you can build Google Test and all of its own tests. On *nix,
+this is usually done by 'make'. To run the tests, do
+
+ make test
+
+All tests should pass.
+
+### Regenerating Source Files ###
-Regenerating Source Files
--------------------------
Some of Google Test's source files are generated from templates (not
in the C++ sense) using a script. A template file is named FOO.pump,
where FOO is the name of the file it will generate. For example, the
@@ -307,12 +398,20 @@ file include/gtest/internal/gtest-type-util.h.pump is used to generate
gtest-type-util.h in the same directory.
Normally you don't need to worry about regenerating the source files,
-unless you need to modify them (e.g. if you are working on a patch for
-Google Test). In that case, you should modify the corresponding .pump
-files instead and run the 'pump' script (for Pump is Useful for Meta
-Programming) to regenerate them. We are still working on releasing
-the script and its documentation. If you need it now, please email
-googletestframework@googlegroups.com such that we know to make it
-happen sooner.
+unless you need to modify them. In that case, you should modify the
+corresponding .pump files instead and run the pump.py Python script to
+regenerate them. You can find pump.py in the scripts/ directory.
+Read the Pump manual [2] for how to use it.
+
+ [2] http://code.google.com/p/googletest/wiki/PumpManual
+
+### Contributing a Patch ###
+
+We welcome patches. Please read the Google Test developer's guide [3]
+for how you can contribute. In particular, make sure you have signed
+the Contributor License Agreement, or we won't be able to accept the
+patch.
+
+ [3] http://code.google.com/p/googletest/wiki/GoogleTestDevGuide
Happy testing!
diff --git a/gtest/aclocal.m4 b/gtest/aclocal.m4
index 567ee74..bed39b9 100644
--- a/gtest/aclocal.m4
+++ b/gtest/aclocal.m4
@@ -1,8 +1,7 @@
-# generated automatically by aclocal 1.11.3 -*- Autoconf -*-
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
-# Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -12,13 +11,14 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,
-[m4_warning([this file was generated for autoconf 2.68.
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
-To do so, use the procedure documented by the package, typically `autoreconf'.])])
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
#
@@ -1326,7 +1326,7 @@ ia64-*-hpux*)
rm -rf conftest*
;;
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
@@ -1338,9 +1338,19 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
LD="${LD-ld} -m elf_i386_fbsd"
;;
x86_64-*linux*)
- LD="${LD-ld} -m elf_i386"
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
;;
- ppc64-*linux*|powerpc64-*linux*)
+ powerpc64le-*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
@@ -1359,7 +1369,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
- ppc*-*linux*|powerpc*-*linux*)
+ powerpcle-*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
@@ -1702,7 +1715,8 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
;;
*)
lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len"; then
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
else
@@ -2526,17 +2540,6 @@ freebsd* | dragonfly*)
esac
;;
-gnu*)
- version_type=linux # correct to gnu/linux during the next big refactor
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
haiku*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
@@ -2653,7 +2656,7 @@ linux*oldld* | linux*aout* | linux*coff*)
;;
# This must be glibc/ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
@@ -3269,10 +3272,6 @@ freebsd* | dragonfly*)
fi
;;
-gnu*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
haiku*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -3311,7 +3310,7 @@ irix5* | irix6* | nonstopux*)
;;
# This must be glibc/ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -4063,7 +4062,7 @@ m4_if([$1], [CXX], [
;;
esac
;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
KCC*)
# KAI C++ Compiler
@@ -4362,7 +4361,7 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
# old Intel for x86_64 which still supported -KPIC.
ecc*)
@@ -6251,9 +6250,6 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(ld_shlibs, $1)=yes
;;
- gnu*)
- ;;
-
haiku*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
_LT_TAGVAR(link_all_deplibs, $1)=yes
@@ -6415,7 +6411,7 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(inherit_rpath, $1)=yes
;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
@@ -8626,25 +8622,22 @@ m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
-
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.11'
+[am__api_version='1.14'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.3], [],
+m4_if([$1], [1.14.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -8660,24 +8653,22 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.3])dnl
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
-
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
-# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
-# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory. The problem is that $srcdir (and
@@ -8696,7 +8687,7 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir. In an in-source build this is usually
-# harmless because $srcdir is `.', but things will broke when you
+# harmless because $srcdir is '.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
@@ -8722,22 +8713,19 @@ am_aux_dir=`cd $ac_aux_dir && pwd`
# AM_CONDITIONAL -*- Autoconf -*-
-# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 9
-
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
-[AC_PREREQ(2.52)dnl
- ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
- [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])dnl
AC_SUBST([$1_FALSE])dnl
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
@@ -8756,16 +8744,14 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
-# 2010, 2011 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 12
-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
@@ -8775,7 +8761,7 @@ fi])])
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
-# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
@@ -8788,12 +8774,13 @@ AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
-ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
- [$1], CXX, [depcc="$CXX" am_compiler_list=],
- [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
- [$1], UPC, [depcc="$UPC" am_compiler_list=],
- [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
- [depcc="$$1" am_compiler_list=])
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
@@ -8801,8 +8788,8 @@ AC_CACHE_CHECK([dependency style of $depcc],
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
@@ -8842,16 +8829,16 @@ AC_CACHE_CHECK([dependency style of $depcc],
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
@@ -8860,8 +8847,8 @@ AC_CACHE_CHECK([dependency style of $depcc],
test "$am__universal" = false || continue
;;
nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
if test "x$enable_dependency_tracking" = xyes; then
continue
else
@@ -8869,7 +8856,7 @@ AC_CACHE_CHECK([dependency style of $depcc],
fi
;;
msvc7 | msvc7msys | msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
+ # This compiler won't grok '-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
@@ -8917,7 +8904,7 @@ AM_CONDITIONAL([am__fastdep$1], [
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
-# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
AC_DEFUN([AM_SET_DEPDIR],
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
@@ -8927,9 +8914,13 @@ AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
-[AC_ARG_ENABLE(dependency-tracking,
-[ --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors])
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
@@ -8944,20 +8935,18 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-#serial 5
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[{
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
@@ -8970,7 +8959,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
+ # We used to match only the files named 'Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
@@ -8982,21 +8971,19 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
+ # from the Makefile without running 'make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
+ test -z "$am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
@@ -9014,7 +9001,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
-# is enabled. FIXME. This creates each `.P' file that we will
+# is enabled. FIXME. This creates each '.P' file that we will
# need in order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
@@ -9024,18 +9011,21 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# Do all the work for Automake. -*- Autoconf -*-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 16
-
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
@@ -9048,7 +9038,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.62])dnl
+[AC_PREREQ([2.65])dnl
dnl Autoconf wants to disallow AM_ names. We explicitly allow
dnl the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
@@ -9077,31 +9067,40 @@ AC_SUBST([CYGPATH_W])
# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
-[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+[AC_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
-m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
_AM_IF_OPTION([no-define],,
-[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
-AM_MISSING_PROG(AUTOCONF, autoconf)
-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
-AM_MISSING_PROG(AUTOHEADER, autoheader)
-AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
-AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
@@ -9112,34 +9111,78 @@ _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
[_AM_PROG_TAR([v7])])])
_AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC],
- [_AM_DEPENDENCIES(CC)],
- [define([AC_PROG_CC],
- defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+ [_AM_DEPENDENCIES([CC])],
+ [m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX],
- [_AM_DEPENDENCIES(CXX)],
- [define([AC_PROG_CXX],
- defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
- [_AM_DEPENDENCIES(OBJC)],
- [define([AC_PROG_OBJC],
- defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
])
-_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
-dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
-dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
-dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
-])
-dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+ fi
+fi])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
dnl mangled by Autoconf and run in a shell conditional statement.
m4_define([_AC_COMPILER_EXEEXT],
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
-
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
@@ -9161,15 +9204,12 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
-# Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
-
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
@@ -9183,16 +9223,14 @@ if test x"${install_sh}" != xset; then
install_sh="\${SHELL} $am_aux_dir/install-sh"
esac
fi
-AC_SUBST(install_sh)])
+AC_SUBST([install_sh])])
-# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 2
-
# Check whether the underlying file-system supports filenames
# with a leading dot. For instance MS-DOS doesn't.
AC_DEFUN([AM_SET_LEADING_DOT],
@@ -9208,14 +9246,12 @@ AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
-# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 4
-
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
@@ -9233,7 +9269,7 @@ am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
+# Ignore all kinds of additional output from 'make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
@@ -9260,15 +9296,12 @@ rm -f confinc confmf
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 6
-
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
@@ -9276,11 +9309,10 @@ AC_DEFUN([AM_MISSING_PROG],
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
-
# AM_MISSING_HAS_RUN
# ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([missing])dnl
@@ -9293,54 +9325,22 @@ if test x"${MISSING+set}" != xset; then
esac
fi
# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
else
am_missing_run=
- AC_MSG_WARN([`missing' script is too old or missing])
+ AC_MSG_WARN(['missing' script is too old or missing])
fi
])
-# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
-# Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 1
-
-# AM_PROG_MKDIR_P
-# ---------------
-# Check for `mkdir -p'.
-AC_DEFUN([AM_PROG_MKDIR_P],
-[AC_PREREQ([2.60])dnl
-AC_REQUIRE([AC_PROG_MKDIR_P])dnl
-dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
-dnl while keeping a definition of mkdir_p for backward compatibility.
-dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
-dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
-dnl Makefile.ins that do not define MKDIR_P, so we do our own
-dnl adjustment using top_builddir (which is defined more often than
-dnl MKDIR_P).
-AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
-case $mkdir_p in
- [[\\/$]]* | ?:[[\\/]]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-])
-
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 5
-
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
@@ -9350,7 +9350,7 @@ AC_DEFUN([_AM_MANGLE_OPTION],
# --------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
-[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
# _AM_SET_OPTIONS(OPTIONS)
# ------------------------
@@ -9364,14 +9364,59 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009,
-# 2011 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+ [whether $CC understands -c and -o together],
+ [am_cv_prog_cc_c_o],
+ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 2
# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# ---------------------------------------------------------------------------
@@ -9400,7 +9445,7 @@ AC_DEFUN([AM_PATH_PYTHON],
dnl Find a Python interpreter. Python versions prior to 2.0 are not
dnl supported. (2.0 was released on October 16, 2000).
m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
-[python python2 python3 python3.2 python3.1 python3.0 python2.7 dnl
+[python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 dnl
python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0])
AC_ARG_VAR([PYTHON], [the Python interpreter])
@@ -9416,10 +9461,11 @@ AC_DEFUN([AM_PATH_PYTHON],
dnl A version check is needed.
if test -n "$PYTHON"; then
# If the user set $PYTHON, use it and don't search something else.
- AC_MSG_CHECKING([whether $PYTHON version >= $1])
+ AC_MSG_CHECKING([whether $PYTHON version is >= $1])
AM_PYTHON_CHECK_VERSION([$PYTHON], [$1],
- [AC_MSG_RESULT(yes)],
- [AC_MSG_ERROR(too old)])
+ [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])
+ AC_MSG_ERROR([Python interpreter is too old])])
am_display_PYTHON=$PYTHON
else
# Otherwise, try each interpreter until we find one that satisfies
@@ -9468,6 +9514,25 @@ AC_DEFUN([AM_PATH_PYTHON],
[am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`])
AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform])
+ # Just factor out some code duplication.
+ am_python_setup_sysconfig="\
+import sys
+# Prefer sysconfig over distutils.sysconfig, for better compatibility
+# with python 3.x. See automake bug#10227.
+try:
+ import sysconfig
+except ImportError:
+ can_use_sysconfig = 0
+else:
+ can_use_sysconfig = 1
+# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs:
+# <https://github.com/pypa/virtualenv/issues/118>
+try:
+ from platform import python_implementation
+ if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7':
+ can_use_sysconfig = 0
+except ImportError:
+ pass"
dnl Set up 4 directories:
@@ -9484,7 +9549,14 @@ AC_DEFUN([AM_PATH_PYTHON],
else
am_py_prefix=$prefix
fi
- am_cv_python_pythondir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(0,0,prefix='$am_py_prefix'))" 2>/dev/null`
+ am_cv_python_pythondir=`$PYTHON -c "
+$am_python_setup_sysconfig
+if can_use_sysconfig:
+ sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
+else:
+ from distutils import sysconfig
+ sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
+sys.stdout.write(sitedir)"`
case $am_cv_python_pythondir in
$am_py_prefix*)
am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
@@ -9519,7 +9591,14 @@ AC_DEFUN([AM_PATH_PYTHON],
else
am_py_exec_prefix=$exec_prefix
fi
- am_cv_python_pyexecdir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(1,0,prefix='$am_py_exec_prefix'))" 2>/dev/null`
+ am_cv_python_pyexecdir=`$PYTHON -c "
+$am_python_setup_sysconfig
+if can_use_sysconfig:
+ sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'})
+else:
+ from distutils import sysconfig
+ sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix')
+sys.stdout.write(sitedir)"`
case $am_cv_python_pyexecdir in
$am_py_exec_prefix*)
am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
@@ -9567,14 +9646,12 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
sys.exit(sys.hexversion < minverhex)"
AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
-# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
-
# AM_RUN_LOG(COMMAND)
# -------------------
# Run COMMAND, save the exit status in ac_status, and log it.
@@ -9588,22 +9665,16 @@ AC_DEFUN([AM_RUN_LOG],
# Check to make sure that the build environment is sane. -*- Autoconf -*-
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 5
-
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftest.file
# Reject unsafe characters in $srcdir or the absolute working directory
# name. Accept space and tab only in the latter.
am_lf='
@@ -9614,32 +9685,40 @@ case `pwd` in
esac
case $srcdir in
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
- AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
esac
-# Do `set' in a subshell so we don't clobber the current shell's
+# Do 'set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$[*]" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- rm -f conftest.file
- if test "$[*]" != "X $srcdir/configure conftest.file" \
- && test "$[*]" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
-alias in your environment])
- fi
-
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+ alias in your environment])
+ fi
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
test "$[2]" = conftest.file
)
then
@@ -9649,46 +9728,118 @@ else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
-AC_MSG_RESULT(yes)])
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
-# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+ [--enable-silent-rules],
+ [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+ [--disable-silent-rules],
+ [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+ [am_cv_make_support_nested_variables],
+ [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
# AM_PROG_INSTALL_STRIP
# ---------------------
-# One issue with vendor `install' (even GNU) is that you can't
+# One issue with vendor 'install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
-# always use install-sh in `make install-strip', and initialize
+# always use install-sh in "make install-strip", and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 3
-
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
@@ -9702,18 +9853,16 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 2
-
# _AM_PROG_TAR(FORMAT)
# --------------------
# Check how to create a tarball in format FORMAT.
-# FORMAT should be one of `v7', `ustar', or `pax'.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
#
# Substitute a variable $(am__tar) that is a command
# writing to stdout a FORMAT-tarball containing the directory
@@ -9723,76 +9872,114 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Substitute a variable $(am__untar) that extract such
# a tarball read from stdin.
# $(am__untar) < result.tar
+#
AC_DEFUN([_AM_PROG_TAR],
[# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AC_SUBST([AMTAR], ['$${TAR-tar}'])
-m4_if([$1], [v7],
- [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
- [m4_case([$1], [ustar],, [pax],,
- [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
+
+# We'll loop over all known methods to create a tar archive until one works.
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of `-'.
-for _am_tool in $_am_tools
-do
- case $_am_tool in
- gnutar)
- for _am_tar in tar gnutar gtar;
- do
- AM_RUN_LOG([$_am_tar --version]) && break
- done
- am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
- am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
- am__untar="$_am_tar -xf -"
- ;;
- plaintar)
- # Must skip GNU tar: if it does not support --format= it doesn't create
- # ustar tarball either.
- (tar --version) >/dev/null 2>&1 && continue
- am__tar='tar chf - "$$tardir"'
- am__tar_='tar chf - "$tardir"'
- am__untar='tar xf -'
- ;;
- pax)
- am__tar='pax -L -x $1 -w "$$tardir"'
- am__tar_='pax -L -x $1 -w "$tardir"'
- am__untar='pax -r'
- ;;
- cpio)
- am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
- am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
- am__untar='cpio -i -H $1 -d'
- ;;
- none)
- am__tar=false
- am__tar_=false
- am__untar=false
- ;;
- esac
- # If the value was cached, stop now. We just wanted to have am__tar
- # and am__untar set.
- test -n "${am_cv_prog_tar_$1}" && break
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
- # tar/untar a dummy directory, and stop if the command works
- rm -rf conftest.dir
- mkdir conftest.dir
- echo GrepMe > conftest.dir/file
- AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ for _am_tool in $_am_tools; do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar; do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ AM_RUN_LOG([cat conftest.dir/file])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
rm -rf conftest.dir
- if test -s conftest.tar; then
- AM_RUN_LOG([$am__untar <conftest.tar])
- grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
- fi
-done
-rm -rf conftest.dir
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+ AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+ AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
diff --git a/gtest/build-aux/compile b/gtest/build-aux/compile
new file mode 100755
index 0000000..531136b
--- /dev/null
+++ b/gtest/build-aux/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" "" $nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv/,$2, in
+ *,$file_conv,*)
+ ;;
+ mingw/*)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin/*)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine/*)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+ func_file_conv "$1"
+ if test -z "$lib_path"; then
+ lib_path=$file
+ else
+ lib_path="$lib_path;$file"
+ fi
+ linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+ lib=$1
+ found=no
+ save_IFS=$IFS
+ IFS=';'
+ for dir in $lib_path $LIB
+ do
+ IFS=$save_IFS
+ if $shared && test -f "$dir/$lib.dll.lib"; then
+ found=yes
+ lib=$dir/$lib.dll.lib
+ break
+ fi
+ if test -f "$dir/$lib.lib"; then
+ found=yes
+ lib=$dir/$lib.lib
+ break
+ fi
+ if test -f "$dir/lib$lib.a"; then
+ found=yes
+ lib=$dir/lib$lib.a
+ break
+ fi
+ done
+ IFS=$save_IFS
+
+ if test "$found" != yes; then
+ lib=$lib.lib
+ fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+ # Assume a capable shell
+ lib_path=
+ shared=:
+ linker_opts=
+ for arg
+ do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ eat=1
+ case $2 in
+ *.o | *.[oO][bB][jJ])
+ func_file_conv "$2"
+ set x "$@" -Fo"$file"
+ shift
+ ;;
+ *)
+ func_file_conv "$2"
+ set x "$@" -Fe"$file"
+ shift
+ ;;
+ esac
+ ;;
+ -I)
+ eat=1
+ func_file_conv "$2" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -I*)
+ func_file_conv "${1#-I}" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -l)
+ eat=1
+ func_cl_dashl "$2"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -l*)
+ func_cl_dashl "${1#-l}"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -L)
+ eat=1
+ func_cl_dashL "$2"
+ ;;
+ -L*)
+ func_cl_dashL "${1#-L}"
+ ;;
+ -static)
+ shared=false
+ ;;
+ -Wl,*)
+ arg=${1#-Wl,}
+ save_ifs="$IFS"; IFS=','
+ for flag in $arg; do
+ IFS="$save_ifs"
+ linker_opts="$linker_opts $flag"
+ done
+ IFS="$save_ifs"
+ ;;
+ -Xlinker)
+ eat=1
+ linker_opts="$linker_opts $2"
+ ;;
+ -*)
+ set x "$@" "$1"
+ shift
+ ;;
+ *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+ func_file_conv "$1"
+ set x "$@" -Tp"$file"
+ shift
+ ;;
+ *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+ func_file_conv "$1" mingw
+ set x "$@" "$file"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+ done
+ if test -n "$linker_opts"; then
+ linker_opts="-link$linker_opts"
+ fi
+ exec "$@" $linker_opts
+ exit 1
+}
+
+eat=
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+ cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+ func_cl_wrapper "$@" # Doesn't return...
+ ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ # So we strip '-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no '-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # '.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/gtest/build-aux/config.guess b/gtest/build-aux/config.guess
index 278f9e9..b79252d 100755
--- a/gtest/build-aux/config.guess
+++ b/gtest/build-aux/config.guess
@@ -1,14 +1,12 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
+# Copyright 1992-2013 Free Software Foundation, Inc.
-timestamp='2007-07-22'
+timestamp='2013-06-10'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@@ -17,26 +15,22 @@ timestamp='2007-07-22'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Originally written by Per Bothner <per@bothner.com>.
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner.
#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+
me=`echo "$0" | sed -e 's,.*/,,'`
@@ -56,8 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -139,12 +132,33 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ ;;
+esac
+
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
@@ -170,7 +184,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep __ELF__ >/dev/null
+ | grep -q __ELF__
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
@@ -180,7 +194,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
fi
;;
*)
- os=netbsd
+ os=netbsd
;;
esac
# The OS release
@@ -201,6 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
@@ -223,7 +241,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
@@ -269,7 +287,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit ;;
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@@ -295,12 +316,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
- echo powerpc-ibm-os400
+ echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
- arm:riscos:*:*|arm:RISCOS:*:*)
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@@ -324,14 +345,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -375,23 +415,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
+ exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
@@ -461,8 +501,8 @@ EOF
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@@ -475,7 +515,7 @@ EOF
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
@@ -532,7 +572,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
- *:AIX:*:[45])
+ *:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@@ -575,52 +615,52 @@ EOF
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
+ esac ;;
+ esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ sed 's/^ //' << EOF >$dummy.c
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
@@ -640,7 +680,7 @@ EOF
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep __LP64__ >/dev/null
+ grep -q __LP64__
then
HP_ARCH="hppa2.0w"
else
@@ -711,22 +751,22 @@ EOF
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
- exit ;;
+ exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
- exit ;;
+ exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
- exit ;;
+ exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
- exit ;;
+ exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
- exit ;;
+ exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
@@ -750,14 +790,14 @@ EOF
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@@ -769,40 +809,51 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
- case ${UNAME_MACHINE} in
- pc98)
- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
+ i*:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
- *:Interix*:[3456]*)
- case ${UNAME_MACHINE} in
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
- EM64T | authenticamd)
+ authenticamd | genuineintel | EM64T)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
@@ -823,203 +874,157 @@ EOF
exit ;;
*:GNU:*:*)
# the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
arm*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
exit ;;
avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
cris:Linux:*:*)
- echo cris-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
crisv32:Linux:*:*)
- echo crisv32-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
frv:Linux:*:*)
- echo frv-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
- mips:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips
- #undef mipsel
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mipsel
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- mips64:Linux:*:*)
+ mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
- #undef mips64
- #undef mips64el
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
+ CPU=${UNAME_MACHINE}el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
+ CPU=${UNAME_MACHINE}
#else
CPU=
#endif
#endif
EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
+ or1k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
or32:Linux:*:*)
- echo or32-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
esac
exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
- xtensa:Linux:*:*)
- echo xtensa-unknown-linux-gnu
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
- i*86:Linux:*:*)
- # The BFD linker knows what the default object file format is, so
- # first see if it will tell us. cd to the root directory to prevent
- # problems with other programs or directories called `ld' in the path.
- # Set LC_ALL=C to ensure ld outputs messages in English.
- ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
- | sed -ne '/supported targets:/!d
- s/[ ][ ]*/ /g
- s/.*supported targets: *//
- s/ .*//
- p'`
- case "$ld_supported_targets" in
- elf32-i386)
- TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
- ;;
- a.out-i386-linux)
- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit ;;
- "")
- # Either a pre-BFD a.out linker (linux-gnuoldld) or
- # one that does not give us useful --help.
- echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit ;;
- esac
- # Determine whether the default compiler is a.out or elf
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <features.h>
- #ifdef __ELF__
- # ifdef __GLIBC__
- # if __GLIBC__ >= 2
- LIBC=gnu
- # else
- LIBC=gnulibc1
- # endif
- # else
- LIBC=gnulibc1
- # endif
- #else
- #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
- LIBC=gnu
- #else
- LIBC=gnuaout
- #endif
- #endif
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^LIBC/{
- s: ::g
- p
- }'`"
- test x"${LIBC}" != x && {
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit
- }
- test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
- ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
@@ -1027,11 +1032,11 @@ EOF
echo i386-sequent-sysv4
exit ;;
i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
+ # Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
@@ -1048,7 +1053,7 @@ EOF
i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable
exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;;
i*86:*DOS:*:*)
@@ -1063,7 +1068,7 @@ EOF
fi
exit ;;
i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
@@ -1091,10 +1096,13 @@ EOF
exit ;;
pc:*:*:*)
# Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
- exit ;;
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
@@ -1129,8 +1137,18 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
@@ -1143,7 +1161,7 @@ EOF
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;;
SM[BE]S:UNIX_SV:*:*)
@@ -1163,10 +1181,10 @@ EOF
echo ns32k-sni-sysv
fi
exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
@@ -1192,11 +1210,11 @@ EOF
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
+ echo mips-nec-sysv${UNAME_RELEASE}
else
- echo mips-unknown-sysv${UNAME_RELEASE}
+ echo mips-unknown-sysv${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
@@ -1206,6 +1224,12 @@ EOF
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@@ -1232,9 +1256,21 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
@@ -1248,7 +1284,10 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
- NSE-?:NONSTOP_KERNEL:*:*)
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
@@ -1293,13 +1332,13 @@ EOF
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
+ echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
@@ -1314,11 +1353,14 @@ EOF
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
esac
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
@@ -1336,11 +1378,11 @@ main ()
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
- "4"
+ "4"
#else
- ""
+ ""
#endif
- ); exit (0);
+ ); exit (0);
#endif
#endif
@@ -1474,9 +1516,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
diff --git a/gtest/build-aux/config.sub b/gtest/build-aux/config.sub
index 1761d8b..9633db7 100755
--- a/gtest/build-aux/config.sub
+++ b/gtest/build-aux/config.sub
@@ -1,44 +1,40 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
+# Copyright 1992-2013 Free Software Foundation, Inc.
-timestamp='2007-06-28'
+timestamp='2013-08-10'
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
@@ -72,8 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -120,12 +115,18 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
- nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
@@ -148,10 +149,13 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray)
+ -apple | -axis | -knuth | -cray | -microblaze*)
os=
basic_machine=$1
;;
+ -bluegene*)
+ os=-cnk
+ ;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
@@ -166,10 +170,10 @@ case $os in
os=-chorusos
basic_machine=$1
;;
- -chorusrdb)
- os=-chorusrdb
+ -chorusrdb)
+ os=-chorusrdb
basic_machine=$1
- ;;
+ ;;
-hiux*)
os=-hiuxwe2
;;
@@ -214,6 +218,12 @@ case $os in
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
-lynx*)
os=-lynxos
;;
@@ -238,24 +248,34 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
+ | aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
| bfin \
- | c4x | clipper \
+ | c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
+ | epiphany \
| fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
+ | le32 | le64 \
+ | lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | mcore | mep \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
- | mips64vr | mips64vrel \
+ | mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
@@ -266,31 +286,45 @@ case $basic_machine in
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
+ | moxie \
| mt \
| msp430 \
- | nios | nios2 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
- | or32 \
+ | open8 \
+ | or1k | or32 \
| pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
+ | rl78 | rx \
| score \
- | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu | strongarm \
- | tahoe | thumb | tic4x | tic80 | tron \
- | v850 | v850e \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| we32k \
- | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
- | z8k)
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
basic_machine=$basic_machine-unknown
;;
- m6811 | m68hc11 | m6812 | m68hc12)
- # Motorola 68HC11/12.
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@@ -300,6 +334,21 @@ case $basic_machine in
basic_machine=mt-unknown
;;
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
@@ -314,29 +363,37 @@ case $basic_machine in
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
+ | aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
+ | be32-* | be64-* \
| bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
- | clipper-* | craynv-* | cydra-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
+ | le32-* | le64-* \
+ | lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
- | mips64vr-* | mips64vrel-* \
+ | mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
@@ -347,31 +404,41 @@ case $basic_machine in
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
- | nios-* | nios2-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
- | romp-* | rs6000-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
- | tahoe-* | thumb-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
| tron-* \
- | v850-* | v850e-* | vax-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
| we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
| ymp-* \
- | z8k-*)
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -389,7 +456,7 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
- abacus)
+ abacus)
basic_machine=abacus-unknown
;;
adobe68k)
@@ -435,6 +502,10 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -443,10 +514,35 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
c90)
basic_machine=c90-cray
os=-unicos
;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -475,7 +571,7 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
- cr16)
+ cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
@@ -514,6 +610,10 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
@@ -629,7 +729,6 @@ case $basic_machine in
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
@@ -668,6 +767,14 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -679,8 +786,15 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
mingw32)
- basic_machine=i386-pc
+ basic_machine=i686-pc
os=-mingw32
;;
mingw32ce)
@@ -715,10 +829,18 @@ case $basic_machine in
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@@ -783,6 +905,12 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@@ -813,6 +941,14 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
pbd)
basic_machine=sparc-tti
;;
@@ -857,9 +993,10 @@ case $basic_machine in
;;
power) basic_machine=power-ibm
;;
- ppc) basic_machine=powerpc-unknown
+ ppc | ppcbe) basic_machine=powerpc-unknown
;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
@@ -884,7 +1021,11 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
- rdos)
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
basic_machine=i386-pc
os=-rdos
;;
@@ -953,6 +1094,9 @@ case $basic_machine in
basic_machine=i860-stratus
os=-sysv4
;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
sun2)
basic_machine=m68000-sun
;;
@@ -1009,17 +1153,9 @@ case $basic_machine in
basic_machine=t90-cray
os=-unicos
;;
- tic54x | c54x*)
- basic_machine=tic54x-unknown
- os=-coff
- ;;
- tic55x | c55x*)
- basic_machine=tic55x-unknown
- os=-coff
- ;;
- tic6x | c6x*)
- basic_machine=tic6x-unknown
- os=-coff
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
;;
tx39)
basic_machine=mipstx39-unknown
@@ -1088,6 +1224,9 @@ case $basic_machine in
xps | xps100)
basic_machine=xps100-honeywell
;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
ymp)
basic_machine=ymp-cray
os=-unicos
@@ -1096,6 +1235,10 @@ case $basic_machine in
basic_machine=z8k-unknown
os=-sim
;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
none)
basic_machine=none-none
os=-none
@@ -1134,7 +1277,7 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
- sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
@@ -1181,9 +1324,12 @@ esac
if [ x"$os" != x"" ]
then
case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
+ # First match some system type aliases
+ # that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
@@ -1204,21 +1350,23 @@ case $os in
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
+ | -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -openbsd* | -solidbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* \
- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1226,7 +1374,7 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1265,7 +1413,7 @@ case $os in
-opened*)
os=-openedition
;;
- -os400*)
+ -os400*)
os=-os400
;;
-wince*)
@@ -1314,7 +1462,7 @@ case $os in
-sinix*)
os=-sysv4
;;
- -tpf*)
+ -tpf*)
os=-tpf
;;
-triton*)
@@ -1350,12 +1498,14 @@ case $os in
-aros*)
os=-aros
;;
- -kaos*)
- os=-kaos
- ;;
-zvmoe)
os=-zvmoe
;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
-none)
;;
*)
@@ -1378,10 +1528,10 @@ else
# system, and we'll never get to this point.
case $basic_machine in
- score-*)
+ score-*)
os=-elf
;;
- spu-*)
+ spu-*)
os=-elf
;;
*-acorn)
@@ -1393,8 +1543,23 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
- c4x-* | tic4x-*)
- os=-coff
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
@@ -1414,14 +1579,11 @@ case $basic_machine in
;;
m68000-sun)
os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
;;
m68*-cisco)
os=-aout
;;
- mep-*)
+ mep-*)
os=-elf
;;
mips*-cisco)
@@ -1430,6 +1592,9 @@ case $basic_machine in
mips*-*)
os=-elf
;;
+ or1k-*)
+ os=-elf
+ ;;
or32-*)
os=-coff
;;
@@ -1448,7 +1613,7 @@ case $basic_machine in
*-ibm)
os=-aix
;;
- *-knuth)
+ *-knuth)
os=-mmixware
;;
*-wec)
@@ -1553,7 +1718,7 @@ case $basic_machine in
-sunos*)
vendor=sun
;;
- -aix*)
+ -cnk*|-aix*)
vendor=ibm
;;
-beos*)
diff --git a/gtest/build-aux/depcomp b/gtest/build-aux/depcomp
index e5f9736..4ebd5b3 100755
--- a/gtest/build-aux/depcomp
+++ b/gtest/build-aux/depcomp
@@ -1,10 +1,9 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
-scriptversion=2007-03-29.01
+scriptversion=2013-05-30.07; # UTC
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software
-# Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -17,9 +16,7 @@ scriptversion=2007-03-29.01
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -30,9 +27,9 @@ scriptversion=2007-03-29.01
case $1 in
'')
- echo "$0: No command. Try \`$0 --help' for more information." 1>&2
- exit 1;
- ;;
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
@@ -42,11 +39,11 @@ as side-effects.
Environment variables:
depmode Dependency tracking mode.
- source Source file read by `PROGRAMS ARGS'.
- object Object file output by `PROGRAMS ARGS'.
+ source Source file read by 'PROGRAMS ARGS'.
+ object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
- tmpdepfile Temporary file to use when outputing dependencies.
+ tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
@@ -59,6 +56,66 @@ EOF
;;
esac
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'. Note that this directory component will
+# be either empty or ending with a '/' character. This is deliberate.
+set_dir_from ()
+{
+ case $1 in
+ */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+ *) dir=;;
+ esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+ base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+ echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+ # If the compiler actually managed to produce a dependency file,
+ # post-process it.
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form 'foo.o: dependency.h'.
+ # Do two passes, one to just change these to
+ # $object: dependency.h
+ # and one to simply output
+ # dependency.h:
+ # which is needed to avoid the deleted-header problem.
+ { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+ sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+ } > "$depfile"
+ rm -f "$tmpdepfile"
+ else
+ make_dummy_depfile
+ fi
+}
+
+# A tabulation character.
+tab=' '
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
@@ -71,6 +128,9 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
@@ -82,9 +142,32 @@ if test "$depmode" = hp; then
fi
if test "$depmode" = dashXmstdout; then
- # This is just like dashmstdout with a different argument.
- dashmflag=-xM
- depmode=dashmstdout
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
fi
case "$depmode" in
@@ -107,8 +190,7 @@ gcc3)
done
"$@"
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@@ -116,13 +198,17 @@ gcc3)
;;
gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
-## -MM, not -M (despite what the docs say).
+## -MM, not -M (despite what the docs say). Also, it might not be
+## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
@@ -130,31 +216,31 @@ gcc)
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
- alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
-## The second -e expression handles DOS-style file names with drive letters.
+ # The second -e expression handles DOS-style file names with drive
+ # letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
-## This next piece of magic avoids the `deleted header file' problem.
+## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
- tr ' ' '
-' < "$tmpdepfile" |
-## Some versions of gcc put a space before the `:'. On the theory
+## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
-## well.
+## well. hp depmode also adds that space, but also prefixes the VPATH
+## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -172,8 +258,7 @@ sgi)
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@@ -181,43 +266,41 @@ sgi)
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
-
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
- # the IRIX cc adds comments like `#:fec' to the end of the
+ # the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
- tr ' ' '
-' < "$tmpdepfile" \
- | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
- tr '
-' ' ' >> $depfile
- echo >> $depfile
-
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+ | tr "$nl" ' ' >> "$depfile"
+ echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
- tr ' ' '
-' < "$tmpdepfile" \
- | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
- >> $depfile
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
else
- # The sourcefile does not contain any dependencies, so just
- # store a dummy comment line, to avoid errors with the Makefile
- # "include basename.Plo" scheme.
- echo "#dummy" > "$depfile"
+ make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
+xlc)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
- # current directory. Also, the AIX compiler puts `$object:' at the
+ # current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ set_dir_from "$object"
+ set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
@@ -230,9 +313,7 @@ aix)
"$@" -M
fi
stat=$?
-
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
@@ -241,44 +322,100 @@ aix)
do
test -f "$tmpdepfile" && break
done
- if test -f "$tmpdepfile"; then
- # Each line is of the form `foo.o: dependent.h'.
- # Do two passes, one to just change these to
- # `$object: dependent.h' and one to simply `dependent.h:'.
- sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
- # That's a tab and a space in the [].
- sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
- else
- # The sourcefile does not contain any dependencies, so just
- # store a dummy comment line, to avoid errors with the Makefile
- # "include basename.Plo" scheme.
- echo "#dummy" > "$depfile"
+ aix_post_process_depfile
+ ;;
+
+tcc)
+ # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+ # FIXME: That version still under development at the moment of writing.
+ # Make that this statement remains true also for stable, released
+ # versions.
+ # It will wrap lines (doesn't matter whether long or short) with a
+ # trailing '\', as in:
+ #
+ # foo.o : \
+ # foo.c \
+ # foo.h \
+ #
+ # It will put a trailing '\' even on the last line, and will use leading
+ # spaces rather than leading tabs (at least since its commit 0394caf7
+ # "Emit spaces for -MD").
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
fi
+ rm -f "$depfile"
+ # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+ # We have to change lines of the first kind to '$object: \'.
+ sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+ # And for each line of the second kind, we have to emit a 'dep.h:'
+ # dummy dependency, to avoid the deleted-header problem.
+ sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
-icc)
- # Intel's C compiler understands `-MD -MF file'. However on
- # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
- # ICC 7.0 will fill foo.d with something like
- # foo.o: sub/foo.c
- # foo.o: sub/foo.h
- # which is wrong. We want:
- # sub/foo.o: sub/foo.c
- # sub/foo.o: sub/foo.h
- # sub/foo.c:
- # sub/foo.h:
- # ICC 7.1 will output
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file. A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+ # Portland's C compiler understands '-MD'.
+ # Will always output deps to 'file.d' where file is the root name of the
+ # source file under compilation, even if file resides in a subdirectory.
+ # The object file name does not affect the name of the '.d' file.
+ # pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
- # and will wrap long lines using \ :
+ # and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
+ set_dir_from "$object"
+ # Use the source, not the object, to determine the base name, since
+ # that's sadly what pgcc will do too.
+ set_base_from "$source"
+ tmpdepfile=$base.d
+
+ # For projects that build the same source file twice into different object
+ # files, the pgcc approach of using the *source* file root name can cause
+ # problems in parallel builds. Use a locking strategy to avoid stomping on
+ # the same $tmpdepfile.
+ lockdir=$base.d-lock
+ trap "
+ echo '$0: caught signal, cleaning up...' >&2
+ rmdir '$lockdir'
+ exit 1
+ " 1 2 13 15
+ numtries=100
+ i=$numtries
+ while test $i -gt 0; do
+ # mkdir is a portable test-and-set.
+ if mkdir "$lockdir" 2>/dev/null; then
+ # This process acquired the lock.
+ "$@" -MD
+ stat=$?
+ # Release the lock.
+ rmdir "$lockdir"
+ break
+ else
+ # If the lock is being held by a different process, wait
+ # until the winning process is done or we timeout.
+ while test -d "$lockdir" && test $i -gt 0; do
+ sleep 1
+ i=`expr $i - 1`
+ done
+ fi
+ i=`expr $i - 1`
+ done
+ trap - 1 2 13 15
+ if test $i -le 0; then
+ echo "$0: failed to acquire lock after $numtries attempts" >&2
+ echo "$0: check lockdir '$lockdir'" >&2
+ exit 1
+ fi
- "$@" -MD -MF "$tmpdepfile"
- stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
@@ -290,8 +427,8 @@ icc)
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
- sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
- sed -e 's/$/ :/' >> "$depfile"
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -302,9 +439,8 @@ hp2)
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ set_dir_from "$object"
+ set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
@@ -315,8 +451,7 @@ hp2)
"$@" +Maked
fi
stat=$?
- if test $stat -eq 0; then :
- else
+ if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
@@ -326,72 +461,107 @@ hp2)
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
- sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
- # Add `dependent.h:' lines.
- sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
+ sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add 'dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
else
- echo "#dummy" > "$depfile"
+ make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
- # The Tru64 compiler uses -MD to generate dependencies as a side
- # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
- # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
- # dependencies in `foo.d' instead, so we check for that too.
- # Subdirectories are respected.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
-
- if test "$libtool" = yes; then
- # With Tru64 cc, shared objects can also be used to make a
- # static library. This mechanism is used in libtool 1.4 series to
- # handle both shared and static libraries in a single compilation.
- # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
- #
- # With libtool 1.5 this exception was removed, and libtool now
- # generates 2 separate objects for the 2 libraries. These two
- # compilations output dependencies in $dir.libs/$base.o.d and
- # in $dir$base.o.d. We have to check for both files, because
- # one of the two compilations can be disabled. We should prefer
- # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
- # automatically cleaned when .libs/ is deleted, while ignoring
- # the former would cause a distcleancheck panic.
- tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
- tmpdepfile2=$dir$base.o.d # libtool 1.5
- tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
- tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
- "$@" -Wc,-MD
- else
- tmpdepfile1=$dir$base.o.d
- tmpdepfile2=$dir$base.d
- tmpdepfile3=$dir$base.d
- tmpdepfile4=$dir$base.d
- "$@" -MD
- fi
-
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
- exit $stat
- fi
-
- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
- do
- test -f "$tmpdepfile" && break
- done
- if test -f "$tmpdepfile"; then
- sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
- # That's a tab and a space in the [].
- sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
- else
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile"
- ;;
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in 'foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ set_dir_from "$object"
+ set_base_from "$object"
+
+ if test "$libtool" = yes; then
+ # Libtool generates 2 separate objects for the 2 libraries. These
+ # two compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir$base.o.d # libtool 1.5
+ tmpdepfile2=$dir.libs/$base.o.d # Likewise.
+ tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ # Same post-processing that is required for AIX mode.
+ aix_post_process_depfile
+ ;;
+
+msvc7)
+ if test "$libtool" = yes; then
+ showIncludes=-Wc,-showIncludes
+ else
+ showIncludes=-showIncludes
+ fi
+ "$@" $showIncludes > "$tmpdepfile"
+ stat=$?
+ grep -v '^Note: including file: ' "$tmpdepfile"
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The first sed program below extracts the file names and escapes
+ # backslashes for cygpath. The second sed program outputs the file
+ # name when reading, but also accumulates all include files in the
+ # hold buffer in order to output them again at the end. This only
+ # works with sed implementations that can handle large buffers.
+ sed < "$tmpdepfile" -n '
+/^Note: including file: *\(.*\)/ {
+ s//\1/
+ s/\\/\\\\/g
+ p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+ s/.*/'"$tab"'/
+ G
+ p
+}' >> "$depfile"
+ echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7msys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
@@ -404,13 +574,13 @@ dashmstdout)
# Remove the call to Libtool.
if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
+ while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
- # Remove `-o $object'.
+ # Remove '-o $object'.
IFS=" "
for arg
do
@@ -430,18 +600,18 @@ dashmstdout)
done
test -z "$dashmflag" && dashmflag=-M
- # Require at least two characters before searching for `:'
+ # Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
- # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
- sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
- tr ' ' '
-' < "$tmpdepfile" | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this sed invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -455,41 +625,51 @@ makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
+ while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
- cleared=no
- for arg in "$@"; do
+ cleared=no eat=no
+ for arg
+ do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
- obj_suffix="`echo $object | sed 's/^.*\././'`"
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
- cat < "$tmpdepfile" > "$depfile"
- sed '1,2d' "$tmpdepfile" | tr ' ' '
-' | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ # makedepend may prepend the VPATH from the source file name to the object.
+ # No need to regex-escape $object, excess matching of '.' is harmless.
+ sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process the last invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed '1,2d' "$tmpdepfile" \
+ | tr ' ' "$nl" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
@@ -500,13 +680,13 @@ cpp)
# Remove the call to Libtool.
if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
+ while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
- # Remove `-o $object'.
+ # Remove '-o $object'.
IFS=" "
for arg
do
@@ -525,10 +705,10 @@ cpp)
esac
done
- "$@" -E |
- sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
- -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
- sed '$ s: \\$::' > "$tmpdepfile"
+ "$@" -E \
+ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ | sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
@@ -538,35 +718,56 @@ cpp)
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
- # always write the preprocessed file to stdout, regardless of -o,
- # because we must use -o when running libtool.
+ # always write the preprocessed file to stdout.
"$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
IFS=" "
for arg
do
case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
- set fnord "$@"
- shift
- shift
- ;;
+ set fnord "$@"
+ shift
+ shift
+ ;;
*)
- set fnord "$@" "$arg"
- shift
- shift
- ;;
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
esac
done
- "$@" -E |
- sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
- . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
- echo " " >> "$depfile"
- . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+ echo "$tab" >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
none)
exec "$@"
;;
@@ -585,5 +786,6 @@ exit 0
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
# End:
diff --git a/gtest/build-aux/install-sh b/gtest/build-aux/install-sh
index a5897de..377bb86 100755
--- a/gtest/build-aux/install-sh
+++ b/gtest/build-aux/install-sh
@@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
-scriptversion=2006-12-25.00
+scriptversion=2011-11-20.07; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@@ -35,7 +35,7 @@ scriptversion=2006-12-25.00
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
+# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
@@ -156,6 +156,10 @@ while test $# -ne 0; do
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
shift;;
-T) no_target_directory=true;;
@@ -186,6 +190,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
fi
shift # arg
dst_arg=$arg
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
done
fi
@@ -194,13 +202,17 @@ if test $# -eq 0; then
echo "$0: no input file specified." >&2
exit 1
fi
- # It's OK to call `install-sh -d' without argument.
+ # It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
- trap '(exit $?); exit' 1 2 13 15
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
@@ -228,9 +240,9 @@ fi
for src
do
- # Protect names starting with `-'.
+ # Protect names problematic for 'test' and other utilities.
case $src in
- -*) src=./$src;;
+ -* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
@@ -252,12 +264,7 @@ do
echo "$0: no destination specified." >&2
exit 1
fi
-
dst=$dst_arg
- # Protect names starting with `-'.
- case $dst in
- -*) dst=./$dst;;
- esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
@@ -347,7 +354,7 @@ do
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writeable bit of parent directory when it shouldn't.
+ # other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
@@ -385,7 +392,7 @@ do
case $dstdir in
/*) prefix='/';;
- -*) prefix='./';;
+ [-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
@@ -403,7 +410,7 @@ do
for d
do
- test -z "$d" && continue
+ test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
@@ -515,5 +522,6 @@ done
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
# End:
diff --git a/gtest/build-aux/ltmain.sh b/gtest/build-aux/ltmain.sh
index c2852d8..a356aca 100644
--- a/gtest/build-aux/ltmain.sh
+++ b/gtest/build-aux/ltmain.sh
@@ -70,7 +70,7 @@
# compiler: $LTCC
# compiler flags: $LTCFLAGS
# linker: $LD (gnu? $with_gnu_ld)
-# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1
+# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.7ubuntu1
# automake: $automake_version
# autoconf: $autoconf_version
#
@@ -80,7 +80,7 @@
PROGRAM=libtool
PACKAGE=libtool
-VERSION="2.4.2 Debian-2.4.2-1ubuntu1"
+VERSION="2.4.2 Debian-2.4.2-1.7ubuntu1"
TIMESTAMP=""
package_revision=1.3337
diff --git a/gtest/build-aux/missing b/gtest/build-aux/missing
index 1c8ff70..db98974 100755
--- a/gtest/build-aux/missing
+++ b/gtest/build-aux/missing
@@ -1,11 +1,10 @@
#! /bin/sh
-# Common stub for a few missing GNU programs while installing.
+# Common wrapper for a few potentially missing GNU programs.
-scriptversion=2006-05-10.23
+scriptversion=2013-10-28.13; # UTC
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
-# Free Software Foundation, Inc.
-# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -18,9 +17,7 @@ scriptversion=2006-05-10.23
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -28,66 +25,40 @@ scriptversion=2006-05-10.23
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
- echo 1>&2 "Try \`$0 --help' for more information"
+ echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
-run=:
-sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
-sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
-
-# In the cases where this matters, `missing' is being run in the
-# srcdir already.
-if test -f configure.ac; then
- configure_ac=configure.ac
-else
- configure_ac=configure.in
-fi
+case $1 in
-msg="missing on your system"
+ --is-lightweight)
+ # Used by our autoconf macros to check whether the available missing
+ # script is modern enough.
+ exit 0
+ ;;
-case $1 in
---run)
- # Try to run requested program, and just exit if it succeeds.
- run=
- shift
- "$@" && exit 0
- # Exit code 63 means version mismatch. This often happens
- # when the user try to use an ancient version of a tool on
- # a file that requires a minimum version. In this case we
- # we should proceed has if the program had been absent, or
- # if --run hadn't been passed.
- if test $? = 63; then
- run=:
- msg="probably too old"
- fi
- ;;
+ --run)
+ # Back-compat with the calling convention used by older automake.
+ shift
+ ;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
-Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
-error status if there is no known handling for PROGRAM.
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
- --run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
- aclocal touch file \`aclocal.m4'
- autoconf touch file \`configure'
- autoheader touch file \`config.h.in'
- autom4te touch the output file, or create a stub one
- automake touch all \`Makefile.in' files
- bison create \`y.tab.[ch]', if possible, from existing .[ch]
- flex create \`lex.yy.c', if possible, from existing .c
- help2man touch the output file
- lex create \`lex.yy.c', if possible, from existing .c
- makeinfo touch the output file
- tar try tar, gnutar, gtar, then tar without non-portable flags
- yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+ aclocal autoconf autoheader autom4te automake makeinfo
+ bison yacc flex lex help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
@@ -99,269 +70,146 @@ Send bug reports to <bug-automake@gnu.org>."
;;
-*)
- echo 1>&2 "$0: Unknown \`$1' option"
- echo 1>&2 "Try \`$0 --help' for more information"
+ echo 1>&2 "$0: unknown '$1' option"
+ echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
-# Now exit if we have it, but it failed. Also exit now if we
-# don't have it and --version was passed (most likely to detect
-# the program).
-case $1 in
- lex|yacc)
- # Not GNU programs, they don't have --version.
- ;;
-
- tar)
- if test -n "$run"; then
- echo 1>&2 "ERROR: \`tar' requires --run"
- exit 1
- elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
- exit 1
- fi
- ;;
-
- *)
- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
- # We have it, but it failed.
- exit 1
- elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
- # Could not run --version or --help. This is probably someone
- # running `$TOOL --version' or `$TOOL --help' to check whether
- # $TOOL exists and not knowing $TOOL uses missing.
- exit 1
- fi
- ;;
-esac
-
-# If it does not exist, or fails to run (possibly an outdated version),
-# try to emulate it.
-case $1 in
- aclocal*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`acinclude.m4' or \`${configure_ac}'. You might want
- to install the \`Automake' and \`Perl' packages. Grab them from
- any GNU archive site."
- touch aclocal.m4
- ;;
-
- autoconf)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`${configure_ac}'. You might want to install the
- \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
- archive site."
- touch configure
- ;;
-
- autoheader)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`acconfig.h' or \`${configure_ac}'. You might want
- to install the \`Autoconf' and \`GNU m4' packages. Grab them
- from any GNU archive site."
- files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
- test -z "$files" && files="config.h"
- touch_files=
- for f in $files; do
- case $f in
- *:*) touch_files="$touch_files "`echo "$f" |
- sed -e 's/^[^:]*://' -e 's/:.*//'`;;
- *) touch_files="$touch_files $f.in";;
- esac
- done
- touch $touch_files
- ;;
-
- automake*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
- You might want to install the \`Automake' and \`Perl' packages.
- Grab them from any GNU archive site."
- find . -type f -name Makefile.am -print |
- sed 's/\.am$/.in/' |
- while read f; do touch "$f"; done
- ;;
-
- autom4te)
- echo 1>&2 "\
-WARNING: \`$1' is needed, but is $msg.
- You might have modified some files without having the
- proper tools for further handling them.
- You can get \`$1' as part of \`Autoconf' from any GNU
- archive site."
-
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -f "$file"; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo "#! /bin/sh"
- echo "# Created by GNU Automake missing as a replacement of"
- echo "# $ $@"
- echo "exit 0"
- chmod +x $file
- exit 1
- fi
- ;;
-
- bison|yacc)
- echo 1>&2 "\
-WARNING: \`$1' $msg. You should only need it if
- you modified a \`.y' file. You may need the \`Bison' package
- in order for those modifications to take effect. You can get
- \`Bison' from any GNU archive site."
- rm -f y.tab.c y.tab.h
- if test $# -ne 1; then
- eval LASTARG="\${$#}"
- case $LASTARG in
- *.y)
- SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" y.tab.c
- fi
- SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" y.tab.h
- fi
- ;;
- esac
- fi
- if test ! -f y.tab.h; then
- echo >y.tab.h
- fi
- if test ! -f y.tab.c; then
- echo 'main() { return 0; }' >y.tab.c
- fi
- ;;
-
- lex|flex)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a \`.l' file. You may need the \`Flex' package
- in order for those modifications to take effect. You can get
- \`Flex' from any GNU archive site."
- rm -f lex.yy.c
- if test $# -ne 1; then
- eval LASTARG="\${$#}"
- case $LASTARG in
- *.l)
- SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" lex.yy.c
- fi
- ;;
- esac
- fi
- if test ! -f lex.yy.c; then
- echo 'main() { return 0; }' >lex.yy.c
- fi
- ;;
-
- help2man)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a dependency of a manual page. You may need the
- \`Help2man' package in order for those modifications to take
- effect. You can get \`Help2man' from any GNU archive site."
-
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -f "$file"; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo ".ab help2man is required to generate this page"
- exit 1
- fi
- ;;
-
- makeinfo)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a \`.texi' or \`.texinfo' file, or any other file
- indirectly affecting the aspect of the manual. The spurious
- call might also be the consequence of using a buggy \`make' (AIX,
- DU, IRIX). You might want to install the \`Texinfo' package or
- the \`GNU make' package. Grab either from any GNU archive site."
- # The file to touch is that specified with -o ...
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -z "$file"; then
- # ... or it is the one specified with @setfilename ...
- infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
- file=`sed -n '
- /^@setfilename/{
- s/.* \([^ ]*\) *$/\1/
- p
- q
- }' $infile`
- # ... or it is derived from the source name (dir/f.texi becomes f.info)
- test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
- fi
- # If the file does not exist, the user really needs makeinfo;
- # let's fail without touching anything.
- test -f $file || exit 1
- touch $file
- ;;
-
- tar)
- shift
-
- # We have already tried tar in the generic part.
- # Look for gnutar/gtar before invocation to avoid ugly error
- # messages.
- if (gnutar --version > /dev/null 2>&1); then
- gnutar "$@" && exit 0
- fi
- if (gtar --version > /dev/null 2>&1); then
- gtar "$@" && exit 0
- fi
- firstarg="$1"
- if shift; then
- case $firstarg in
- *o*)
- firstarg=`echo "$firstarg" | sed s/o//`
- tar "$firstarg" "$@" && exit 0
- ;;
- esac
- case $firstarg in
- *h*)
- firstarg=`echo "$firstarg" | sed s/h//`
- tar "$firstarg" "$@" && exit 0
- ;;
- esac
- fi
-
- echo 1>&2 "\
-WARNING: I can't seem to be able to run \`tar' with the given arguments.
- You may want to install GNU tar or Free paxutils, or check the
- command line arguments."
- exit 1
- ;;
-
- *)
- echo 1>&2 "\
-WARNING: \`$1' is needed, and is $msg.
- You might have modified some files without having the
- proper tools for further handling them. Check the \`README' file,
- it often tells you about the needed prerequisites for installing
- this package. You may also peek at any GNU archive site, in case
- some other package would contain this missing \`$1' program."
- exit 1
- ;;
-esac
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch. This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+ msg="probably too old"
+elif test $st -eq 127; then
+ # Program was missing.
+ msg="missing on your system"
+else
+ # Program was found and executed, but failed. Give up.
+ exit $st
+fi
-exit 0
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+ case $1 in
+ aclocal|automake)
+ echo "The '$1' program is part of the GNU Automake package:"
+ echo "<$gnu_software_URL/automake>"
+ echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/autoconf>"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ autoconf|autom4te|autoheader)
+ echo "The '$1' program is part of the GNU Autoconf package:"
+ echo "<$gnu_software_URL/autoconf/>"
+ echo "It also requires GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ esac
+}
+
+give_advice ()
+{
+ # Normalize program name to check for.
+ normalized_program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+ printf '%s\n' "'$1' is $msg."
+
+ configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+ case $normalized_program in
+ autoconf*)
+ echo "You should only need it if you modified 'configure.ac',"
+ echo "or m4 files included by it."
+ program_details 'autoconf'
+ ;;
+ autoheader*)
+ echo "You should only need it if you modified 'acconfig.h' or"
+ echo "$configure_deps."
+ program_details 'autoheader'
+ ;;
+ automake*)
+ echo "You should only need it if you modified 'Makefile.am' or"
+ echo "$configure_deps."
+ program_details 'automake'
+ ;;
+ aclocal*)
+ echo "You should only need it if you modified 'acinclude.m4' or"
+ echo "$configure_deps."
+ program_details 'aclocal'
+ ;;
+ autom4te*)
+ echo "You might have modified some maintainer files that require"
+ echo "the 'autom4te' program to be rebuilt."
+ program_details 'autom4te'
+ ;;
+ bison*|yacc*)
+ echo "You should only need it if you modified a '.y' file."
+ echo "You may want to install the GNU Bison package:"
+ echo "<$gnu_software_URL/bison/>"
+ ;;
+ lex*|flex*)
+ echo "You should only need it if you modified a '.l' file."
+ echo "You may want to install the Fast Lexical Analyzer package:"
+ echo "<$flex_URL>"
+ ;;
+ help2man*)
+ echo "You should only need it if you modified a dependency" \
+ "of a man page."
+ echo "You may want to install the GNU Help2man package:"
+ echo "<$gnu_software_URL/help2man/>"
+ ;;
+ makeinfo*)
+ echo "You should only need it if you modified a '.texi' file, or"
+ echo "any other file indirectly affecting the aspect of the manual."
+ echo "You might want to install the Texinfo package:"
+ echo "<$gnu_software_URL/texinfo/>"
+ echo "The spurious makeinfo call might also be the consequence of"
+ echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+ echo "want to install GNU make:"
+ echo "<$gnu_software_URL/make/>"
+ ;;
+ *)
+ echo "You might have modified some files without having the proper"
+ echo "tools for further handling them. Check the 'README' file, it"
+ echo "often tells you about the needed prerequisites for installing"
+ echo "this package. You may also peek at any GNU archive site, in"
+ echo "case some other package contains this missing '$1' program."
+ ;;
+ esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+ -e '2,$s/^/ /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
# End:
diff --git a/gtest/build-aux/test-driver b/gtest/build-aux/test-driver
new file mode 100755
index 0000000..d306056
--- /dev/null
+++ b/gtest/build-aux/test-driver
@@ -0,0 +1,139 @@
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2013-07-13.22; # UTC
+
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+# Make unconditional expansion of undefined variables an error. This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+ echo "$0: $*" >&2
+ print_usage >&2
+ exit 2
+}
+
+print_usage ()
+{
+ cat <<END
+Usage:
+ test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+ [--expect-failure={yes|no}] [--color-tests={yes|no}]
+ [--enable-hard-errors={yes|no}] [--]
+ TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+test_name= # Used for reporting.
+log_file= # Where to save the output of the test script.
+trs_file= # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+ case $1 in
+ --help) print_usage; exit $?;;
+ --version) echo "test-driver $scriptversion"; exit $?;;
+ --test-name) test_name=$2; shift;;
+ --log-file) log_file=$2; shift;;
+ --trs-file) trs_file=$2; shift;;
+ --color-tests) color_tests=$2; shift;;
+ --expect-failure) expect_failure=$2; shift;;
+ --enable-hard-errors) enable_hard_errors=$2; shift;;
+ --) shift; break;;
+ -*) usage_error "invalid option: '$1'";;
+ *) break;;
+ esac
+ shift
+done
+
+missing_opts=
+test x"$test_name" = x && missing_opts="$missing_opts --test-name"
+test x"$log_file" = x && missing_opts="$missing_opts --log-file"
+test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
+if test x"$missing_opts" != x; then
+ usage_error "the following mandatory options are missing:$missing_opts"
+fi
+
+if test $# -eq 0; then
+ usage_error "missing argument"
+fi
+
+if test $color_tests = yes; then
+ # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+ red='' # Red.
+ grn='' # Green.
+ lgn='' # Light green.
+ blu='' # Blue.
+ mgn='' # Magenta.
+ std='' # No color.
+else
+ red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+ estatus=1
+fi
+
+case $estatus:$expect_failure in
+ 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+ 0:*) col=$grn res=PASS recheck=no gcopy=no;;
+ 77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
+ 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;;
+ *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;;
+ *:*) col=$red res=FAIL recheck=yes gcopy=yes;;
+esac
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/gtest/codegear/gtest.groupproj b/gtest/codegear/gtest.groupproj
index 8b650f8..faf31ca 100644
--- a/gtest/codegear/gtest.groupproj
+++ b/gtest/codegear/gtest.groupproj
@@ -23,15 +23,6 @@
<Target Name="gtest:Make">
<MSBuild Projects="gtest.cbproj" Targets="Make" />
</Target>
- <Target Name="gtest_unittest">
- <MSBuild Projects="gtest_unittest.cbproj" Targets="" />
- </Target>
- <Target Name="gtest_unittest:Clean">
- <MSBuild Projects="gtest_unittest.cbproj" Targets="Clean" />
- </Target>
- <Target Name="gtest_unittest:Make">
- <MSBuild Projects="gtest_unittest.cbproj" Targets="Make" />
- </Target>
<Target Name="gtest_main">
<MSBuild Projects="gtest_main.cbproj" Targets="" />
</Target>
@@ -41,14 +32,23 @@
<Target Name="gtest_main:Make">
<MSBuild Projects="gtest_main.cbproj" Targets="Make" />
</Target>
+ <Target Name="gtest_unittest">
+ <MSBuild Projects="gtest_unittest.cbproj" Targets="" />
+ </Target>
+ <Target Name="gtest_unittest:Clean">
+ <MSBuild Projects="gtest_unittest.cbproj" Targets="Clean" />
+ </Target>
+ <Target Name="gtest_unittest:Make">
+ <MSBuild Projects="gtest_unittest.cbproj" Targets="Make" />
+ </Target>
<Target Name="Build">
- <CallTarget Targets="gtest;gtest_unittest;gtest_main" />
+ <CallTarget Targets="gtest;gtest_main;gtest_unittest" />
</Target>
<Target Name="Clean">
- <CallTarget Targets="gtest:Clean;gtest_unittest:Clean;gtest_main:Clean" />
+ <CallTarget Targets="gtest:Clean;gtest_main:Clean;gtest_unittest:Clean" />
</Target>
<Target Name="Make">
- <CallTarget Targets="gtest:Make;gtest_unittest:Make;gtest_main:Make" />
+ <CallTarget Targets="gtest:Make;gtest_main:Make;gtest_unittest:Make" />
</Target>
<Import Condition="Exists('$(MSBuildBinPath)\Borland.Group.Targets')" Project="$(MSBuildBinPath)\Borland.Group.Targets" />
</Project> \ No newline at end of file
diff --git a/gtest/codegear/gtest_unittest.cbproj b/gtest/codegear/gtest_unittest.cbproj
index d3823c9..dc5db8e 100644
--- a/gtest/codegear/gtest_unittest.cbproj
+++ b/gtest/codegear/gtest_unittest.cbproj
@@ -18,27 +18,27 @@
<CfgParent>Base</CfgParent>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
- <BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
<OutputExt>exe</OutputExt>
- <DCC_CBuilderOutput>JPHNE</DCC_CBuilderOutput>
+ <BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
<Defines>NO_STRICT</Defines>
+ <DCC_CBuilderOutput>JPHNE</DCC_CBuilderOutput>
<DynamicRTL>true</DynamicRTL>
- <UsePackages>true</UsePackages>
<ILINK_ObjectSearchPath>..\test</ILINK_ObjectSearchPath>
- <NoVCL>true</NoVCL>
+ <UsePackages>true</UsePackages>
<ProjectType>CppConsoleApplication</ProjectType>
+ <NoVCL>true</NoVCL>
<BCC_CPPCompileAlways>true</BCC_CPPCompileAlways>
- <PackageImports>rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi</PackageImports>
+ <PackageImports>rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi</PackageImports>
<BCC_wpar>false</BCC_wpar>
<IncludePath>$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;..</IncludePath>
<ILINK_LibraryPath>$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test</ILINK_LibraryPath>
<Multithreaded>true</Multithreaded>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
- <DCC_Optimize>false</DCC_Optimize>
<BCC_OptimizeForSpeed>false</BCC_OptimizeForSpeed>
- <Defines>_DEBUG;$(Defines)</Defines>
+ <DCC_Optimize>false</DCC_Optimize>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
+ <Defines>_DEBUG;$(Defines)</Defines>
<ILINK_FullDebugInfo>true</ILINK_FullDebugInfo>
<BCC_InlineFunctionExpansion>false</BCC_InlineFunctionExpansion>
<ILINK_DisableIncrementalLinking>true</ILINK_DisableIncrementalLinking>
@@ -48,8 +48,8 @@
<IntermediateOutputDir>Debug</IntermediateOutputDir>
<TASM_DisplaySourceLines>true</TASM_DisplaySourceLines>
<BCC_StackFrames>true</BCC_StackFrames>
- <ILINK_LibraryPath>$(BDS)\lib\debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<BCC_DisableOptimizations>true</BCC_DisableOptimizations>
+ <ILINK_LibraryPath>$(BDS)\lib\debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<TASM_Debugging>Full</TASM_Debugging>
<BCC_SourceDebuggingOn>true</BCC_SourceDebuggingOn>
</PropertyGroup>
diff --git a/gtest/configure b/gtest/configure
index 8001f82..7d4daf9 100755
--- a/gtest/configure
+++ b/gtest/configure
@@ -1,13 +1,11 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for Google C++ Testing Framework 1.4.0.
+# Generated by GNU Autoconf 2.69 for Google C++ Testing Framework 1.5.0.
#
# Report bugs to <googletestframework@googlegroups.com>.
#
#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
@@ -136,6 +134,31 @@ export LANGUAGE
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
@@ -169,7 +192,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
else
exitcode=1; echo positional parameters were not saved.
fi
-test x\$exitcode = x0 || exit 1"
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
@@ -222,21 +246,25 @@ IFS=$as_save_IFS
if test "x$CONFIG_SHELL" != x; then :
- # We cannot yet assume a decent shell, so we have to provide a
- # neutralization value for shells without unset; and this also
- # works around shells that cannot unset nonexistent variables.
- # Preserve -v and -x to the replacement shell.
- BASH_ENV=/dev/null
- ENV=/dev/null
- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
- export CONFIG_SHELL
- case $- in # ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
- esac
- exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
fi
if test x$as_have_required = xno; then :
@@ -339,6 +367,14 @@ $as_echo X"$as_dir" |
} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
@@ -460,6 +496,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
chmod +x "$as_me.lineno" ||
{ $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensitive to this).
@@ -494,16 +534,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -515,28 +555,8 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -570,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='Google C++ Testing Framework'
PACKAGE_TARNAME='gtest'
-PACKAGE_VERSION='1.4.0'
-PACKAGE_STRING='Google C++ Testing Framework 1.4.0'
+PACKAGE_VERSION='1.5.0'
+PACKAGE_STRING='Google C++ Testing Framework 1.5.0'
PACKAGE_BUGREPORT='googletestframework@googlegroups.com'
PACKAGE_URL=''
@@ -616,6 +636,8 @@ ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
+HAVE_PTHREADS_FALSE
+HAVE_PTHREADS_TRUE
PTHREAD_CFLAGS
PTHREAD_LIBS
PTHREAD_CC
@@ -677,6 +699,10 @@ CPPFLAGS
LDFLAGS
CFLAGS
CC
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
am__untar
am__tar
AMTAR
@@ -741,6 +767,7 @@ SHELL'
ac_subst_files=''
ac_user_opts='
enable_option_checking
+enable_silent_rules
enable_dependency_tracking
enable_shared
enable_static
@@ -749,6 +776,7 @@ enable_fast_install
with_gnu_ld
with_sysroot
enable_libtool_lock
+with_pthreads
'
ac_precious_vars='build_alias
host_alias
@@ -1218,8 +1246,6 @@ target=$target_alias
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
- $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used" >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
@@ -1305,7 +1331,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures Google C++ Testing Framework 1.4.0 to adapt to many kinds of systems.
+\`configure' configures Google C++ Testing Framework 1.5.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1375,7 +1401,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Google C++ Testing Framework 1.4.0:";;
+ short | recursive ) echo "Configuration of Google C++ Testing Framework 1.5.0:";;
esac
cat <<\_ACEOF
@@ -1383,8 +1409,12 @@ Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-silent-rules less verbose build output (undo: "make V=1")
+ --disable-silent-rules verbose build output (undo: "make V=0")
+ --enable-dependency-tracking
+ do not reject slow dependency extractors
+ --disable-dependency-tracking
+ speeds up one-time build
--enable-shared[=PKGS] build shared libraries [default=yes]
--enable-static[=PKGS] build static libraries [default=yes]
--enable-fast-install[=PKGS]
@@ -1399,6 +1429,7 @@ Optional Packages:
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
--with-sysroot=DIR Search for dependent libraries within DIR
(or the compiler's sysroot if not specified).
+ --with-pthreads use pthreads (default is yes)
Some influential environment variables:
CC C compiler command
@@ -1479,10 +1510,10 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-Google C++ Testing Framework configure 1.4.0
-generated by GNU Autoconf 2.68
+Google C++ Testing Framework configure 1.5.0
+generated by GNU Autoconf 2.69
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1596,7 +1627,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -1856,7 +1887,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -1878,8 +1909,8 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by Google C++ Testing Framework $as_me 1.4.0, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+It was created by Google C++ Testing Framework $as_me 1.5.0, which was
+generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2269,7 +2300,7 @@ ac_config_files="$ac_config_files scripts/gtest-config"
# Initialize Automake with various options. We require at least v1.9, prevent
# pedantic complaints about package files, and enable various distribution
# targets.
-am__api_version='1.11'
+am__api_version='1.14'
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -2308,7 +2339,7 @@ case $as_dir/ in #((
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
if test $ac_prog = install &&
grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
@@ -2366,9 +2397,6 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
$as_echo_n "checking whether build environment is sane... " >&6; }
-# Just in case
-sleep 1
-echo timestamp > conftest.file
# Reject unsafe characters in $srcdir or the absolute working directory
# name. Accept space and tab only in the latter.
am_lf='
@@ -2379,32 +2407,40 @@ case `pwd` in
esac
case $srcdir in
*[\\\"\#\$\&\'\`$am_lf\ \ ]*)
- as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
esac
-# Do `set' in a subshell so we don't clobber the current shell's
+# Do 'set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$*" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- rm -f conftest.file
- if test "$*" != "X $srcdir/configure conftest.file" \
- && test "$*" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
-alias in your environment" "$LINENO" 5
- fi
-
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+ alias in your environment" "$LINENO" 5
+ fi
+ if test "$2" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
test "$2" = conftest.file
)
then
@@ -2416,6 +2452,16 @@ Check your system clock" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
test "$program_prefix" != NONE &&
program_transform_name="s&^&$program_prefix&;$program_transform_name"
# Use a double $ so make ignores it.
@@ -2438,12 +2484,12 @@ if test x"${MISSING+set}" != xset; then
esac
fi
# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
else
am_missing_run=
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
-$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
fi
if test x"${install_sh}" != xset; then
@@ -2455,10 +2501,10 @@ if test x"${install_sh}" != xset; then
esac
fi
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
+# will honor the 'STRIP' environment variable to overrule this program.
if test "$cross_compiling" != no; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
@@ -2477,7 +2523,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2517,7 +2563,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2568,7 +2614,7 @@ do
test -z "$as_dir" && as_dir=.
for ac_prog in mkdir gmkdir; do
for ac_exec_ext in '' $ac_executable_extensions; do
- { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
'mkdir (GNU coreutils) '* | \
'mkdir (coreutils) '* | \
@@ -2597,12 +2643,6 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
$as_echo "$MKDIR_P" >&6; }
-mkdir_p="$MKDIR_P"
-case $mkdir_p in
- [\\/$]* | ?:[\\/]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-
for ac_prog in gawk mawk nawk awk
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
@@ -2621,7 +2661,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AWK="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2685,6 +2725,45 @@ else
fi
rmdir .tst 2>/dev/null
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
if test "`cd $srcdir && pwd`" != "`pwd`"; then
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
# is not polluted with repeated "-I."
@@ -2707,7 +2786,7 @@ fi
# Define the identity of the package.
PACKAGE='gtest'
- VERSION='1.4.0'
+ VERSION='1.5.0'
cat >>confdefs.h <<_ACEOF
@@ -2735,12 +2814,22 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AMTAR='$${TAR-tar}'
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar pax cpio none'
+
am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
@@ -2748,6 +2837,48 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+ fi
+fi
+
# Check for programs used in building Google Test.
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@@ -2771,7 +2902,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2811,7 +2942,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2864,7 +2995,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2905,7 +3036,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
@@ -2963,7 +3094,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3007,7 +3138,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3453,8 +3584,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdarg.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -3538,6 +3668,65 @@ ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
DEPDIR="${am__leading_dot}deps"
ac_config_commands="$ac_config_commands depfiles"
@@ -3557,7 +3746,7 @@ am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
+# Ignore all kinds of additional output from 'make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
@@ -3613,8 +3802,8 @@ else
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
@@ -3649,16 +3838,16 @@ else
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
@@ -3667,8 +3856,8 @@ else
test "$am__universal" = false || continue
;;
nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
if test "x$enable_dependency_tracking" = xyes; then
continue
else
@@ -3676,7 +3865,7 @@ else
fi
;;
msvc7 | msvc7msys | msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
+ # This compiler won't grok '-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
@@ -3758,7 +3947,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3802,7 +3991,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CXX="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3998,8 +4187,8 @@ else
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
@@ -4034,16 +4223,16 @@ else
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
@@ -4052,8 +4241,8 @@ else
test "$am__universal" = false || continue
;;
nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
if test "x$enable_dependency_tracking" = xyes; then
continue
else
@@ -4061,7 +4250,7 @@ else
fi
;;
msvc7 | msvc7msys | msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
+ # This compiler won't grok '-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
@@ -4308,7 +4497,7 @@ do
for ac_prog in sed gsed; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+ as_fn_executable_p "$ac_path_SED" || continue
# Check for GNU ac_path_SED and select it if it is found.
# Check for GNU $ac_path_SED
case `"$ac_path_SED" --version 2>&1` in
@@ -4384,7 +4573,7 @@ do
for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+ as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
@@ -4450,7 +4639,7 @@ do
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+ as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
@@ -4517,7 +4706,7 @@ do
for ac_prog in fgrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+ as_fn_executable_p "$ac_path_FGREP" || continue
# Check for GNU ac_path_FGREP and select it if it is found.
# Check for GNU $ac_path_FGREP
case `"$ac_path_FGREP" --version 2>&1` in
@@ -4773,7 +4962,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4817,7 +5006,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5006,7 +5195,8 @@ else
;;
*)
lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len"; then
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
else
@@ -5241,7 +5431,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5281,7 +5471,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OBJDUMP="objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5407,10 +5597,6 @@ freebsd* | dragonfly*)
fi
;;
-gnu*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
haiku*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -5449,7 +5635,7 @@ irix5* | irix6* | nonstopux*)
;;
# This must be glibc/ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -5587,7 +5773,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5627,7 +5813,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DLLTOOL="dlltool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5731,7 +5917,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5775,7 +5961,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5900,7 +6086,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5940,7 +6126,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5999,7 +6185,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6039,7 +6225,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_RANLIB="ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6532,7 +6718,7 @@ ia64-*-hpux*)
rm -rf conftest*
;;
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
@@ -6548,9 +6734,19 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
LD="${LD-ld} -m elf_i386_fbsd"
;;
x86_64-*linux*)
- LD="${LD-ld} -m elf_i386"
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*)
+ LD="${LD-ld} -m elf32lppclinux"
;;
- ppc64-*linux*|powerpc64-*linux*)
+ powerpc64-*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
@@ -6569,7 +6765,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
- ppc*-*linux*|powerpc*-*linux*)
+ powerpcle-*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
@@ -6689,7 +6888,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6729,7 +6928,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6809,7 +7008,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6849,7 +7048,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6901,7 +7100,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6941,7 +7140,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_NMEDIT="nmedit"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6993,7 +7192,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7033,7 +7232,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_LIPO="lipo"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7085,7 +7284,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7125,7 +7324,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OTOOL="otool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7177,7 +7376,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7217,7 +7416,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OTOOL64="otool64"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -8383,7 +8582,7 @@ lt_prog_compiler_static=
lt_prog_compiler_static='-non_shared'
;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
# old Intel for x86_64 which still supported -KPIC.
ecc*)
@@ -10553,17 +10752,6 @@ freebsd* | dragonfly*)
esac
;;
-gnu*)
- version_type=linux # correct to gnu/linux during the next big refactor
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
haiku*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
@@ -10680,7 +10868,7 @@ linux*oldld* | linux*aout* | linux*coff*)
;;
# This must be glibc/ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
@@ -12503,9 +12691,6 @@ fi
ld_shlibs_CXX=yes
;;
- gnu*)
- ;;
-
haiku*)
archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
link_all_deplibs_CXX=yes
@@ -12667,7 +12852,7 @@ fi
inherit_rpath_CXX=yes
;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
@@ -13527,7 +13712,7 @@ lt_prog_compiler_static_CXX=
;;
esac
;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
KCC*)
# KAI C++ Compiler
@@ -14399,17 +14584,6 @@ freebsd* | dragonfly*)
esac
;;
-gnu*)
- version_type=linux # correct to gnu/linux during the next big refactor
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
haiku*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
@@ -14526,7 +14700,7 @@ linux*oldld* | linux*aout* | linux*coff*)
;;
# This must be glibc/ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
@@ -14954,7 +15128,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -15006,7 +15180,18 @@ else
fi
-# Check for pthreads.
+# Configure pthreads.
+
+# Check whether --with-pthreads was given.
+if test "${with_pthreads+set}" = set; then :
+ withval=$with_pthreads; with_pthreads=$withval
+else
+ with_pthreads=check
+fi
+
+
+have_pthreads=no
+if test "x$with_pthreads" != "xno"; then :
@@ -15144,7 +15329,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_acx_pthread_config="yes"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -15299,7 +15484,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_PTHREAD_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -15520,7 +15705,12 @@ $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
:
else
acx_pthread_ok=no
-
+ if test "x$with_pthreads" != "xcheck"; then :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--with-pthreads was specified, but unable to be used
+See \`config.log' for more details" "$LINENO" 5; }
+fi
fi
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
@@ -15529,6 +15719,18 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+ have_pthreads="$acx_pthread_ok"
+fi
+ if test "x$have_pthreads" == "xyes"; then
+ HAVE_PTHREADS_TRUE=
+ HAVE_PTHREADS_FALSE='#'
+else
+ HAVE_PTHREADS_TRUE='#'
+ HAVE_PTHREADS_FALSE=
+fi
+
+
+
# TODO(chandlerc@google.com) Check for the necessary system headers.
@@ -15645,6 +15847,14 @@ LIBOBJS=$ac_libobjs
LTLIBOBJS=$ac_ltlibobjs
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
if test -n "$EXEEXT"; then
am__EXEEXT_TRUE=
am__EXEEXT_FALSE='#'
@@ -15669,6 +15879,10 @@ if test -z "${HAVE_PYTHON_TRUE}" && test -z "${HAVE_PYTHON_FALSE}"; then
as_fn_error $? "conditional \"HAVE_PYTHON\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${HAVE_PTHREADS_TRUE}" && test -z "${HAVE_PTHREADS_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_PTHREADS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
@@ -15967,16 +16181,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -16036,28 +16250,16 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -16078,8 +16280,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by Google C++ Testing Framework $as_me 1.4.0, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+This file was extended by Google C++ Testing Framework $as_me 1.5.0, which was
+generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -16144,11 +16346,11 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-Google C++ Testing Framework config.status 1.4.0
-configured by $0, generated by GNU Autoconf 2.68,
+Google C++ Testing Framework config.status 1.5.0
+configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -16239,7 +16441,7 @@ fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'
@@ -17250,7 +17452,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
case $ac_file$ac_mode in
"scripts/gtest-config":F) chmod +x scripts/gtest-config ;;
"depfiles":C) test x"$AMDEP_TRUE" != x"" || {
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
@@ -17263,7 +17465,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
+ # We used to match only the files named 'Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
@@ -17297,21 +17499,19 @@ $as_echo X"$mf" |
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
+ # from the Makefile without running 'make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
+ test -z "$am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`$as_dirname -- "$file" ||
diff --git a/gtest/configure.ac b/gtest/configure.ac
index 709b024..1b91237 100644
--- a/gtest/configure.ac
+++ b/gtest/configure.ac
@@ -5,7 +5,7 @@ m4_include(m4/acx_pthread.m4)
# "[1.0.1]"). It also asumes that there won't be any closing parenthesis
# between "AC_INIT(" and the closing ")" including comments and strings.
AC_INIT([Google C++ Testing Framework],
- [1.4.0],
+ [1.5.0],
[googletestframework@googlegroups.com],
[gtest])
@@ -39,8 +39,24 @@ AS_IF([test "$PYTHON" != ":"],
[AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])])
AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"])
-# Check for pthreads.
-ACX_PTHREAD
+# Configure pthreads.
+AC_ARG_WITH([pthreads],
+ [AS_HELP_STRING([--with-pthreads],
+ [use pthreads (default is yes)])],
+ [with_pthreads=$withval],
+ [with_pthreads=check])
+
+have_pthreads=no
+AS_IF([test "x$with_pthreads" != "xno"],
+ [ACX_PTHREAD(
+ [],
+ [AS_IF([test "x$with_pthreads" != "xcheck"],
+ [AC_MSG_FAILURE(
+ [--with-pthreads was specified, but unable to be used])])])
+ have_pthreads="$acx_pthread_ok"])
+AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" == "xyes"])
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_LIBS)
# TODO(chandlerc@google.com) Check for the necessary system headers.
diff --git a/gtest/fused-src/gtest/gtest-all.cc b/gtest/fused-src/gtest/gtest-all.cc
new file mode 100644
index 0000000..644479a
--- /dev/null
+++ b/gtest/fused-src/gtest/gtest-all.cc
@@ -0,0 +1,8510 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// 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: mheule@google.com (Markus Heule)
+//
+// Google C++ Testing Framework (Google Test)
+//
+// Sometimes it's desirable to build Google Test by compiling a single file.
+// This file serves this purpose.
+
+// This line ensures that gtest.h can be compiled on its own, even
+// when it's fused.
+#include <gtest/gtest.h>
+
+// The following lines pull in the real gtest *.cc files.
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// 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: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// 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: wan@google.com (Zhanyong Wan)
+//
+// Utilities for testing Google Test itself and code that uses Google Test
+// (e.g. frameworks built on top of Google Test).
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
+#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
+
+
+namespace testing {
+
+// This helper class can be used to mock out Google Test failure reporting
+// so that we can test Google Test or code that builds on Google Test.
+//
+// An object of this class appends a TestPartResult object to the
+// TestPartResultArray object given in the constructor whenever a Google Test
+// failure is reported. It can either intercept only failures that are
+// generated in the same thread that created this object or it can intercept
+// all generated failures. The scope of this mock object can be controlled with
+// the second argument to the two arguments constructor.
+class GTEST_API_ ScopedFakeTestPartResultReporter
+ : public TestPartResultReporterInterface {
+ public:
+ // The two possible mocking modes of this object.
+ enum InterceptMode {
+ INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures.
+ INTERCEPT_ALL_THREADS // Intercepts all failures.
+ };
+
+ // The c'tor sets this object as the test part result reporter used
+ // by Google Test. The 'result' parameter specifies where to report the
+ // results. This reporter will only catch failures generated in the current
+ // thread. DEPRECATED
+ explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
+
+ // Same as above, but you can choose the interception scope of this object.
+ ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
+ TestPartResultArray* result);
+
+ // The d'tor restores the previous test part result reporter.
+ virtual ~ScopedFakeTestPartResultReporter();
+
+ // Appends the TestPartResult object to the TestPartResultArray
+ // received in the constructor.
+ //
+ // This method is from the TestPartResultReporterInterface
+ // interface.
+ virtual void ReportTestPartResult(const TestPartResult& result);
+ private:
+ void Init();
+
+ const InterceptMode intercept_mode_;
+ TestPartResultReporterInterface* old_reporter_;
+ TestPartResultArray* const result_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);
+};
+
+namespace internal {
+
+// A helper class for implementing EXPECT_FATAL_FAILURE() and
+// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given
+// TestPartResultArray contains exactly one failure that has the given
+// type and contains the given substring. If that's not the case, a
+// non-fatal failure will be generated.
+class GTEST_API_ SingleFailureChecker {
+ public:
+ // The constructor remembers the arguments.
+ SingleFailureChecker(const TestPartResultArray* results,
+ TestPartResult::Type type,
+ const char* substr);
+ ~SingleFailureChecker();
+ private:
+ const TestPartResultArray* const results_;
+ const TestPartResult::Type type_;
+ const String substr_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
+};
+
+} // namespace internal
+
+} // namespace testing
+
+// A set of macros for testing Google Test assertions or code that's expected
+// to generate Google Test fatal failures. It verifies that the given
+// statement will cause exactly one fatal Google Test failure with 'substr'
+// being part of the failure message.
+//
+// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
+// affects and considers failures generated in the current thread and
+// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
+//
+// The verification of the assertion is done correctly even when the statement
+// throws an exception or aborts the current function.
+//
+// Known restrictions:
+// - 'statement' cannot reference local non-static variables or
+// non-static members of the current object.
+// - 'statement' cannot return a value.
+// - You cannot stream a failure message to this macro.
+//
+// Note that even though the implementations of the following two
+// macros are much alike, we cannot refactor them to use a common
+// helper macro, due to some peculiarity in how the preprocessor
+// works. The AcceptsMacroThatExpandsToUnprotectedComma test in
+// gtest_unittest.cc will fail to compile if we do that.
+#define EXPECT_FATAL_FAILURE(statement, substr) \
+ do { \
+ class GTestExpectFatalFailureHelper {\
+ public:\
+ static void Execute() { statement; }\
+ };\
+ ::testing::TestPartResultArray gtest_failures;\
+ ::testing::internal::SingleFailureChecker gtest_checker(\
+ &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
+ {\
+ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+ ::testing::ScopedFakeTestPartResultReporter:: \
+ INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
+ GTestExpectFatalFailureHelper::Execute();\
+ }\
+ } while (::testing::internal::AlwaysFalse())
+
+#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
+ do { \
+ class GTestExpectFatalFailureHelper {\
+ public:\
+ static void Execute() { statement; }\
+ };\
+ ::testing::TestPartResultArray gtest_failures;\
+ ::testing::internal::SingleFailureChecker gtest_checker(\
+ &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
+ {\
+ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+ ::testing::ScopedFakeTestPartResultReporter:: \
+ INTERCEPT_ALL_THREADS, &gtest_failures);\
+ GTestExpectFatalFailureHelper::Execute();\
+ }\
+ } while (::testing::internal::AlwaysFalse())
+
+// A macro for testing Google Test assertions or code that's expected to
+// generate Google Test non-fatal failures. It asserts that the given
+// statement will cause exactly one non-fatal Google Test failure with 'substr'
+// being part of the failure message.
+//
+// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
+// affects and considers failures generated in the current thread and
+// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
+//
+// 'statement' is allowed to reference local variables and members of
+// the current object.
+//
+// The verification of the assertion is done correctly even when the statement
+// throws an exception or aborts the current function.
+//
+// Known restrictions:
+// - You cannot stream a failure message to this macro.
+//
+// Note that even though the implementations of the following two
+// macros are much alike, we cannot refactor them to use a common
+// helper macro, due to some peculiarity in how the preprocessor
+// works. If we do that, the code won't compile when the user gives
+// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
+// expands to code containing an unprotected comma. The
+// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
+// catches that.
+//
+// For the same reason, we have to write
+// if (::testing::internal::AlwaysTrue()) { statement; }
+// instead of
+// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
+// to avoid an MSVC warning on unreachable code.
+#define EXPECT_NONFATAL_FAILURE(statement, substr) \
+ do {\
+ ::testing::TestPartResultArray gtest_failures;\
+ ::testing::internal::SingleFailureChecker gtest_checker(\
+ &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
+ (substr));\
+ {\
+ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+ ::testing::ScopedFakeTestPartResultReporter:: \
+ INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
+ if (::testing::internal::AlwaysTrue()) { statement; }\
+ }\
+ } while (::testing::internal::AlwaysFalse())
+
+#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
+ do {\
+ ::testing::TestPartResultArray gtest_failures;\
+ ::testing::internal::SingleFailureChecker gtest_checker(\
+ &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
+ (substr));\
+ {\
+ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+ ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\
+ &gtest_failures);\
+ if (::testing::internal::AlwaysTrue()) { statement; }\
+ }\
+ } while (::testing::internal::AlwaysFalse())
+
+#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
+
+#include <ctype.h>
+#include <math.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include <algorithm>
+#include <ostream>
+#include <sstream>
+#include <vector>
+
+#if GTEST_OS_LINUX
+
+// TODO(kenton@google.com): Use autoconf to detect availability of
+// gettimeofday().
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+
+#include <fcntl.h>
+#include <limits.h>
+#include <sched.h>
+// Declares vsnprintf(). This header is not available on Windows.
+#include <strings.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <string>
+#include <vector>
+
+#elif GTEST_OS_SYMBIAN
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+#include <sys/time.h> // NOLINT
+
+#elif GTEST_OS_ZOS
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+#include <sys/time.h> // NOLINT
+
+// On z/OS we additionally need strings.h for strcasecmp.
+#include <strings.h> // NOLINT
+
+#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE.
+
+#include <windows.h> // NOLINT
+
+#elif GTEST_OS_WINDOWS // We are on Windows proper.
+
+#include <io.h> // NOLINT
+#include <sys/timeb.h> // NOLINT
+#include <sys/types.h> // NOLINT
+#include <sys/stat.h> // NOLINT
+
+#if GTEST_OS_WINDOWS_MINGW
+// MinGW has gettimeofday() but not _ftime64().
+// TODO(kenton@google.com): Use autoconf to detect availability of
+// gettimeofday().
+// TODO(kenton@google.com): There are other ways to get the time on
+// Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW
+// supports these. consider using them instead.
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+#include <sys/time.h> // NOLINT
+#endif // GTEST_OS_WINDOWS_MINGW
+
+// cpplint thinks that the header is already included, so we want to
+// silence it.
+#include <windows.h> // NOLINT
+
+#else
+
+// Assume other platforms have gettimeofday().
+// TODO(kenton@google.com): Use autoconf to detect availability of
+// gettimeofday().
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+
+// cpplint thinks that the header is already included, so we want to
+// silence it.
+#include <sys/time.h> // NOLINT
+#include <unistd.h> // NOLINT
+
+#endif // GTEST_OS_LINUX
+
+#if GTEST_HAS_EXCEPTIONS
+#include <stdexcept>
+#endif
+
+// Indicates that this translation unit is part of Google Test's
+// implementation. It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error. This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION_ 1
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// 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.
+
+// Utility functions and classes used by the Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// This file contains purely Google Test's internal implementation. Please
+// DO NOT #INCLUDE IT IN A USER PROGRAM.
+
+#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_
+#define GTEST_SRC_GTEST_INTERNAL_INL_H_
+
+// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is
+// part of Google Test's implementation; otherwise it's undefined.
+#if !GTEST_IMPLEMENTATION_
+// A user is trying to include this from his code - just say no.
+#error "gtest-internal-inl.h is part of Google Test's internal implementation."
+#error "It must not be included except by Google Test itself."
+#endif // GTEST_IMPLEMENTATION_
+
+#ifndef _WIN32_WCE
+#include <errno.h>
+#endif // !_WIN32_WCE
+#include <stddef.h>
+#include <stdlib.h> // For strtoll/_strtoul64/malloc/free.
+#include <string.h> // For memmove.
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+
+#if GTEST_OS_WINDOWS
+#include <windows.h> // For DWORD.
+#endif // GTEST_OS_WINDOWS
+
+
+namespace testing {
+
+// Declares the flags.
+//
+// We don't want the users to modify this flag in the code, but want
+// Google Test's own unit tests to be able to access it. Therefore we
+// declare it here as opposed to in gtest.h.
+GTEST_DECLARE_bool_(death_test_use_fork);
+
+namespace internal {
+
+// The value of GetTestTypeId() as seen from within the Google Test
+// library. This is solely for testing GetTestTypeId().
+GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;
+
+// Names of the flags (needed for parsing Google Test flags).
+const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
+const char kBreakOnFailureFlag[] = "break_on_failure";
+const char kCatchExceptionsFlag[] = "catch_exceptions";
+const char kColorFlag[] = "color";
+const char kFilterFlag[] = "filter";
+const char kListTestsFlag[] = "list_tests";
+const char kOutputFlag[] = "output";
+const char kPrintTimeFlag[] = "print_time";
+const char kRandomSeedFlag[] = "random_seed";
+const char kRepeatFlag[] = "repeat";
+const char kShuffleFlag[] = "shuffle";
+const char kStackTraceDepthFlag[] = "stack_trace_depth";
+const char kThrowOnFailureFlag[] = "throw_on_failure";
+
+// A valid random seed must be in [1, kMaxRandomSeed].
+const int kMaxRandomSeed = 99999;
+
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+GTEST_API_ extern bool g_help_flag;
+
+// Returns the current time in milliseconds.
+GTEST_API_ TimeInMillis GetTimeInMillis();
+
+// Returns true iff Google Test should use colors in the output.
+GTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
+
+// Formats the given time in milliseconds as seconds.
+GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
+
+// Parses a string for an Int32 flag, in the form of "--flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true. On failure, returns false without changing *value.
+GTEST_API_ bool ParseInt32Flag(
+ const char* str, const char* flag, Int32* value);
+
+// Returns a random seed in range [1, kMaxRandomSeed] based on the
+// given --gtest_random_seed flag value.
+inline int GetRandomSeedFromFlag(Int32 random_seed_flag) {
+ const unsigned int raw_seed = (random_seed_flag == 0) ?
+ static_cast<unsigned int>(GetTimeInMillis()) :
+ static_cast<unsigned int>(random_seed_flag);
+
+ // Normalizes the actual seed to range [1, kMaxRandomSeed] such that
+ // it's easy to type.
+ const int normalized_seed =
+ static_cast<int>((raw_seed - 1U) %
+ static_cast<unsigned int>(kMaxRandomSeed)) + 1;
+ return normalized_seed;
+}
+
+// Returns the first valid random seed after 'seed'. The behavior is
+// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is
+// considered to be 1.
+inline int GetNextRandomSeed(int seed) {
+ GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed)
+ << "Invalid random seed " << seed << " - must be in [1, "
+ << kMaxRandomSeed << "].";
+ const int next_seed = seed + 1;
+ return (next_seed > kMaxRandomSeed) ? 1 : next_seed;
+}
+
+// This class saves the values of all Google Test flags in its c'tor, and
+// restores them in its d'tor.
+class GTestFlagSaver {
+ public:
+ // The c'tor.
+ GTestFlagSaver() {
+ also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests);
+ break_on_failure_ = GTEST_FLAG(break_on_failure);
+ catch_exceptions_ = GTEST_FLAG(catch_exceptions);
+ color_ = GTEST_FLAG(color);
+ death_test_style_ = GTEST_FLAG(death_test_style);
+ death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);
+ filter_ = GTEST_FLAG(filter);
+ internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
+ list_tests_ = GTEST_FLAG(list_tests);
+ output_ = GTEST_FLAG(output);
+ print_time_ = GTEST_FLAG(print_time);
+ random_seed_ = GTEST_FLAG(random_seed);
+ repeat_ = GTEST_FLAG(repeat);
+ shuffle_ = GTEST_FLAG(shuffle);
+ stack_trace_depth_ = GTEST_FLAG(stack_trace_depth);
+ throw_on_failure_ = GTEST_FLAG(throw_on_failure);
+ }
+
+ // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS.
+ ~GTestFlagSaver() {
+ GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_;
+ GTEST_FLAG(break_on_failure) = break_on_failure_;
+ GTEST_FLAG(catch_exceptions) = catch_exceptions_;
+ GTEST_FLAG(color) = color_;
+ GTEST_FLAG(death_test_style) = death_test_style_;
+ GTEST_FLAG(death_test_use_fork) = death_test_use_fork_;
+ GTEST_FLAG(filter) = filter_;
+ GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;
+ GTEST_FLAG(list_tests) = list_tests_;
+ GTEST_FLAG(output) = output_;
+ GTEST_FLAG(print_time) = print_time_;
+ GTEST_FLAG(random_seed) = random_seed_;
+ GTEST_FLAG(repeat) = repeat_;
+ GTEST_FLAG(shuffle) = shuffle_;
+ GTEST_FLAG(stack_trace_depth) = stack_trace_depth_;
+ GTEST_FLAG(throw_on_failure) = throw_on_failure_;
+ }
+ private:
+ // Fields for saving the original values of flags.
+ bool also_run_disabled_tests_;
+ bool break_on_failure_;
+ bool catch_exceptions_;
+ String color_;
+ String death_test_style_;
+ bool death_test_use_fork_;
+ String filter_;
+ String internal_run_death_test_;
+ bool list_tests_;
+ String output_;
+ bool print_time_;
+ bool pretty_;
+ internal::Int32 random_seed_;
+ internal::Int32 repeat_;
+ bool shuffle_;
+ internal::Int32 stack_trace_depth_;
+ bool throw_on_failure_;
+} GTEST_ATTRIBUTE_UNUSED_;
+
+// Converts a Unicode code point to a narrow string in UTF-8 encoding.
+// code_point parameter is of type UInt32 because wchar_t may not be
+// wide enough to contain a code point.
+// The output buffer str must containt at least 32 characters.
+// The function returns the address of the output buffer.
+// If the code_point is not a valid Unicode code point
+// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'.
+GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str);
+
+// Converts a wide string to a narrow string in UTF-8 encoding.
+// The wide string is assumed to have the following encoding:
+// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+// UTF-32 if sizeof(wchar_t) == 4 (on Linux)
+// Parameter str points to a null-terminated wide string.
+// Parameter num_chars may additionally limit the number
+// of wchar_t characters processed. -1 is used when the entire string
+// should be processed.
+// If the string contains code points that are not valid Unicode code points
+// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
+// and contains invalid UTF-16 surrogate pairs, values in those pairs
+// will be encoded as individual Unicode characters from Basic Normal Plane.
+GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars);
+
+// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
+// if the variable is present. If a file already exists at this location, this
+// function will write over it. If the variable is present, but the file cannot
+// be created, prints an error and exits.
+void WriteToShardStatusFileIfNeeded();
+
+// Checks whether sharding is enabled by examining the relevant
+// environment variable values. If the variables are present,
+// but inconsistent (e.g., shard_index >= total_shards), prints
+// an error and exits. If in_subprocess_for_death_test, sharding is
+// disabled because it must only be applied to the original test
+// process. Otherwise, we could filter out death tests we intended to execute.
+GTEST_API_ bool ShouldShard(const char* total_shards_str,
+ const char* shard_index_str,
+ bool in_subprocess_for_death_test);
+
+// Parses the environment variable var as an Int32. If it is unset,
+// returns default_val. If it is not an Int32, prints an error and
+// and aborts.
+GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);
+
+// Given the total number of shards, the shard index, and the test id,
+// returns true iff the test should be run on this shard. The test id is
+// some arbitrary but unique non-negative integer assigned to each test
+// method. Assumes that 0 <= shard_index < total_shards.
+GTEST_API_ bool ShouldRunTestOnShard(
+ int total_shards, int shard_index, int test_id);
+
+// STL container utilities.
+
+// Returns the number of elements in the given container that satisfy
+// the given predicate.
+template <class Container, typename Predicate>
+inline int CountIf(const Container& c, Predicate predicate) {
+ return static_cast<int>(std::count_if(c.begin(), c.end(), predicate));
+}
+
+// Applies a function/functor to each element in the container.
+template <class Container, typename Functor>
+void ForEach(const Container& c, Functor functor) {
+ std::for_each(c.begin(), c.end(), functor);
+}
+
+// Returns the i-th element of the vector, or default_value if i is not
+// in range [0, v.size()).
+template <typename E>
+inline E GetElementOr(const std::vector<E>& v, int i, E default_value) {
+ return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i];
+}
+
+// Performs an in-place shuffle of a range of the vector's elements.
+// 'begin' and 'end' are element indices as an STL-style range;
+// i.e. [begin, end) are shuffled, where 'end' == size() means to
+// shuffle to the end of the vector.
+template <typename E>
+void ShuffleRange(internal::Random* random, int begin, int end,
+ std::vector<E>* v) {
+ const int size = static_cast<int>(v->size());
+ GTEST_CHECK_(0 <= begin && begin <= size)
+ << "Invalid shuffle range start " << begin << ": must be in range [0, "
+ << size << "].";
+ GTEST_CHECK_(begin <= end && end <= size)
+ << "Invalid shuffle range finish " << end << ": must be in range ["
+ << begin << ", " << size << "].";
+
+ // Fisher-Yates shuffle, from
+ // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
+ for (int range_width = end - begin; range_width >= 2; range_width--) {
+ const int last_in_range = begin + range_width - 1;
+ const int selected = begin + random->Generate(range_width);
+ std::swap((*v)[selected], (*v)[last_in_range]);
+ }
+}
+
+// Performs an in-place shuffle of the vector's elements.
+template <typename E>
+inline void Shuffle(internal::Random* random, std::vector<E>* v) {
+ ShuffleRange(random, 0, static_cast<int>(v->size()), v);
+}
+
+// A function for deleting an object. Handy for being used as a
+// functor.
+template <typename T>
+static void Delete(T* x) {
+ delete x;
+}
+
+// A predicate that checks the key of a TestProperty against a known key.
+//
+// TestPropertyKeyIs is copyable.
+class TestPropertyKeyIs {
+ public:
+ // Constructor.
+ //
+ // TestPropertyKeyIs has NO default constructor.
+ explicit TestPropertyKeyIs(const char* key)
+ : key_(key) {}
+
+ // Returns true iff the test name of test property matches on key_.
+ bool operator()(const TestProperty& test_property) const {
+ return String(test_property.key()).Compare(key_) == 0;
+ }
+
+ private:
+ String key_;
+};
+
+class TestInfoImpl {
+ public:
+ TestInfoImpl(TestInfo* parent, const char* test_case_name,
+ const char* name, const char* test_case_comment,
+ const char* comment, TypeId fixture_class_id,
+ internal::TestFactoryBase* factory);
+ ~TestInfoImpl();
+
+ // Returns true if this test should run.
+ bool should_run() const { return should_run_; }
+
+ // Sets the should_run member.
+ void set_should_run(bool should) { should_run_ = should; }
+
+ // Returns true if this test is disabled. Disabled tests are not run.
+ bool is_disabled() const { return is_disabled_; }
+
+ // Sets the is_disabled member.
+ void set_is_disabled(bool is) { is_disabled_ = is; }
+
+ // Returns true if this test matches the filter specified by the user.
+ bool matches_filter() const { return matches_filter_; }
+
+ // Sets the matches_filter member.
+ void set_matches_filter(bool matches) { matches_filter_ = matches; }
+
+ // Returns the test case name.
+ const char* test_case_name() const { return test_case_name_.c_str(); }
+
+ // Returns the test name.
+ const char* name() const { return name_.c_str(); }
+
+ // Returns the test case comment.
+ const char* test_case_comment() const { return test_case_comment_.c_str(); }
+
+ // Returns the test comment.
+ const char* comment() const { return comment_.c_str(); }
+
+ // Returns the ID of the test fixture class.
+ TypeId fixture_class_id() const { return fixture_class_id_; }
+
+ // Returns the test result.
+ TestResult* result() { return &result_; }
+ const TestResult* result() const { return &result_; }
+
+ // Creates the test object, runs it, records its result, and then
+ // deletes it.
+ void Run();
+
+ // Clears the test result.
+ void ClearResult() { result_.Clear(); }
+
+ // Clears the test result in the given TestInfo object.
+ static void ClearTestResult(TestInfo * test_info) {
+ test_info->impl()->ClearResult();
+ }
+
+ private:
+ // These fields are immutable properties of the test.
+ TestInfo* const parent_; // The owner of this object
+ const String test_case_name_; // Test case name
+ const String name_; // Test name
+ const String test_case_comment_; // Test case comment
+ const String comment_; // Test comment
+ const TypeId fixture_class_id_; // ID of the test fixture class
+ bool should_run_; // True iff this test should run
+ bool is_disabled_; // True iff this test is disabled
+ bool matches_filter_; // True if this test matches the
+ // user-specified filter.
+ internal::TestFactoryBase* const factory_; // The factory that creates
+ // the test object
+
+ // This field is mutable and needs to be reset before running the
+ // test for the second time.
+ TestResult result_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfoImpl);
+};
+
+// Class UnitTestOptions.
+//
+// This class contains functions for processing options the user
+// specifies when running the tests. It has only static members.
+//
+// In most cases, the user can specify an option using either an
+// environment variable or a command line flag. E.g. you can set the
+// test filter using either GTEST_FILTER or --gtest_filter. If both
+// the variable and the flag are present, the latter overrides the
+// former.
+class GTEST_API_ UnitTestOptions {
+ public:
+ // Functions for processing the gtest_output flag.
+
+ // Returns the output format, or "" for normal printed output.
+ static String GetOutputFormat();
+
+ // Returns the absolute path of the requested output file, or the
+ // default (test_detail.xml in the original working directory) if
+ // none was explicitly specified.
+ static String GetAbsolutePathToOutputFile();
+
+ // Functions for processing the gtest_filter flag.
+
+ // Returns true iff the wildcard pattern matches the string. The
+ // first ':' or '\0' character in pattern marks the end of it.
+ //
+ // This recursive algorithm isn't very efficient, but is clear and
+ // works well enough for matching test names, which are short.
+ static bool PatternMatchesString(const char *pattern, const char *str);
+
+ // Returns true iff the user-specified filter matches the test case
+ // name and the test name.
+ static bool FilterMatchesTest(const String &test_case_name,
+ const String &test_name);
+
+#if GTEST_OS_WINDOWS
+ // Function for supporting the gtest_catch_exception flag.
+
+ // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the
+ // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.
+ // This function is useful as an __except condition.
+ static int GTestShouldProcessSEH(DWORD exception_code);
+#endif // GTEST_OS_WINDOWS
+
+ // Returns true if "name" matches the ':' separated list of glob-style
+ // filters in "filter".
+ static bool MatchesFilter(const String& name, const char* filter);
+};
+
+// Returns the current application's name, removing directory path if that
+// is present. Used by UnitTestOptions::GetOutputFile.
+GTEST_API_ FilePath GetCurrentExecutableName();
+
+// The role interface for getting the OS stack trace as a string.
+class OsStackTraceGetterInterface {
+ public:
+ OsStackTraceGetterInterface() {}
+ virtual ~OsStackTraceGetterInterface() {}
+
+ // Returns the current OS stack trace as a String. Parameters:
+ //
+ // max_depth - the maximum number of stack frames to be included
+ // in the trace.
+ // skip_count - the number of top frames to be skipped; doesn't count
+ // against max_depth.
+ virtual String CurrentStackTrace(int max_depth, int skip_count) = 0;
+
+ // UponLeavingGTest() should be called immediately before Google Test calls
+ // user code. It saves some information about the current stack that
+ // CurrentStackTrace() will use to find and hide Google Test stack frames.
+ virtual void UponLeavingGTest() = 0;
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface);
+};
+
+// A working implementation of the OsStackTraceGetterInterface interface.
+class OsStackTraceGetter : public OsStackTraceGetterInterface {
+ public:
+ OsStackTraceGetter() : caller_frame_(NULL) {}
+ virtual String CurrentStackTrace(int max_depth, int skip_count);
+ virtual void UponLeavingGTest();
+
+ // This string is inserted in place of stack frames that are part of
+ // Google Test's implementation.
+ static const char* const kElidedFramesMarker;
+
+ private:
+ Mutex mutex_; // protects all internal state
+
+ // We save the stack frame below the frame that calls user code.
+ // We do this because the address of the frame immediately below
+ // the user code changes between the call to UponLeavingGTest()
+ // and any calls to CurrentStackTrace() from within the user code.
+ void* caller_frame_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter);
+};
+
+// Information about a Google Test trace point.
+struct TraceInfo {
+ const char* file;
+ int line;
+ String message;
+};
+
+// This is the default global test part result reporter used in UnitTestImpl.
+// This class should only be used by UnitTestImpl.
+class DefaultGlobalTestPartResultReporter
+ : public TestPartResultReporterInterface {
+ public:
+ explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);
+ // Implements the TestPartResultReporterInterface. Reports the test part
+ // result in the current test.
+ virtual void ReportTestPartResult(const TestPartResult& result);
+
+ private:
+ UnitTestImpl* const unit_test_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter);
+};
+
+// This is the default per thread test part result reporter used in
+// UnitTestImpl. This class should only be used by UnitTestImpl.
+class DefaultPerThreadTestPartResultReporter
+ : public TestPartResultReporterInterface {
+ public:
+ explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);
+ // Implements the TestPartResultReporterInterface. The implementation just
+ // delegates to the current global test part result reporter of *unit_test_.
+ virtual void ReportTestPartResult(const TestPartResult& result);
+
+ private:
+ UnitTestImpl* const unit_test_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter);
+};
+
+// The private implementation of the UnitTest class. We don't protect
+// the methods under a mutex, as this class is not accessible by a
+// user and the UnitTest class that delegates work to this class does
+// proper locking.
+class GTEST_API_ UnitTestImpl {
+ public:
+ explicit UnitTestImpl(UnitTest* parent);
+ virtual ~UnitTestImpl();
+
+ // There are two different ways to register your own TestPartResultReporter.
+ // You can register your own repoter to listen either only for test results
+ // from the current thread or for results from all threads.
+ // By default, each per-thread test result repoter just passes a new
+ // TestPartResult to the global test result reporter, which registers the
+ // test part result for the currently running test.
+
+ // Returns the global test part result reporter.
+ TestPartResultReporterInterface* GetGlobalTestPartResultReporter();
+
+ // Sets the global test part result reporter.
+ void SetGlobalTestPartResultReporter(
+ TestPartResultReporterInterface* reporter);
+
+ // Returns the test part result reporter for the current thread.
+ TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread();
+
+ // Sets the test part result reporter for the current thread.
+ void SetTestPartResultReporterForCurrentThread(
+ TestPartResultReporterInterface* reporter);
+
+ // Gets the number of successful test cases.
+ int successful_test_case_count() const;
+
+ // Gets the number of failed test cases.
+ int failed_test_case_count() const;
+
+ // Gets the number of all test cases.
+ int total_test_case_count() const;
+
+ // Gets the number of all test cases that contain at least one test
+ // that should run.
+ int test_case_to_run_count() const;
+
+ // Gets the number of successful tests.
+ int successful_test_count() const;
+
+ // Gets the number of failed tests.
+ int failed_test_count() const;
+
+ // Gets the number of disabled tests.
+ int disabled_test_count() const;
+
+ // Gets the number of all tests.
+ int total_test_count() const;
+
+ // Gets the number of tests that should run.
+ int test_to_run_count() const;
+
+ // Gets the elapsed time, in milliseconds.
+ TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+ // Returns true iff the unit test passed (i.e. all test cases passed).
+ bool Passed() const { return !Failed(); }
+
+ // Returns true iff the unit test failed (i.e. some test case failed
+ // or something outside of all tests failed).
+ bool Failed() const {
+ return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed();
+ }
+
+ // Gets the i-th test case among all the test cases. i can range from 0 to
+ // total_test_case_count() - 1. If i is not in that range, returns NULL.
+ const TestCase* GetTestCase(int i) const {
+ const int index = GetElementOr(test_case_indices_, i, -1);
+ return index < 0 ? NULL : test_cases_[i];
+ }
+
+ // Gets the i-th test case among all the test cases. i can range from 0 to
+ // total_test_case_count() - 1. If i is not in that range, returns NULL.
+ TestCase* GetMutableTestCase(int i) {
+ const int index = GetElementOr(test_case_indices_, i, -1);
+ return index < 0 ? NULL : test_cases_[index];
+ }
+
+ // Provides access to the event listener list.
+ TestEventListeners* listeners() { return &listeners_; }
+
+ // Returns the TestResult for the test that's currently running, or
+ // the TestResult for the ad hoc test if no test is running.
+ TestResult* current_test_result();
+
+ // Returns the TestResult for the ad hoc test.
+ const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }
+
+ // Sets the OS stack trace getter.
+ //
+ // Does nothing if the input and the current OS stack trace getter
+ // are the same; otherwise, deletes the old getter and makes the
+ // input the current getter.
+ void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter);
+
+ // Returns the current OS stack trace getter if it is not NULL;
+ // otherwise, creates an OsStackTraceGetter, makes it the current
+ // getter, and returns it.
+ OsStackTraceGetterInterface* os_stack_trace_getter();
+
+ // Returns the current OS stack trace as a String.
+ //
+ // The maximum number of stack frames to be included is specified by
+ // the gtest_stack_trace_depth flag. The skip_count parameter
+ // specifies the number of top frames to be skipped, which doesn't
+ // count against the number of frames to be included.
+ //
+ // For example, if Foo() calls Bar(), which in turn calls
+ // CurrentOsStackTraceExceptTop(1), Foo() will be included in the
+ // trace but Bar() and CurrentOsStackTraceExceptTop() won't.
+ String CurrentOsStackTraceExceptTop(int skip_count);
+
+ // Finds and returns a TestCase with the given name. If one doesn't
+ // exist, creates one and returns it.
+ //
+ // Arguments:
+ //
+ // test_case_name: name of the test case
+ // set_up_tc: pointer to the function that sets up the test case
+ // tear_down_tc: pointer to the function that tears down the test case
+ TestCase* GetTestCase(const char* test_case_name,
+ const char* comment,
+ Test::SetUpTestCaseFunc set_up_tc,
+ Test::TearDownTestCaseFunc tear_down_tc);
+
+ // Adds a TestInfo to the unit test.
+ //
+ // Arguments:
+ //
+ // set_up_tc: pointer to the function that sets up the test case
+ // tear_down_tc: pointer to the function that tears down the test case
+ // test_info: the TestInfo object
+ void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,
+ Test::TearDownTestCaseFunc tear_down_tc,
+ TestInfo * test_info) {
+ // In order to support thread-safe death tests, we need to
+ // remember the original working directory when the test program
+ // was first invoked. We cannot do this in RUN_ALL_TESTS(), as
+ // the user may have changed the current directory before calling
+ // RUN_ALL_TESTS(). Therefore we capture the current directory in
+ // AddTestInfo(), which is called to register a TEST or TEST_F
+ // before main() is reached.
+ if (original_working_dir_.IsEmpty()) {
+ original_working_dir_.Set(FilePath::GetCurrentDir());
+ GTEST_CHECK_(!original_working_dir_.IsEmpty())
+ << "Failed to get the current working directory.";
+ }
+
+ GetTestCase(test_info->test_case_name(),
+ test_info->test_case_comment(),
+ set_up_tc,
+ tear_down_tc)->AddTestInfo(test_info);
+ }
+
+#if GTEST_HAS_PARAM_TEST
+ // Returns ParameterizedTestCaseRegistry object used to keep track of
+ // value-parameterized tests and instantiate and register them.
+ internal::ParameterizedTestCaseRegistry& parameterized_test_registry() {
+ return parameterized_test_registry_;
+ }
+#endif // GTEST_HAS_PARAM_TEST
+
+ // Sets the TestCase object for the test that's currently running.
+ void set_current_test_case(TestCase* a_current_test_case) {
+ current_test_case_ = a_current_test_case;
+ }
+
+ // Sets the TestInfo object for the test that's currently running. If
+ // current_test_info is NULL, the assertion results will be stored in
+ // ad_hoc_test_result_.
+ void set_current_test_info(TestInfo* a_current_test_info) {
+ current_test_info_ = a_current_test_info;
+ }
+
+ // Registers all parameterized tests defined using TEST_P and
+ // INSTANTIATE_TEST_P, creating regular tests for each test/parameter
+ // combination. This method can be called more then once; it has
+ // guards protecting from registering the tests more then once.
+ // If value-parameterized tests are disabled, RegisterParameterizedTests
+ // is present but does nothing.
+ void RegisterParameterizedTests();
+
+ // Runs all tests in this UnitTest object, prints the result, and
+ // returns 0 if all tests are successful, or 1 otherwise. If any
+ // exception is thrown during a test on Windows, this test is
+ // considered to be failed, but the rest of the tests will still be
+ // run. (We disable exceptions on Linux and Mac OS X, so the issue
+ // doesn't apply there.)
+ int RunAllTests();
+
+ // Clears the results of all tests, including the ad hoc test.
+ void ClearResult() {
+ ForEach(test_cases_, TestCase::ClearTestCaseResult);
+ ad_hoc_test_result_.Clear();
+ }
+
+ enum ReactionToSharding {
+ HONOR_SHARDING_PROTOCOL,
+ IGNORE_SHARDING_PROTOCOL
+ };
+
+ // Matches the full name of each test against the user-specified
+ // filter to decide whether the test should run, then records the
+ // result in each TestCase and TestInfo object.
+ // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests
+ // based on sharding variables in the environment.
+ // Returns the number of tests that should run.
+ int FilterTests(ReactionToSharding shard_tests);
+
+ // Prints the names of the tests matching the user-specified filter flag.
+ void ListTestsMatchingFilter();
+
+ const TestCase* current_test_case() const { return current_test_case_; }
+ TestInfo* current_test_info() { return current_test_info_; }
+ const TestInfo* current_test_info() const { return current_test_info_; }
+
+ // Returns the vector of environments that need to be set-up/torn-down
+ // before/after the tests are run.
+ std::vector<Environment*>& environments() { return environments_; }
+
+ // Getters for the per-thread Google Test trace stack.
+ std::vector<TraceInfo>& gtest_trace_stack() {
+ return *(gtest_trace_stack_.pointer());
+ }
+ const std::vector<TraceInfo>& gtest_trace_stack() const {
+ return gtest_trace_stack_.get();
+ }
+
+#if GTEST_HAS_DEATH_TEST
+ void InitDeathTestSubprocessControlInfo() {
+ internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
+ }
+ // Returns a pointer to the parsed --gtest_internal_run_death_test
+ // flag, or NULL if that flag was not specified.
+ // This information is useful only in a death test child process.
+ // Must not be called before a call to InitGoogleTest.
+ const InternalRunDeathTestFlag* internal_run_death_test_flag() const {
+ return internal_run_death_test_flag_.get();
+ }
+
+ // Returns a pointer to the current death test factory.
+ internal::DeathTestFactory* death_test_factory() {
+ return death_test_factory_.get();
+ }
+
+ void SuppressTestEventsIfInSubprocess();
+
+ friend class ReplaceDeathTestFactory;
+#endif // GTEST_HAS_DEATH_TEST
+
+ // Initializes the event listener performing XML output as specified by
+ // UnitTestOptions. Must not be called before InitGoogleTest.
+ void ConfigureXmlOutput();
+
+ // Performs initialization dependent upon flag values obtained in
+ // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to
+ // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest
+ // this function is also called from RunAllTests. Since this function can be
+ // called more than once, it has to be idempotent.
+ void PostFlagParsingInit();
+
+ // Gets the random seed used at the start of the current test iteration.
+ int random_seed() const { return random_seed_; }
+
+ // Gets the random number generator.
+ internal::Random* random() { return &random_; }
+
+ // Shuffles all test cases, and the tests within each test case,
+ // making sure that death tests are still run first.
+ void ShuffleTests();
+
+ // Restores the test cases and tests to their order before the first shuffle.
+ void UnshuffleTests();
+
+ private:
+ friend class ::testing::UnitTest;
+
+ // The UnitTest object that owns this implementation object.
+ UnitTest* const parent_;
+
+ // The working directory when the first TEST() or TEST_F() was
+ // executed.
+ internal::FilePath original_working_dir_;
+
+ // The default test part result reporters.
+ DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;
+ DefaultPerThreadTestPartResultReporter
+ default_per_thread_test_part_result_reporter_;
+
+ // Points to (but doesn't own) the global test part result reporter.
+ TestPartResultReporterInterface* global_test_part_result_repoter_;
+
+ // Protects read and write access to global_test_part_result_reporter_.
+ internal::Mutex global_test_part_result_reporter_mutex_;
+
+ // Points to (but doesn't own) the per-thread test part result reporter.
+ internal::ThreadLocal<TestPartResultReporterInterface*>
+ per_thread_test_part_result_reporter_;
+
+ // The vector of environments that need to be set-up/torn-down
+ // before/after the tests are run.
+ std::vector<Environment*> environments_;
+
+ // The vector of TestCases in their original order. It owns the
+ // elements in the vector.
+ std::vector<TestCase*> test_cases_;
+
+ // Provides a level of indirection for the test case list to allow
+ // easy shuffling and restoring the test case order. The i-th
+ // element of this vector is the index of the i-th test case in the
+ // shuffled order.
+ std::vector<int> test_case_indices_;
+
+#if GTEST_HAS_PARAM_TEST
+ // ParameterizedTestRegistry object used to register value-parameterized
+ // tests.
+ internal::ParameterizedTestCaseRegistry parameterized_test_registry_;
+
+ // Indicates whether RegisterParameterizedTests() has been called already.
+ bool parameterized_tests_registered_;
+#endif // GTEST_HAS_PARAM_TEST
+
+ // Index of the last death test case registered. Initially -1.
+ int last_death_test_case_;
+
+ // This points to the TestCase for the currently running test. It
+ // changes as Google Test goes through one test case after another.
+ // When no test is running, this is set to NULL and Google Test
+ // stores assertion results in ad_hoc_test_result_. Initially NULL.
+ TestCase* current_test_case_;
+
+ // This points to the TestInfo for the currently running test. It
+ // changes as Google Test goes through one test after another. When
+ // no test is running, this is set to NULL and Google Test stores
+ // assertion results in ad_hoc_test_result_. Initially NULL.
+ TestInfo* current_test_info_;
+
+ // Normally, a user only writes assertions inside a TEST or TEST_F,
+ // or inside a function called by a TEST or TEST_F. Since Google
+ // Test keeps track of which test is current running, it can
+ // associate such an assertion with the test it belongs to.
+ //
+ // If an assertion is encountered when no TEST or TEST_F is running,
+ // Google Test attributes the assertion result to an imaginary "ad hoc"
+ // test, and records the result in ad_hoc_test_result_.
+ TestResult ad_hoc_test_result_;
+
+ // The list of event listeners that can be used to track events inside
+ // Google Test.
+ TestEventListeners listeners_;
+
+ // The OS stack trace getter. Will be deleted when the UnitTest
+ // object is destructed. By default, an OsStackTraceGetter is used,
+ // but the user can set this field to use a custom getter if that is
+ // desired.
+ OsStackTraceGetterInterface* os_stack_trace_getter_;
+
+ // True iff PostFlagParsingInit() has been called.
+ bool post_flag_parse_init_performed_;
+
+ // The random number seed used at the beginning of the test run.
+ int random_seed_;
+
+ // Our random number generator.
+ internal::Random random_;
+
+ // How long the test took to run, in milliseconds.
+ TimeInMillis elapsed_time_;
+
+#if GTEST_HAS_DEATH_TEST
+ // The decomposed components of the gtest_internal_run_death_test flag,
+ // parsed when RUN_ALL_TESTS is called.
+ internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;
+ internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_;
+#endif // GTEST_HAS_DEATH_TEST
+
+ // A per-thread stack of traces created by the SCOPED_TRACE() macro.
+ internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl);
+}; // class UnitTestImpl
+
+// Convenience function for accessing the global UnitTest
+// implementation object.
+inline UnitTestImpl* GetUnitTestImpl() {
+ return UnitTest::GetInstance()->impl();
+}
+
+// Internal helper functions for implementing the simple regular
+// expression matcher.
+GTEST_API_ bool IsInSet(char ch, const char* str);
+GTEST_API_ bool IsDigit(char ch);
+GTEST_API_ bool IsPunct(char ch);
+GTEST_API_ bool IsRepeat(char ch);
+GTEST_API_ bool IsWhiteSpace(char ch);
+GTEST_API_ bool IsWordChar(char ch);
+GTEST_API_ bool IsValidEscape(char ch);
+GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);
+GTEST_API_ bool ValidateRegex(const char* regex);
+GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);
+GTEST_API_ bool MatchRepetitionAndRegexAtHead(
+ bool escaped, char ch, char repeat, const char* regex, const char* str);
+GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
+
+#if GTEST_HAS_DEATH_TEST
+
+// Returns the message describing the last system error, regardless of the
+// platform.
+String GetLastErrnoDescription();
+
+#if GTEST_OS_WINDOWS
+// Provides leak-safe Windows kernel handle ownership.
+class AutoHandle {
+ public:
+ AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}
+ explicit AutoHandle(HANDLE handle) : handle_(handle) {}
+
+ ~AutoHandle() { Reset(); }
+
+ HANDLE Get() const { return handle_; }
+ void Reset() { Reset(INVALID_HANDLE_VALUE); }
+ void Reset(HANDLE handle) {
+ if (handle != handle_) {
+ if (handle_ != INVALID_HANDLE_VALUE)
+ ::CloseHandle(handle_);
+ handle_ = handle;
+ }
+ }
+
+ private:
+ HANDLE handle_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle);
+};
+#endif // GTEST_OS_WINDOWS
+
+// Attempts to parse a string into a positive integer pointed to by the
+// number parameter. Returns true if that is possible.
+// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use
+// it here.
+template <typename Integer>
+bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
+ // Fail fast if the given string does not begin with a digit;
+ // this bypasses strtoXXX's "optional leading whitespace and plus
+ // or minus sign" semantics, which are undesirable here.
+ if (str.empty() || !isdigit(str[0])) {
+ return false;
+ }
+ errno = 0;
+
+ char* end;
+ // BiggestConvertible is the largest integer type that system-provided
+ // string-to-number conversion routines can return.
+#if GTEST_OS_WINDOWS && !defined(__GNUC__)
+ // MSVC and C++ Builder define __int64 instead of the standard long long.
+ typedef unsigned __int64 BiggestConvertible;
+ const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10);
+#else
+ typedef unsigned long long BiggestConvertible; // NOLINT
+ const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10);
+#endif // GTEST_OS_WINDOWS && !defined(__GNUC__)
+ const bool parse_success = *end == '\0' && errno == 0;
+
+ // TODO(vladl@google.com): Convert this to compile time assertion when it is
+ // available.
+ GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));
+
+ const Integer result = static_cast<Integer>(parsed);
+ if (parse_success && static_cast<BiggestConvertible>(result) == parsed) {
+ *number = result;
+ return true;
+ }
+ return false;
+}
+#endif // GTEST_HAS_DEATH_TEST
+
+// TestResult contains some private methods that should be hidden from
+// Google Test user but are required for testing. This class allow our tests
+// to access them.
+//
+// This class is supplied only for the purpose of testing Google Test's own
+// constructs. Do not use it in user tests, either directly or indirectly.
+class TestResultAccessor {
+ public:
+ static void RecordProperty(TestResult* test_result,
+ const TestProperty& property) {
+ test_result->RecordProperty(property);
+ }
+
+ static void ClearTestPartResults(TestResult* test_result) {
+ test_result->ClearTestPartResults();
+ }
+
+ static const std::vector<testing::TestPartResult>& test_part_results(
+ const TestResult& test_result) {
+ return test_result.test_part_results();
+ }
+};
+
+} // namespace internal
+} // namespace testing
+
+#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_
+#undef GTEST_IMPLEMENTATION_
+
+#if GTEST_OS_WINDOWS
+#define vsnprintf _vsnprintf
+#endif // GTEST_OS_WINDOWS
+
+namespace testing {
+
+using internal::CountIf;
+using internal::ForEach;
+using internal::GetElementOr;
+using internal::Shuffle;
+
+// Constants.
+
+// A test whose test case name or test name matches this filter is
+// disabled and not run.
+static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*";
+
+// A test case whose name matches this filter is considered a death
+// test case and will be run before test cases whose name doesn't
+// match this filter.
+static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
+
+// A test filter that matches everything.
+static const char kUniversalFilter[] = "*";
+
+// The default output file for XML output.
+static const char kDefaultOutputFile[] = "test_detail.xml";
+
+// The environment variable name for the test shard index.
+static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
+// The environment variable name for the total number of test shards.
+static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
+// The environment variable name for the test shard status file.
+static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE";
+
+namespace internal {
+
+// The text used in failure messages to indicate the start of the
+// stack trace.
+const char kStackTraceMarker[] = "\nStack trace:\n";
+
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+bool g_help_flag = false;
+
+} // namespace internal
+
+GTEST_DEFINE_bool_(
+ also_run_disabled_tests,
+ internal::BoolFromGTestEnv("also_run_disabled_tests", false),
+ "Run disabled tests too, in addition to the tests normally being run.");
+
+GTEST_DEFINE_bool_(
+ break_on_failure,
+ internal::BoolFromGTestEnv("break_on_failure", false),
+ "True iff a failed assertion should be a debugger break-point.");
+
+GTEST_DEFINE_bool_(
+ catch_exceptions,
+ internal::BoolFromGTestEnv("catch_exceptions", false),
+ "True iff " GTEST_NAME_
+ " should catch exceptions and treat them as test failures.");
+
+GTEST_DEFINE_string_(
+ color,
+ internal::StringFromGTestEnv("color", "auto"),
+ "Whether to use colors in the output. Valid values: yes, no, "
+ "and auto. 'auto' means to use colors if the output is "
+ "being sent to a terminal and the TERM environment variable "
+ "is set to xterm, xterm-color, xterm-256color, linux or cygwin.");
+
+GTEST_DEFINE_string_(
+ filter,
+ internal::StringFromGTestEnv("filter", kUniversalFilter),
+ "A colon-separated list of glob (not regex) patterns "
+ "for filtering the tests to run, optionally followed by a "
+ "'-' and a : separated list of negative patterns (tests to "
+ "exclude). A test is run if it matches one of the positive "
+ "patterns and does not match any of the negative patterns.");
+
+GTEST_DEFINE_bool_(list_tests, false,
+ "List all tests without running them.");
+
+GTEST_DEFINE_string_(
+ output,
+ internal::StringFromGTestEnv("output", ""),
+ "A format (currently must be \"xml\"), optionally followed "
+ "by a colon and an output file name or directory. A directory "
+ "is indicated by a trailing pathname separator. "
+ "Examples: \"xml:filename.xml\", \"xml::directoryname/\". "
+ "If a directory is specified, output files will be created "
+ "within that directory, with file-names based on the test "
+ "executable's name and, if necessary, made unique by adding "
+ "digits.");
+
+GTEST_DEFINE_bool_(
+ print_time,
+ internal::BoolFromGTestEnv("print_time", true),
+ "True iff " GTEST_NAME_
+ " should display elapsed time in text output.");
+
+GTEST_DEFINE_int32_(
+ random_seed,
+ internal::Int32FromGTestEnv("random_seed", 0),
+ "Random number seed to use when shuffling test orders. Must be in range "
+ "[1, 99999], or 0 to use a seed based on the current time.");
+
+GTEST_DEFINE_int32_(
+ repeat,
+ internal::Int32FromGTestEnv("repeat", 1),
+ "How many times to repeat each test. Specify a negative number "
+ "for repeating forever. Useful for shaking out flaky tests.");
+
+GTEST_DEFINE_bool_(
+ show_internal_stack_frames, false,
+ "True iff " GTEST_NAME_ " should include internal stack frames when "
+ "printing test failure stack traces.");
+
+GTEST_DEFINE_bool_(
+ shuffle,
+ internal::BoolFromGTestEnv("shuffle", false),
+ "True iff " GTEST_NAME_
+ " should randomize tests' order on every run.");
+
+GTEST_DEFINE_int32_(
+ stack_trace_depth,
+ internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth),
+ "The maximum number of stack frames to print when an "
+ "assertion fails. The valid range is 0 through 100, inclusive.");
+
+GTEST_DEFINE_bool_(
+ throw_on_failure,
+ internal::BoolFromGTestEnv("throw_on_failure", false),
+ "When this flag is specified, a failed assertion will throw an exception "
+ "if exceptions are enabled or exit the program with a non-zero code "
+ "otherwise.");
+
+namespace internal {
+
+// Generates a random number from [0, range), using a Linear
+// Congruential Generator (LCG). Crashes if 'range' is 0 or greater
+// than kMaxRange.
+UInt32 Random::Generate(UInt32 range) {
+ // These constants are the same as are used in glibc's rand(3).
+ state_ = (1103515245U*state_ + 12345U) % kMaxRange;
+
+ GTEST_CHECK_(range > 0)
+ << "Cannot generate a number in the range [0, 0).";
+ GTEST_CHECK_(range <= kMaxRange)
+ << "Generation of a number in [0, " << range << ") was requested, "
+ << "but this can only generate numbers in [0, " << kMaxRange << ").";
+
+ // Converting via modulus introduces a bit of downward bias, but
+ // it's simple, and a linear congruential generator isn't too good
+ // to begin with.
+ return state_ % range;
+}
+
+// GTestIsInitialized() returns true iff the user has initialized
+// Google Test. Useful for catching the user mistake of not initializing
+// Google Test before calling RUN_ALL_TESTS().
+//
+// A user must call testing::InitGoogleTest() to initialize Google
+// Test. g_init_gtest_count is set to the number of times
+// InitGoogleTest() has been called. We don't protect this variable
+// under a mutex as it is only accessed in the main thread.
+int g_init_gtest_count = 0;
+static bool GTestIsInitialized() { return g_init_gtest_count != 0; }
+
+// Iterates over a vector of TestCases, keeping a running sum of the
+// results of calling a given int-returning method on each.
+// Returns the sum.
+static int SumOverTestCaseList(const std::vector<TestCase*>& case_list,
+ int (TestCase::*method)() const) {
+ int sum = 0;
+ for (size_t i = 0; i < case_list.size(); i++) {
+ sum += (case_list[i]->*method)();
+ }
+ return sum;
+}
+
+// Returns true iff the test case passed.
+static bool TestCasePassed(const TestCase* test_case) {
+ return test_case->should_run() && test_case->Passed();
+}
+
+// Returns true iff the test case failed.
+static bool TestCaseFailed(const TestCase* test_case) {
+ return test_case->should_run() && test_case->Failed();
+}
+
+// Returns true iff test_case contains at least one test that should
+// run.
+static bool ShouldRunTestCase(const TestCase* test_case) {
+ return test_case->should_run();
+}
+
+// AssertHelper constructor.
+AssertHelper::AssertHelper(TestPartResult::Type type,
+ const char* file,
+ int line,
+ const char* message)
+ : data_(new AssertHelperData(type, file, line, message)) {
+}
+
+AssertHelper::~AssertHelper() {
+ delete data_;
+}
+
+// Message assignment, for assertion streaming support.
+void AssertHelper::operator=(const Message& message) const {
+ UnitTest::GetInstance()->
+ AddTestPartResult(data_->type, data_->file, data_->line,
+ AppendUserMessage(data_->message, message),
+ UnitTest::GetInstance()->impl()
+ ->CurrentOsStackTraceExceptTop(1)
+ // Skips the stack frame for this function itself.
+ ); // NOLINT
+}
+
+// Mutex for linked pointers.
+GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
+
+// Application pathname gotten in InitGoogleTest.
+String g_executable_path;
+
+// Returns the current application's name, removing directory path if that
+// is present.
+FilePath GetCurrentExecutableName() {
+ FilePath result;
+
+#if GTEST_OS_WINDOWS
+ result.Set(FilePath(g_executable_path).RemoveExtension("exe"));
+#else
+ result.Set(FilePath(g_executable_path));
+#endif // GTEST_OS_WINDOWS
+
+ return result.RemoveDirectoryName();
+}
+
+// Functions for processing the gtest_output flag.
+
+// Returns the output format, or "" for normal printed output.
+String UnitTestOptions::GetOutputFormat() {
+ const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
+ if (gtest_output_flag == NULL) return String("");
+
+ const char* const colon = strchr(gtest_output_flag, ':');
+ return (colon == NULL) ?
+ String(gtest_output_flag) :
+ String(gtest_output_flag, colon - gtest_output_flag);
+}
+
+// Returns the name of the requested output file, or the default if none
+// was explicitly specified.
+String UnitTestOptions::GetAbsolutePathToOutputFile() {
+ const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
+ if (gtest_output_flag == NULL)
+ return String("");
+
+ const char* const colon = strchr(gtest_output_flag, ':');
+ if (colon == NULL)
+ return String(internal::FilePath::ConcatPaths(
+ internal::FilePath(
+ UnitTest::GetInstance()->original_working_dir()),
+ internal::FilePath(kDefaultOutputFile)).ToString() );
+
+ internal::FilePath output_name(colon + 1);
+ if (!output_name.IsAbsolutePath())
+ // TODO(wan@google.com): on Windows \some\path is not an absolute
+ // path (as its meaning depends on the current drive), yet the
+ // following logic for turning it into an absolute path is wrong.
+ // Fix it.
+ output_name = internal::FilePath::ConcatPaths(
+ internal::FilePath(UnitTest::GetInstance()->original_working_dir()),
+ internal::FilePath(colon + 1));
+
+ if (!output_name.IsDirectory())
+ return output_name.ToString();
+
+ internal::FilePath result(internal::FilePath::GenerateUniqueFileName(
+ output_name, internal::GetCurrentExecutableName(),
+ GetOutputFormat().c_str()));
+ return result.ToString();
+}
+
+// Returns true iff the wildcard pattern matches the string. The
+// first ':' or '\0' character in pattern marks the end of it.
+//
+// This recursive algorithm isn't very efficient, but is clear and
+// works well enough for matching test names, which are short.
+bool UnitTestOptions::PatternMatchesString(const char *pattern,
+ const char *str) {
+ switch (*pattern) {
+ case '\0':
+ case ':': // Either ':' or '\0' marks the end of the pattern.
+ return *str == '\0';
+ case '?': // Matches any single character.
+ return *str != '\0' && PatternMatchesString(pattern + 1, str + 1);
+ case '*': // Matches any string (possibly empty) of characters.
+ return (*str != '\0' && PatternMatchesString(pattern, str + 1)) ||
+ PatternMatchesString(pattern + 1, str);
+ default: // Non-special character. Matches itself.
+ return *pattern == *str &&
+ PatternMatchesString(pattern + 1, str + 1);
+ }
+}
+
+bool UnitTestOptions::MatchesFilter(const String& name, const char* filter) {
+ const char *cur_pattern = filter;
+ for (;;) {
+ if (PatternMatchesString(cur_pattern, name.c_str())) {
+ return true;
+ }
+
+ // Finds the next pattern in the filter.
+ cur_pattern = strchr(cur_pattern, ':');
+
+ // Returns if no more pattern can be found.
+ if (cur_pattern == NULL) {
+ return false;
+ }
+
+ // Skips the pattern separater (the ':' character).
+ cur_pattern++;
+ }
+}
+
+// TODO(keithray): move String function implementations to gtest-string.cc.
+
+// Returns true iff the user-specified filter matches the test case
+// name and the test name.
+bool UnitTestOptions::FilterMatchesTest(const String &test_case_name,
+ const String &test_name) {
+ const String& full_name = String::Format("%s.%s",
+ test_case_name.c_str(),
+ test_name.c_str());
+
+ // Split --gtest_filter at '-', if there is one, to separate into
+ // positive filter and negative filter portions
+ const char* const p = GTEST_FLAG(filter).c_str();
+ const char* const dash = strchr(p, '-');
+ String positive;
+ String negative;
+ if (dash == NULL) {
+ positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter
+ negative = String("");
+ } else {
+ positive = String(p, dash - p); // Everything up to the dash
+ negative = String(dash+1); // Everything after the dash
+ if (positive.empty()) {
+ // Treat '-test1' as the same as '*-test1'
+ positive = kUniversalFilter;
+ }
+ }
+
+ // A filter is a colon-separated list of patterns. It matches a
+ // test if any pattern in it matches the test.
+ return (MatchesFilter(full_name, positive.c_str()) &&
+ !MatchesFilter(full_name, negative.c_str()));
+}
+
+#if GTEST_OS_WINDOWS
+// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the
+// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.
+// This function is useful as an __except condition.
+int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
+ // Google Test should handle an exception if:
+ // 1. the user wants it to, AND
+ // 2. this is not a breakpoint exception.
+ return (GTEST_FLAG(catch_exceptions) &&
+ exception_code != EXCEPTION_BREAKPOINT) ?
+ EXCEPTION_EXECUTE_HANDLER :
+ EXCEPTION_CONTINUE_SEARCH;
+}
+#endif // GTEST_OS_WINDOWS
+
+} // namespace internal
+
+// The c'tor sets this object as the test part result reporter used by
+// Google Test. The 'result' parameter specifies where to report the
+// results. Intercepts only failures from the current thread.
+ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(
+ TestPartResultArray* result)
+ : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD),
+ result_(result) {
+ Init();
+}
+
+// The c'tor sets this object as the test part result reporter used by
+// Google Test. The 'result' parameter specifies where to report the
+// results.
+ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(
+ InterceptMode intercept_mode, TestPartResultArray* result)
+ : intercept_mode_(intercept_mode),
+ result_(result) {
+ Init();
+}
+
+void ScopedFakeTestPartResultReporter::Init() {
+ internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+ if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
+ old_reporter_ = impl->GetGlobalTestPartResultReporter();
+ impl->SetGlobalTestPartResultReporter(this);
+ } else {
+ old_reporter_ = impl->GetTestPartResultReporterForCurrentThread();
+ impl->SetTestPartResultReporterForCurrentThread(this);
+ }
+}
+
+// The d'tor restores the test part result reporter used by Google Test
+// before.
+ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() {
+ internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+ if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
+ impl->SetGlobalTestPartResultReporter(old_reporter_);
+ } else {
+ impl->SetTestPartResultReporterForCurrentThread(old_reporter_);
+ }
+}
+
+// Increments the test part result count and remembers the result.
+// This method is from the TestPartResultReporterInterface interface.
+void ScopedFakeTestPartResultReporter::ReportTestPartResult(
+ const TestPartResult& result) {
+ result_->Append(result);
+}
+
+namespace internal {
+
+// Returns the type ID of ::testing::Test. We should always call this
+// instead of GetTypeId< ::testing::Test>() to get the type ID of
+// testing::Test. This is to work around a suspected linker bug when
+// using Google Test as a framework on Mac OS X. The bug causes
+// GetTypeId< ::testing::Test>() to return different values depending
+// on whether the call is from the Google Test framework itself or
+// from user test code. GetTestTypeId() is guaranteed to always
+// return the same value, as it always calls GetTypeId<>() from the
+// gtest.cc, which is within the Google Test framework.
+TypeId GetTestTypeId() {
+ return GetTypeId<Test>();
+}
+
+// The value of GetTestTypeId() as seen from within the Google Test
+// library. This is solely for testing GetTestTypeId().
+extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId();
+
+// This predicate-formatter checks that 'results' contains a test part
+// failure of the given type and that the failure message contains the
+// given substring.
+AssertionResult HasOneFailure(const char* /* results_expr */,
+ const char* /* type_expr */,
+ const char* /* substr_expr */,
+ const TestPartResultArray& results,
+ TestPartResult::Type type,
+ const char* substr) {
+ const String expected(type == TestPartResult::kFatalFailure ?
+ "1 fatal failure" :
+ "1 non-fatal failure");
+ Message msg;
+ if (results.size() != 1) {
+ msg << "Expected: " << expected << "\n"
+ << " Actual: " << results.size() << " failures";
+ for (int i = 0; i < results.size(); i++) {
+ msg << "\n" << results.GetTestPartResult(i);
+ }
+ return AssertionFailure(msg);
+ }
+
+ const TestPartResult& r = results.GetTestPartResult(0);
+ if (r.type() != type) {
+ msg << "Expected: " << expected << "\n"
+ << " Actual:\n"
+ << r;
+ return AssertionFailure(msg);
+ }
+
+ if (strstr(r.message(), substr) == NULL) {
+ msg << "Expected: " << expected << " containing \""
+ << substr << "\"\n"
+ << " Actual:\n"
+ << r;
+ return AssertionFailure(msg);
+ }
+
+ return AssertionSuccess();
+}
+
+// The constructor of SingleFailureChecker remembers where to look up
+// test part results, what type of failure we expect, and what
+// substring the failure message should contain.
+SingleFailureChecker:: SingleFailureChecker(
+ const TestPartResultArray* results,
+ TestPartResult::Type type,
+ const char* substr)
+ : results_(results),
+ type_(type),
+ substr_(substr) {}
+
+// The destructor of SingleFailureChecker verifies that the given
+// TestPartResultArray contains exactly one failure that has the given
+// type and contains the given substring. If that's not the case, a
+// non-fatal failure will be generated.
+SingleFailureChecker::~SingleFailureChecker() {
+ EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_.c_str());
+}
+
+DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(
+ UnitTestImpl* unit_test) : unit_test_(unit_test) {}
+
+void DefaultGlobalTestPartResultReporter::ReportTestPartResult(
+ const TestPartResult& result) {
+ unit_test_->current_test_result()->AddTestPartResult(result);
+ unit_test_->listeners()->repeater()->OnTestPartResult(result);
+}
+
+DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(
+ UnitTestImpl* unit_test) : unit_test_(unit_test) {}
+
+void DefaultPerThreadTestPartResultReporter::ReportTestPartResult(
+ const TestPartResult& result) {
+ unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result);
+}
+
+// Returns the global test part result reporter.
+TestPartResultReporterInterface*
+UnitTestImpl::GetGlobalTestPartResultReporter() {
+ internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
+ return global_test_part_result_repoter_;
+}
+
+// Sets the global test part result reporter.
+void UnitTestImpl::SetGlobalTestPartResultReporter(
+ TestPartResultReporterInterface* reporter) {
+ internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
+ global_test_part_result_repoter_ = reporter;
+}
+
+// Returns the test part result reporter for the current thread.
+TestPartResultReporterInterface*
+UnitTestImpl::GetTestPartResultReporterForCurrentThread() {
+ return per_thread_test_part_result_reporter_.get();
+}
+
+// Sets the test part result reporter for the current thread.
+void UnitTestImpl::SetTestPartResultReporterForCurrentThread(
+ TestPartResultReporterInterface* reporter) {
+ per_thread_test_part_result_reporter_.set(reporter);
+}
+
+// Gets the number of successful test cases.
+int UnitTestImpl::successful_test_case_count() const {
+ return CountIf(test_cases_, TestCasePassed);
+}
+
+// Gets the number of failed test cases.
+int UnitTestImpl::failed_test_case_count() const {
+ return CountIf(test_cases_, TestCaseFailed);
+}
+
+// Gets the number of all test cases.
+int UnitTestImpl::total_test_case_count() const {
+ return static_cast<int>(test_cases_.size());
+}
+
+// Gets the number of all test cases that contain at least one test
+// that should run.
+int UnitTestImpl::test_case_to_run_count() const {
+ return CountIf(test_cases_, ShouldRunTestCase);
+}
+
+// Gets the number of successful tests.
+int UnitTestImpl::successful_test_count() const {
+ return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count);
+}
+
+// Gets the number of failed tests.
+int UnitTestImpl::failed_test_count() const {
+ return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count);
+}
+
+// Gets the number of disabled tests.
+int UnitTestImpl::disabled_test_count() const {
+ return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count);
+}
+
+// Gets the number of all tests.
+int UnitTestImpl::total_test_count() const {
+ return SumOverTestCaseList(test_cases_, &TestCase::total_test_count);
+}
+
+// Gets the number of tests that should run.
+int UnitTestImpl::test_to_run_count() const {
+ return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count);
+}
+
+// Returns the current OS stack trace as a String.
+//
+// The maximum number of stack frames to be included is specified by
+// the gtest_stack_trace_depth flag. The skip_count parameter
+// specifies the number of top frames to be skipped, which doesn't
+// count against the number of frames to be included.
+//
+// For example, if Foo() calls Bar(), which in turn calls
+// CurrentOsStackTraceExceptTop(1), Foo() will be included in the
+// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
+String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
+ (void)skip_count;
+ return String("");
+}
+
+// Returns the current time in milliseconds.
+TimeInMillis GetTimeInMillis() {
+#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__)
+ // Difference between 1970-01-01 and 1601-01-01 in milliseconds.
+ // http://analogous.blogspot.com/2005/04/epoch.html
+ const TimeInMillis kJavaEpochToWinFileTimeDelta =
+ static_cast<TimeInMillis>(116444736UL) * 100000UL;
+ const DWORD kTenthMicrosInMilliSecond = 10000;
+
+ SYSTEMTIME now_systime;
+ FILETIME now_filetime;
+ ULARGE_INTEGER now_int64;
+ // TODO(kenton@google.com): Shouldn't this just use
+ // GetSystemTimeAsFileTime()?
+ GetSystemTime(&now_systime);
+ if (SystemTimeToFileTime(&now_systime, &now_filetime)) {
+ now_int64.LowPart = now_filetime.dwLowDateTime;
+ now_int64.HighPart = now_filetime.dwHighDateTime;
+ now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) -
+ kJavaEpochToWinFileTimeDelta;
+ return now_int64.QuadPart;
+ }
+ return 0;
+#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_
+ __timeb64 now;
+#ifdef _MSC_VER
+ // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996
+ // (deprecated function) there.
+ // TODO(kenton@google.com): Use GetTickCount()? Or use
+ // SystemTimeToFileTime()
+#pragma warning(push) // Saves the current warning state.
+#pragma warning(disable:4996) // Temporarily disables warning 4996.
+ _ftime64(&now);
+#pragma warning(pop) // Restores the warning state.
+#else
+ _ftime64(&now);
+#endif // _MSC_VER
+ return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm;
+#elif GTEST_HAS_GETTIMEOFDAY_
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000;
+#else
+#error "Don't know how to get the current time on your system."
+#endif
+}
+
+// Utilities
+
+// class String
+
+// Returns the input enclosed in double quotes if it's not NULL;
+// otherwise returns "(null)". For example, "\"Hello\"" is returned
+// for input "Hello".
+//
+// This is useful for printing a C string in the syntax of a literal.
+//
+// Known issue: escape sequences are not handled yet.
+String String::ShowCStringQuoted(const char* c_str) {
+ return c_str ? String::Format("\"%s\"", c_str) : String("(null)");
+}
+
+// Copies at most length characters from str into a newly-allocated
+// piece of memory of size length+1. The memory is allocated with new[].
+// A terminating null byte is written to the memory, and a pointer to it
+// is returned. If str is NULL, NULL is returned.
+static char* CloneString(const char* str, size_t length) {
+ if (str == NULL) {
+ return NULL;
+ } else {
+ char* const clone = new char[length + 1];
+ posix::StrNCpy(clone, str, length);
+ clone[length] = '\0';
+ return clone;
+ }
+}
+
+// Clones a 0-terminated C string, allocating memory using new. The
+// caller is responsible for deleting[] the return value. Returns the
+// cloned string, or NULL if the input is NULL.
+const char * String::CloneCString(const char* c_str) {
+ return (c_str == NULL) ?
+ NULL : CloneString(c_str, strlen(c_str));
+}
+
+#if GTEST_OS_WINDOWS_MOBILE
+// Creates a UTF-16 wide string from the given ANSI string, allocating
+// memory using new. The caller is responsible for deleting the return
+// value using delete[]. Returns the wide string, or NULL if the
+// input is NULL.
+LPCWSTR String::AnsiToUtf16(const char* ansi) {
+ if (!ansi) return NULL;
+ const int length = strlen(ansi);
+ const int unicode_length =
+ MultiByteToWideChar(CP_ACP, 0, ansi, length,
+ NULL, 0);
+ WCHAR* unicode = new WCHAR[unicode_length + 1];
+ MultiByteToWideChar(CP_ACP, 0, ansi, length,
+ unicode, unicode_length);
+ unicode[unicode_length] = 0;
+ return unicode;
+}
+
+// Creates an ANSI string from the given wide string, allocating
+// memory using new. The caller is responsible for deleting the return
+// value using delete[]. Returns the ANSI string, or NULL if the
+// input is NULL.
+const char* String::Utf16ToAnsi(LPCWSTR utf16_str) {
+ if (!utf16_str) return NULL;
+ const int ansi_length =
+ WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
+ NULL, 0, NULL, NULL);
+ char* ansi = new char[ansi_length + 1];
+ WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
+ ansi, ansi_length, NULL, NULL);
+ ansi[ansi_length] = 0;
+ return ansi;
+}
+
+#endif // GTEST_OS_WINDOWS_MOBILE
+
+// Compares two C strings. Returns true iff they have the same content.
+//
+// Unlike strcmp(), this function can handle NULL argument(s). A NULL
+// C string is considered different to any non-NULL C string,
+// including the empty string.
+bool String::CStringEquals(const char * lhs, const char * rhs) {
+ if ( lhs == NULL ) return rhs == NULL;
+
+ if ( rhs == NULL ) return false;
+
+ return strcmp(lhs, rhs) == 0;
+}
+
+#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
+
+// Converts an array of wide chars to a narrow string using the UTF-8
+// encoding, and streams the result to the given Message object.
+static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,
+ Message* msg) {
+ // TODO(wan): consider allowing a testing::String object to
+ // contain '\0'. This will make it behave more like std::string,
+ // and will allow ToUtf8String() to return the correct encoding
+ // for '\0' s.t. we can get rid of the conditional here (and in
+ // several other places).
+ for (size_t i = 0; i != length; ) { // NOLINT
+ if (wstr[i] != L'\0') {
+ *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i));
+ while (i != length && wstr[i] != L'\0')
+ i++;
+ } else {
+ *msg << '\0';
+ i++;
+ }
+ }
+}
+
+#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
+
+} // namespace internal
+
+#if GTEST_HAS_STD_WSTRING
+// Converts the given wide string to a narrow string using the UTF-8
+// encoding, and streams the result to this Message object.
+Message& Message::operator <<(const ::std::wstring& wstr) {
+ internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);
+ return *this;
+}
+#endif // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+// Converts the given wide string to a narrow string using the UTF-8
+// encoding, and streams the result to this Message object.
+Message& Message::operator <<(const ::wstring& wstr) {
+ internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);
+ return *this;
+}
+#endif // GTEST_HAS_GLOBAL_WSTRING
+
+namespace internal {
+
+// Formats a value to be used in a failure message.
+
+// For a char value, we print it as a C++ char literal and as an
+// unsigned integer (both in decimal and in hexadecimal).
+String FormatForFailureMessage(char ch) {
+ const unsigned int ch_as_uint = ch;
+ // A String object cannot contain '\0', so we print "\\0" when ch is
+ // '\0'.
+ return String::Format("'%s' (%u, 0x%X)",
+ ch ? String::Format("%c", ch).c_str() : "\\0",
+ ch_as_uint, ch_as_uint);
+}
+
+// For a wchar_t value, we print it as a C++ wchar_t literal and as an
+// unsigned integer (both in decimal and in hexidecimal).
+String FormatForFailureMessage(wchar_t wchar) {
+ // The C++ standard doesn't specify the exact size of the wchar_t
+ // type. It just says that it shall have the same size as another
+ // integral type, called its underlying type.
+ //
+ // Therefore, in order to print a wchar_t value in the numeric form,
+ // we first convert it to the largest integral type (UInt64) and
+ // then print the converted value.
+ //
+ // We use streaming to print the value as "%llu" doesn't work
+ // correctly with MSVC 7.1.
+ const UInt64 wchar_as_uint64 = wchar;
+ Message msg;
+ // A String object cannot contain '\0', so we print "\\0" when wchar is
+ // L'\0'.
+ char buffer[32]; // CodePointToUtf8 requires a buffer that big.
+ msg << "L'"
+ << (wchar ? CodePointToUtf8(static_cast<UInt32>(wchar), buffer) : "\\0")
+ << "' (" << wchar_as_uint64 << ", 0x" << ::std::setbase(16)
+ << wchar_as_uint64 << ")";
+ return msg.GetString();
+}
+
+} // namespace internal
+
+// AssertionResult constructors.
+// Used in EXPECT_TRUE/FALSE(assertion_result).
+AssertionResult::AssertionResult(const AssertionResult& other)
+ : success_(other.success_),
+ message_(other.message_.get() != NULL ?
+ new internal::String(*other.message_) :
+ static_cast<internal::String*>(NULL)) {
+}
+
+// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
+AssertionResult AssertionResult::operator!() const {
+ AssertionResult negation(!success_);
+ if (message_.get() != NULL)
+ negation << *message_;
+ return negation;
+}
+
+// Makes a successful assertion result.
+AssertionResult AssertionSuccess() {
+ return AssertionResult(true);
+}
+
+// Makes a failed assertion result.
+AssertionResult AssertionFailure() {
+ return AssertionResult(false);
+}
+
+// Makes a failed assertion result with the given failure message.
+// Deprecated; use AssertionFailure() << message.
+AssertionResult AssertionFailure(const Message& message) {
+ return AssertionFailure() << message;
+}
+
+namespace internal {
+
+// Constructs and returns the message for an equality assertion
+// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
+//
+// The first four parameters are the expressions used in the assertion
+// and their values, as strings. For example, for ASSERT_EQ(foo, bar)
+// where foo is 5 and bar is 6, we have:
+//
+// expected_expression: "foo"
+// actual_expression: "bar"
+// expected_value: "5"
+// actual_value: "6"
+//
+// The ignoring_case parameter is true iff the assertion is a
+// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will
+// be inserted into the message.
+AssertionResult EqFailure(const char* expected_expression,
+ const char* actual_expression,
+ const String& expected_value,
+ const String& actual_value,
+ bool ignoring_case) {
+ Message msg;
+ msg << "Value of: " << actual_expression;
+ if (actual_value != actual_expression) {
+ msg << "\n Actual: " << actual_value;
+ }
+
+ msg << "\nExpected: " << expected_expression;
+ if (ignoring_case) {
+ msg << " (ignoring case)";
+ }
+ if (expected_value != expected_expression) {
+ msg << "\nWhich is: " << expected_value;
+ }
+
+ return AssertionFailure(msg);
+}
+
+// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
+String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result,
+ const char* expression_text,
+ const char* actual_predicate_value,
+ const char* expected_predicate_value) {
+ const char* actual_message = assertion_result.message();
+ Message msg;
+ msg << "Value of: " << expression_text
+ << "\n Actual: " << actual_predicate_value;
+ if (actual_message[0] != '\0')
+ msg << " (" << actual_message << ")";
+ msg << "\nExpected: " << expected_predicate_value;
+ return msg.GetString();
+}
+
+// Helper function for implementing ASSERT_NEAR.
+AssertionResult DoubleNearPredFormat(const char* expr1,
+ const char* expr2,
+ const char* abs_error_expr,
+ double val1,
+ double val2,
+ double abs_error) {
+ const double diff = fabs(val1 - val2);
+ if (diff <= abs_error) return AssertionSuccess();
+
+ // TODO(wan): do not print the value of an expression if it's
+ // already a literal.
+ Message msg;
+ msg << "The difference between " << expr1 << " and " << expr2
+ << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n"
+ << expr1 << " evaluates to " << val1 << ",\n"
+ << expr2 << " evaluates to " << val2 << ", and\n"
+ << abs_error_expr << " evaluates to " << abs_error << ".";
+ return AssertionFailure(msg);
+}
+
+
+// Helper template for implementing FloatLE() and DoubleLE().
+template <typename RawType>
+AssertionResult FloatingPointLE(const char* expr1,
+ const char* expr2,
+ RawType val1,
+ RawType val2) {
+ // Returns success if val1 is less than val2,
+ if (val1 < val2) {
+ return AssertionSuccess();
+ }
+
+ // or if val1 is almost equal to val2.
+ const FloatingPoint<RawType> lhs(val1), rhs(val2);
+ if (lhs.AlmostEquals(rhs)) {
+ return AssertionSuccess();
+ }
+
+ // Note that the above two checks will both fail if either val1 or
+ // val2 is NaN, as the IEEE floating-point standard requires that
+ // any predicate involving a NaN must return false.
+
+ StrStream val1_ss;
+ val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+ << val1;
+
+ StrStream val2_ss;
+ val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+ << val2;
+
+ Message msg;
+ msg << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n"
+ << " Actual: " << StrStreamToString(&val1_ss) << " vs "
+ << StrStreamToString(&val2_ss);
+
+ return AssertionFailure(msg);
+}
+
+} // namespace internal
+
+// Asserts that val1 is less than, or almost equal to, val2. Fails
+// otherwise. In particular, it fails if either val1 or val2 is NaN.
+AssertionResult FloatLE(const char* expr1, const char* expr2,
+ float val1, float val2) {
+ return internal::FloatingPointLE<float>(expr1, expr2, val1, val2);
+}
+
+// Asserts that val1 is less than, or almost equal to, val2. Fails
+// otherwise. In particular, it fails if either val1 or val2 is NaN.
+AssertionResult DoubleLE(const char* expr1, const char* expr2,
+ double val1, double val2) {
+ return internal::FloatingPointLE<double>(expr1, expr2, val1, val2);
+}
+
+namespace internal {
+
+// The helper function for {ASSERT|EXPECT}_EQ with int or enum
+// arguments.
+AssertionResult CmpHelperEQ(const char* expected_expression,
+ const char* actual_expression,
+ BiggestInt expected,
+ BiggestInt actual) {
+ if (expected == actual) {
+ return AssertionSuccess();
+ }
+
+ return EqFailure(expected_expression,
+ actual_expression,
+ FormatForComparisonFailureMessage(expected, actual),
+ FormatForComparisonFailureMessage(actual, expected),
+ false);
+}
+
+// A macro for implementing the helper functions needed to implement
+// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here
+// just to avoid copy-and-paste of similar code.
+#define GTEST_IMPL_CMP_HELPER_(op_name, op)\
+AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
+ BiggestInt val1, BiggestInt val2) {\
+ if (val1 op val2) {\
+ return AssertionSuccess();\
+ } else {\
+ Message msg;\
+ msg << "Expected: (" << expr1 << ") " #op " (" << expr2\
+ << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\
+ << " vs " << FormatForComparisonFailureMessage(val2, val1);\
+ return AssertionFailure(msg);\
+ }\
+}
+
+// Implements the helper function for {ASSERT|EXPECT}_NE with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(NE, !=)
+// Implements the helper function for {ASSERT|EXPECT}_LE with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(LE, <=)
+// Implements the helper function for {ASSERT|EXPECT}_LT with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(LT, < )
+// Implements the helper function for {ASSERT|EXPECT}_GE with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(GE, >=)
+// Implements the helper function for {ASSERT|EXPECT}_GT with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(GT, > )
+
+#undef GTEST_IMPL_CMP_HELPER_
+
+// The helper function for {ASSERT|EXPECT}_STREQ.
+AssertionResult CmpHelperSTREQ(const char* expected_expression,
+ const char* actual_expression,
+ const char* expected,
+ const char* actual) {
+ if (String::CStringEquals(expected, actual)) {
+ return AssertionSuccess();
+ }
+
+ return EqFailure(expected_expression,
+ actual_expression,
+ String::ShowCStringQuoted(expected),
+ String::ShowCStringQuoted(actual),
+ false);
+}
+
+// The helper function for {ASSERT|EXPECT}_STRCASEEQ.
+AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,
+ const char* actual_expression,
+ const char* expected,
+ const char* actual) {
+ if (String::CaseInsensitiveCStringEquals(expected, actual)) {
+ return AssertionSuccess();
+ }
+
+ return EqFailure(expected_expression,
+ actual_expression,
+ String::ShowCStringQuoted(expected),
+ String::ShowCStringQuoted(actual),
+ true);
+}
+
+// The helper function for {ASSERT|EXPECT}_STRNE.
+AssertionResult CmpHelperSTRNE(const char* s1_expression,
+ const char* s2_expression,
+ const char* s1,
+ const char* s2) {
+ if (!String::CStringEquals(s1, s2)) {
+ return AssertionSuccess();
+ } else {
+ Message msg;
+ msg << "Expected: (" << s1_expression << ") != ("
+ << s2_expression << "), actual: \""
+ << s1 << "\" vs \"" << s2 << "\"";
+ return AssertionFailure(msg);
+ }
+}
+
+// The helper function for {ASSERT|EXPECT}_STRCASENE.
+AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
+ const char* s2_expression,
+ const char* s1,
+ const char* s2) {
+ if (!String::CaseInsensitiveCStringEquals(s1, s2)) {
+ return AssertionSuccess();
+ } else {
+ Message msg;
+ msg << "Expected: (" << s1_expression << ") != ("
+ << s2_expression << ") (ignoring case), actual: \""
+ << s1 << "\" vs \"" << s2 << "\"";
+ return AssertionFailure(msg);
+ }
+}
+
+} // namespace internal
+
+namespace {
+
+// Helper functions for implementing IsSubString() and IsNotSubstring().
+
+// This group of overloaded functions return true iff needle is a
+// substring of haystack. NULL is considered a substring of itself
+// only.
+
+bool IsSubstringPred(const char* needle, const char* haystack) {
+ if (needle == NULL || haystack == NULL)
+ return needle == haystack;
+
+ return strstr(haystack, needle) != NULL;
+}
+
+bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {
+ if (needle == NULL || haystack == NULL)
+ return needle == haystack;
+
+ return wcsstr(haystack, needle) != NULL;
+}
+
+// StringType here can be either ::std::string or ::std::wstring.
+template <typename StringType>
+bool IsSubstringPred(const StringType& needle,
+ const StringType& haystack) {
+ return haystack.find(needle) != StringType::npos;
+}
+
+// This function implements either IsSubstring() or IsNotSubstring(),
+// depending on the value of the expected_to_be_substring parameter.
+// StringType here can be const char*, const wchar_t*, ::std::string,
+// or ::std::wstring.
+template <typename StringType>
+AssertionResult IsSubstringImpl(
+ bool expected_to_be_substring,
+ const char* needle_expr, const char* haystack_expr,
+ const StringType& needle, const StringType& haystack) {
+ if (IsSubstringPred(needle, haystack) == expected_to_be_substring)
+ return AssertionSuccess();
+
+ const bool is_wide_string = sizeof(needle[0]) > 1;
+ const char* const begin_string_quote = is_wide_string ? "L\"" : "\"";
+ return AssertionFailure(
+ Message()
+ << "Value of: " << needle_expr << "\n"
+ << " Actual: " << begin_string_quote << needle << "\"\n"
+ << "Expected: " << (expected_to_be_substring ? "" : "not ")
+ << "a substring of " << haystack_expr << "\n"
+ << "Which is: " << begin_string_quote << haystack << "\"");
+}
+
+} // namespace
+
+// IsSubstring() and IsNotSubstring() check whether needle is a
+// substring of haystack (NULL is considered a substring of itself
+// only), and return an appropriate error message when they fail.
+
+AssertionResult IsSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const char* needle, const char* haystack) {
+ return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const wchar_t* needle, const wchar_t* haystack) {
+ return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const char* needle, const char* haystack) {
+ return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const wchar_t* needle, const wchar_t* haystack) {
+ return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const ::std::string& needle, const ::std::string& haystack) {
+ return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const ::std::string& needle, const ::std::string& haystack) {
+ return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+
+#if GTEST_HAS_STD_WSTRING
+AssertionResult IsSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const ::std::wstring& needle, const ::std::wstring& haystack) {
+ return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const ::std::wstring& needle, const ::std::wstring& haystack) {
+ return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+#endif // GTEST_HAS_STD_WSTRING
+
+namespace internal {
+
+#if GTEST_OS_WINDOWS
+
+namespace {
+
+// Helper function for IsHRESULT{SuccessFailure} predicates
+AssertionResult HRESULTFailureHelper(const char* expr,
+ const char* expected,
+ long hr) { // NOLINT
+#if GTEST_OS_WINDOWS_MOBILE
+ // Windows CE doesn't support FormatMessage.
+ const char error_text[] = "";
+#else
+ // Looks up the human-readable system message for the HRESULT code
+ // and since we're not passing any params to FormatMessage, we don't
+ // want inserts expanded.
+ const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS;
+ const DWORD kBufSize = 4096; // String::Format can't exceed this length.
+ // Gets the system's human readable message string for this HRESULT.
+ char error_text[kBufSize] = { '\0' };
+ DWORD message_length = ::FormatMessageA(kFlags,
+ 0, // no source, we're asking system
+ hr, // the error
+ 0, // no line width restrictions
+ error_text, // output buffer
+ kBufSize, // buf size
+ NULL); // no arguments for inserts
+ // Trims tailing white space (FormatMessage leaves a trailing cr-lf)
+ for (; message_length && isspace(error_text[message_length - 1]);
+ --message_length) {
+ error_text[message_length - 1] = '\0';
+ }
+#endif // GTEST_OS_WINDOWS_MOBILE
+
+ const String error_hex(String::Format("0x%08X ", hr));
+ Message msg;
+ msg << "Expected: " << expr << " " << expected << ".\n"
+ << " Actual: " << error_hex << error_text << "\n";
+
+ return ::testing::AssertionFailure(msg);
+}
+
+} // namespace
+
+AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT
+ if (SUCCEEDED(hr)) {
+ return AssertionSuccess();
+ }
+ return HRESULTFailureHelper(expr, "succeeds", hr);
+}
+
+AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT
+ if (FAILED(hr)) {
+ return AssertionSuccess();
+ }
+ return HRESULTFailureHelper(expr, "fails", hr);
+}
+
+#endif // GTEST_OS_WINDOWS
+
+// Utility functions for encoding Unicode text (wide strings) in
+// UTF-8.
+
+// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8
+// like this:
+//
+// Code-point length Encoding
+// 0 - 7 bits 0xxxxxxx
+// 8 - 11 bits 110xxxxx 10xxxxxx
+// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx
+// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+
+// The maximum code-point a one-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint1 = (static_cast<UInt32>(1) << 7) - 1;
+
+// The maximum code-point a two-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint2 = (static_cast<UInt32>(1) << (5 + 6)) - 1;
+
+// The maximum code-point a three-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint3 = (static_cast<UInt32>(1) << (4 + 2*6)) - 1;
+
+// The maximum code-point a four-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint4 = (static_cast<UInt32>(1) << (3 + 3*6)) - 1;
+
+// Chops off the n lowest bits from a bit pattern. Returns the n
+// lowest bits. As a side effect, the original bit pattern will be
+// shifted to the right by n bits.
+inline UInt32 ChopLowBits(UInt32* bits, int n) {
+ const UInt32 low_bits = *bits & ((static_cast<UInt32>(1) << n) - 1);
+ *bits >>= n;
+ return low_bits;
+}
+
+// Converts a Unicode code point to a narrow string in UTF-8 encoding.
+// code_point parameter is of type UInt32 because wchar_t may not be
+// wide enough to contain a code point.
+// The output buffer str must containt at least 32 characters.
+// The function returns the address of the output buffer.
+// If the code_point is not a valid Unicode code point
+// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'.
+char* CodePointToUtf8(UInt32 code_point, char* str) {
+ if (code_point <= kMaxCodePoint1) {
+ str[1] = '\0';
+ str[0] = static_cast<char>(code_point); // 0xxxxxxx
+ } else if (code_point <= kMaxCodePoint2) {
+ str[2] = '\0';
+ str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx
+ str[0] = static_cast<char>(0xC0 | code_point); // 110xxxxx
+ } else if (code_point <= kMaxCodePoint3) {
+ str[3] = '\0';
+ str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx
+ str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx
+ str[0] = static_cast<char>(0xE0 | code_point); // 1110xxxx
+ } else if (code_point <= kMaxCodePoint4) {
+ str[4] = '\0';
+ str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx
+ str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx
+ str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx
+ str[0] = static_cast<char>(0xF0 | code_point); // 11110xxx
+ } else {
+ // The longest string String::Format can produce when invoked
+ // with these parameters is 28 character long (not including
+ // the terminating nul character). We are asking for 32 character
+ // buffer just in case. This is also enough for strncpy to
+ // null-terminate the destination string.
+ posix::StrNCpy(
+ str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), 32);
+ str[31] = '\0'; // Makes sure no change in the format to strncpy leaves
+ // the result unterminated.
+ }
+ return str;
+}
+
+// The following two functions only make sense if the the system
+// uses UTF-16 for wide string encoding. All supported systems
+// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16.
+
+// Determines if the arguments constitute UTF-16 surrogate pair
+// and thus should be combined into a single Unicode code point
+// using CreateCodePointFromUtf16SurrogatePair.
+inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {
+ return sizeof(wchar_t) == 2 &&
+ (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00;
+}
+
+// Creates a Unicode code point from UTF16 surrogate pair.
+inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first,
+ wchar_t second) {
+ const UInt32 mask = (1 << 10) - 1;
+ return (sizeof(wchar_t) == 2) ?
+ (((first & mask) << 10) | (second & mask)) + 0x10000 :
+ // This function should not be called when the condition is
+ // false, but we provide a sensible default in case it is.
+ static_cast<UInt32>(first);
+}
+
+// Converts a wide string to a narrow string in UTF-8 encoding.
+// The wide string is assumed to have the following encoding:
+// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+// UTF-32 if sizeof(wchar_t) == 4 (on Linux)
+// Parameter str points to a null-terminated wide string.
+// Parameter num_chars may additionally limit the number
+// of wchar_t characters processed. -1 is used when the entire string
+// should be processed.
+// If the string contains code points that are not valid Unicode code points
+// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
+// and contains invalid UTF-16 surrogate pairs, values in those pairs
+// will be encoded as individual Unicode characters from Basic Normal Plane.
+String WideStringToUtf8(const wchar_t* str, int num_chars) {
+ if (num_chars == -1)
+ num_chars = static_cast<int>(wcslen(str));
+
+ StrStream stream;
+ for (int i = 0; i < num_chars; ++i) {
+ UInt32 unicode_code_point;
+
+ if (str[i] == L'\0') {
+ break;
+ } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) {
+ unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i],
+ str[i + 1]);
+ i++;
+ } else {
+ unicode_code_point = static_cast<UInt32>(str[i]);
+ }
+
+ char buffer[32]; // CodePointToUtf8 requires a buffer this big.
+ stream << CodePointToUtf8(unicode_code_point, buffer);
+ }
+ return StrStreamToString(&stream);
+}
+
+// Converts a wide C string to a String using the UTF-8 encoding.
+// NULL will be converted to "(null)".
+String String::ShowWideCString(const wchar_t * wide_c_str) {
+ if (wide_c_str == NULL) return String("(null)");
+
+ return String(internal::WideStringToUtf8(wide_c_str, -1).c_str());
+}
+
+// Similar to ShowWideCString(), except that this function encloses
+// the converted string in double quotes.
+String String::ShowWideCStringQuoted(const wchar_t* wide_c_str) {
+ if (wide_c_str == NULL) return String("(null)");
+
+ return String::Format("L\"%s\"",
+ String::ShowWideCString(wide_c_str).c_str());
+}
+
+// Compares two wide C strings. Returns true iff they have the same
+// content.
+//
+// Unlike wcscmp(), this function can handle NULL argument(s). A NULL
+// C string is considered different to any non-NULL C string,
+// including the empty string.
+bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) {
+ if (lhs == NULL) return rhs == NULL;
+
+ if (rhs == NULL) return false;
+
+ return wcscmp(lhs, rhs) == 0;
+}
+
+// Helper function for *_STREQ on wide strings.
+AssertionResult CmpHelperSTREQ(const char* expected_expression,
+ const char* actual_expression,
+ const wchar_t* expected,
+ const wchar_t* actual) {
+ if (String::WideCStringEquals(expected, actual)) {
+ return AssertionSuccess();
+ }
+
+ return EqFailure(expected_expression,
+ actual_expression,
+ String::ShowWideCStringQuoted(expected),
+ String::ShowWideCStringQuoted(actual),
+ false);
+}
+
+// Helper function for *_STRNE on wide strings.
+AssertionResult CmpHelperSTRNE(const char* s1_expression,
+ const char* s2_expression,
+ const wchar_t* s1,
+ const wchar_t* s2) {
+ if (!String::WideCStringEquals(s1, s2)) {
+ return AssertionSuccess();
+ }
+
+ Message msg;
+ msg << "Expected: (" << s1_expression << ") != ("
+ << s2_expression << "), actual: "
+ << String::ShowWideCStringQuoted(s1)
+ << " vs " << String::ShowWideCStringQuoted(s2);
+ return AssertionFailure(msg);
+}
+
+// Compares two C strings, ignoring case. Returns true iff they have
+// the same content.
+//
+// Unlike strcasecmp(), this function can handle NULL argument(s). A
+// NULL C string is considered different to any non-NULL C string,
+// including the empty string.
+bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) {
+ if (lhs == NULL)
+ return rhs == NULL;
+ if (rhs == NULL)
+ return false;
+ return posix::StrCaseCmp(lhs, rhs) == 0;
+}
+
+ // Compares two wide C strings, ignoring case. Returns true iff they
+ // have the same content.
+ //
+ // Unlike wcscasecmp(), this function can handle NULL argument(s).
+ // A NULL C string is considered different to any non-NULL wide C string,
+ // including the empty string.
+ // NB: The implementations on different platforms slightly differ.
+ // On windows, this method uses _wcsicmp which compares according to LC_CTYPE
+ // environment variable. On GNU platform this method uses wcscasecmp
+ // which compares according to LC_CTYPE category of the current locale.
+ // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
+ // current locale.
+bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
+ const wchar_t* rhs) {
+ if ( lhs == NULL ) return rhs == NULL;
+
+ if ( rhs == NULL ) return false;
+
+#if GTEST_OS_WINDOWS
+ return _wcsicmp(lhs, rhs) == 0;
+#elif GTEST_OS_LINUX
+ return wcscasecmp(lhs, rhs) == 0;
+#else
+ // Mac OS X and Cygwin don't define wcscasecmp. Other unknown OSes
+ // may not define it either.
+ wint_t left, right;
+ do {
+ left = towlower(*lhs++);
+ right = towlower(*rhs++);
+ } while (left && left == right);
+ return left == right;
+#endif // OS selector
+}
+
+// Compares this with another String.
+// Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0
+// if this is greater than rhs.
+int String::Compare(const String & rhs) const {
+ const char* const lhs_c_str = c_str();
+ const char* const rhs_c_str = rhs.c_str();
+
+ if (lhs_c_str == NULL) {
+ return rhs_c_str == NULL ? 0 : -1; // NULL < anything except NULL
+ } else if (rhs_c_str == NULL) {
+ return 1;
+ }
+
+ const size_t shorter_str_len =
+ length() <= rhs.length() ? length() : rhs.length();
+ for (size_t i = 0; i != shorter_str_len; i++) {
+ if (lhs_c_str[i] < rhs_c_str[i]) {
+ return -1;
+ } else if (lhs_c_str[i] > rhs_c_str[i]) {
+ return 1;
+ }
+ }
+ return (length() < rhs.length()) ? -1 :
+ (length() > rhs.length()) ? 1 : 0;
+}
+
+// Returns true iff this String ends with the given suffix. *Any*
+// String is considered to end with a NULL or empty suffix.
+bool String::EndsWith(const char* suffix) const {
+ if (suffix == NULL || CStringEquals(suffix, "")) return true;
+
+ if (c_str() == NULL) return false;
+
+ const size_t this_len = strlen(c_str());
+ const size_t suffix_len = strlen(suffix);
+ return (this_len >= suffix_len) &&
+ CStringEquals(c_str() + this_len - suffix_len, suffix);
+}
+
+// Returns true iff this String ends with the given suffix, ignoring case.
+// Any String is considered to end with a NULL or empty suffix.
+bool String::EndsWithCaseInsensitive(const char* suffix) const {
+ if (suffix == NULL || CStringEquals(suffix, "")) return true;
+
+ if (c_str() == NULL) return false;
+
+ const size_t this_len = strlen(c_str());
+ const size_t suffix_len = strlen(suffix);
+ return (this_len >= suffix_len) &&
+ CaseInsensitiveCStringEquals(c_str() + this_len - suffix_len, suffix);
+}
+
+// Formats a list of arguments to a String, using the same format
+// spec string as for printf.
+//
+// We do not use the StringPrintf class as it is not universally
+// available.
+//
+// The result is limited to 4096 characters (including the tailing 0).
+// If 4096 characters are not enough to format the input, or if
+// there's an error, "<formatting error or buffer exceeded>" is
+// returned.
+String String::Format(const char * format, ...) {
+ va_list args;
+ va_start(args, format);
+
+ char buffer[4096];
+ const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]);
+
+ // MSVC 8 deprecates vsnprintf(), so we want to suppress warning
+ // 4996 (deprecated function) there.
+#ifdef _MSC_VER // We are using MSVC.
+#pragma warning(push) // Saves the current warning state.
+#pragma warning(disable:4996) // Temporarily disables warning 4996.
+ const int size = vsnprintf(buffer, kBufferSize, format, args);
+#pragma warning(pop) // Restores the warning state.
+#else // We are not using MSVC.
+ const int size = vsnprintf(buffer, kBufferSize, format, args);
+#endif // _MSC_VER
+ va_end(args);
+
+ // vsnprintf()'s behavior is not portable. When the buffer is not
+ // big enough, it returns a negative value in MSVC, and returns the
+ // needed buffer size on Linux. When there is an output error, it
+ // always returns a negative value. For simplicity, we lump the two
+ // error cases together.
+ if (size < 0 || size >= kBufferSize) {
+ return String("<formatting error or buffer exceeded>");
+ } else {
+ return String(buffer, size);
+ }
+}
+
+// Converts the buffer in a StrStream to a String, converting NUL
+// bytes to "\\0" along the way.
+String StrStreamToString(StrStream* ss) {
+ const ::std::string& str = ss->str();
+ const char* const start = str.c_str();
+ const char* const end = start + str.length();
+
+ // We need to use a helper StrStream to do this transformation
+ // because String doesn't support push_back().
+ StrStream helper;
+ for (const char* ch = start; ch != end; ++ch) {
+ if (*ch == '\0') {
+ helper << "\\0"; // Replaces NUL with "\\0";
+ } else {
+ helper.put(*ch);
+ }
+ }
+
+ return String(helper.str().c_str());
+}
+
+// Appends the user-supplied message to the Google-Test-generated message.
+String AppendUserMessage(const String& gtest_msg,
+ const Message& user_msg) {
+ // Appends the user message if it's non-empty.
+ const String user_msg_string = user_msg.GetString();
+ if (user_msg_string.empty()) {
+ return gtest_msg;
+ }
+
+ Message msg;
+ msg << gtest_msg << "\n" << user_msg_string;
+
+ return msg.GetString();
+}
+
+} // namespace internal
+
+// class TestResult
+
+// Creates an empty TestResult.
+TestResult::TestResult()
+ : death_test_count_(0),
+ elapsed_time_(0) {
+}
+
+// D'tor.
+TestResult::~TestResult() {
+}
+
+// Returns the i-th test part result among all the results. i can
+// range from 0 to total_part_count() - 1. If i is not in that range,
+// aborts the program.
+const TestPartResult& TestResult::GetTestPartResult(int i) const {
+ if (i < 0 || i >= total_part_count())
+ internal::posix::Abort();
+ return test_part_results_.at(i);
+}
+
+// Returns the i-th test property. i can range from 0 to
+// test_property_count() - 1. If i is not in that range, aborts the
+// program.
+const TestProperty& TestResult::GetTestProperty(int i) const {
+ if (i < 0 || i >= test_property_count())
+ internal::posix::Abort();
+ return test_properties_.at(i);
+}
+
+// Clears the test part results.
+void TestResult::ClearTestPartResults() {
+ test_part_results_.clear();
+}
+
+// Adds a test part result to the list.
+void TestResult::AddTestPartResult(const TestPartResult& test_part_result) {
+ test_part_results_.push_back(test_part_result);
+}
+
+// Adds a test property to the list. If a property with the same key as the
+// supplied property is already represented, the value of this test_property
+// replaces the old value for that key.
+void TestResult::RecordProperty(const TestProperty& test_property) {
+ if (!ValidateTestProperty(test_property)) {
+ return;
+ }
+ internal::MutexLock lock(&test_properites_mutex_);
+ const std::vector<TestProperty>::iterator property_with_matching_key =
+ std::find_if(test_properties_.begin(), test_properties_.end(),
+ internal::TestPropertyKeyIs(test_property.key()));
+ if (property_with_matching_key == test_properties_.end()) {
+ test_properties_.push_back(test_property);
+ return;
+ }
+ property_with_matching_key->SetValue(test_property.value());
+}
+
+// Adds a failure if the key is a reserved attribute of Google Test
+// testcase tags. Returns true if the property is valid.
+bool TestResult::ValidateTestProperty(const TestProperty& test_property) {
+ internal::String key(test_property.key());
+ if (key == "name" || key == "status" || key == "time" || key == "classname") {
+ ADD_FAILURE()
+ << "Reserved key used in RecordProperty(): "
+ << key
+ << " ('name', 'status', 'time', and 'classname' are reserved by "
+ << GTEST_NAME_ << ")";
+ return false;
+ }
+ return true;
+}
+
+// Clears the object.
+void TestResult::Clear() {
+ test_part_results_.clear();
+ test_properties_.clear();
+ death_test_count_ = 0;
+ elapsed_time_ = 0;
+}
+
+// Returns true iff the test failed.
+bool TestResult::Failed() const {
+ for (int i = 0; i < total_part_count(); ++i) {
+ if (GetTestPartResult(i).failed())
+ return true;
+ }
+ return false;
+}
+
+// Returns true iff the test part fatally failed.
+static bool TestPartFatallyFailed(const TestPartResult& result) {
+ return result.fatally_failed();
+}
+
+// Returns true iff the test fatally failed.
+bool TestResult::HasFatalFailure() const {
+ return CountIf(test_part_results_, TestPartFatallyFailed) > 0;
+}
+
+// Returns true iff the test part non-fatally failed.
+static bool TestPartNonfatallyFailed(const TestPartResult& result) {
+ return result.nonfatally_failed();
+}
+
+// Returns true iff the test has a non-fatal failure.
+bool TestResult::HasNonfatalFailure() const {
+ return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0;
+}
+
+// Gets the number of all test parts. This is the sum of the number
+// of successful test parts and the number of failed test parts.
+int TestResult::total_part_count() const {
+ return static_cast<int>(test_part_results_.size());
+}
+
+// Returns the number of the test properties.
+int TestResult::test_property_count() const {
+ return static_cast<int>(test_properties_.size());
+}
+
+// class Test
+
+// Creates a Test object.
+
+// The c'tor saves the values of all Google Test flags.
+Test::Test()
+ : gtest_flag_saver_(new internal::GTestFlagSaver) {
+}
+
+// The d'tor restores the values of all Google Test flags.
+Test::~Test() {
+ delete gtest_flag_saver_;
+}
+
+// Sets up the test fixture.
+//
+// A sub-class may override this.
+void Test::SetUp() {
+}
+
+// Tears down the test fixture.
+//
+// A sub-class may override this.
+void Test::TearDown() {
+}
+
+// Allows user supplied key value pairs to be recorded for later output.
+void Test::RecordProperty(const char* key, const char* value) {
+ UnitTest::GetInstance()->RecordPropertyForCurrentTest(key, value);
+}
+
+// Allows user supplied key value pairs to be recorded for later output.
+void Test::RecordProperty(const char* key, int value) {
+ Message value_message;
+ value_message << value;
+ RecordProperty(key, value_message.GetString().c_str());
+}
+
+namespace internal {
+
+void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
+ const String& message) {
+ // This function is a friend of UnitTest and as such has access to
+ // AddTestPartResult.
+ UnitTest::GetInstance()->AddTestPartResult(
+ result_type,
+ NULL, // No info about the source file where the exception occurred.
+ -1, // We have no info on which line caused the exception.
+ message,
+ String()); // No stack trace, either.
+}
+
+} // namespace internal
+
+#if GTEST_OS_WINDOWS
+// We are on Windows.
+
+// Adds an "exception thrown" fatal failure to the current test.
+static void AddExceptionThrownFailure(DWORD exception_code,
+ const char* location) {
+ Message message;
+ message << "Exception thrown with code 0x" << std::setbase(16) <<
+ exception_code << std::setbase(10) << " in " << location << ".";
+
+ internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure,
+ message.GetString());
+}
+
+#endif // GTEST_OS_WINDOWS
+
+// Google Test requires all tests in the same test case to use the same test
+// fixture class. This function checks if the current test has the
+// same fixture class as the first test in the current test case. If
+// yes, it returns true; otherwise it generates a Google Test failure and
+// returns false.
+bool Test::HasSameFixtureClass() {
+ internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+ const TestCase* const test_case = impl->current_test_case();
+
+ // Info about the first test in the current test case.
+ const internal::TestInfoImpl* const first_test_info =
+ test_case->test_info_list()[0]->impl();
+ const internal::TypeId first_fixture_id = first_test_info->fixture_class_id();
+ const char* const first_test_name = first_test_info->name();
+
+ // Info about the current test.
+ const internal::TestInfoImpl* const this_test_info =
+ impl->current_test_info()->impl();
+ const internal::TypeId this_fixture_id = this_test_info->fixture_class_id();
+ const char* const this_test_name = this_test_info->name();
+
+ if (this_fixture_id != first_fixture_id) {
+ // Is the first test defined using TEST?
+ const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId();
+ // Is this test defined using TEST?
+ const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId();
+
+ if (first_is_TEST || this_is_TEST) {
+ // The user mixed TEST and TEST_F in this test case - we'll tell
+ // him/her how to fix it.
+
+ // Gets the name of the TEST and the name of the TEST_F. Note
+ // that first_is_TEST and this_is_TEST cannot both be true, as
+ // the fixture IDs are different for the two tests.
+ const char* const TEST_name =
+ first_is_TEST ? first_test_name : this_test_name;
+ const char* const TEST_F_name =
+ first_is_TEST ? this_test_name : first_test_name;
+
+ ADD_FAILURE()
+ << "All tests in the same test case must use the same test fixture\n"
+ << "class, so mixing TEST_F and TEST in the same test case is\n"
+ << "illegal. In test case " << this_test_info->test_case_name()
+ << ",\n"
+ << "test " << TEST_F_name << " is defined using TEST_F but\n"
+ << "test " << TEST_name << " is defined using TEST. You probably\n"
+ << "want to change the TEST to TEST_F or move it to another test\n"
+ << "case.";
+ } else {
+ // The user defined two fixture classes with the same name in
+ // two namespaces - we'll tell him/her how to fix it.
+ ADD_FAILURE()
+ << "All tests in the same test case must use the same test fixture\n"
+ << "class. However, in test case "
+ << this_test_info->test_case_name() << ",\n"
+ << "you defined test " << first_test_name
+ << " and test " << this_test_name << "\n"
+ << "using two different test fixture classes. This can happen if\n"
+ << "the two classes are from different namespaces or translation\n"
+ << "units and have the same name. You should probably rename one\n"
+ << "of the classes to put the tests into different test cases.";
+ }
+ return false;
+ }
+
+ return true;
+}
+
+// Runs the test and updates the test result.
+void Test::Run() {
+ if (!HasSameFixtureClass()) return;
+
+ internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+#if GTEST_HAS_SEH
+ // Catch SEH-style exceptions.
+ impl->os_stack_trace_getter()->UponLeavingGTest();
+ __try {
+ SetUp();
+ } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+ GetExceptionCode())) {
+ AddExceptionThrownFailure(GetExceptionCode(), "SetUp()");
+ }
+
+ // We will run the test only if SetUp() had no fatal failure.
+ if (!HasFatalFailure()) {
+ impl->os_stack_trace_getter()->UponLeavingGTest();
+ __try {
+ TestBody();
+ } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+ GetExceptionCode())) {
+ AddExceptionThrownFailure(GetExceptionCode(), "the test body");
+ }
+ }
+
+ // However, we want to clean up as much as possible. Hence we will
+ // always call TearDown(), even if SetUp() or the test body has
+ // failed.
+ impl->os_stack_trace_getter()->UponLeavingGTest();
+ __try {
+ TearDown();
+ } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+ GetExceptionCode())) {
+ AddExceptionThrownFailure(GetExceptionCode(), "TearDown()");
+ }
+
+#else // We are on a compiler or platform that doesn't support SEH.
+ impl->os_stack_trace_getter()->UponLeavingGTest();
+ SetUp();
+
+ // We will run the test only if SetUp() was successful.
+ if (!HasFatalFailure()) {
+ impl->os_stack_trace_getter()->UponLeavingGTest();
+ TestBody();
+ }
+
+ // However, we want to clean up as much as possible. Hence we will
+ // always call TearDown(), even if SetUp() or the test body has
+ // failed.
+ impl->os_stack_trace_getter()->UponLeavingGTest();
+ TearDown();
+#endif // GTEST_HAS_SEH
+}
+
+
+// Returns true iff the current test has a fatal failure.
+bool Test::HasFatalFailure() {
+ return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();
+}
+
+// Returns true iff the current test has a non-fatal failure.
+bool Test::HasNonfatalFailure() {
+ return internal::GetUnitTestImpl()->current_test_result()->
+ HasNonfatalFailure();
+}
+
+// class TestInfo
+
+// Constructs a TestInfo object. It assumes ownership of the test factory
+// object via impl_.
+TestInfo::TestInfo(const char* a_test_case_name,
+ const char* a_name,
+ const char* a_test_case_comment,
+ const char* a_comment,
+ internal::TypeId fixture_class_id,
+ internal::TestFactoryBase* factory) {
+ impl_ = new internal::TestInfoImpl(this, a_test_case_name, a_name,
+ a_test_case_comment, a_comment,
+ fixture_class_id, factory);
+}
+
+// Destructs a TestInfo object.
+TestInfo::~TestInfo() {
+ delete impl_;
+}
+
+namespace internal {
+
+// Creates a new TestInfo object and registers it with Google Test;
+// returns the created object.
+//
+// Arguments:
+//
+// test_case_name: name of the test case
+// name: name of the test
+// test_case_comment: a comment on the test case that will be included in
+// the test output
+// comment: a comment on the test that will be included in the
+// test output
+// fixture_class_id: ID of the test fixture class
+// set_up_tc: pointer to the function that sets up the test case
+// tear_down_tc: pointer to the function that tears down the test case
+// factory: pointer to the factory that creates a test object.
+// The newly created TestInfo instance will assume
+// ownership of the factory object.
+TestInfo* MakeAndRegisterTestInfo(
+ const char* test_case_name, const char* name,
+ const char* test_case_comment, const char* comment,
+ TypeId fixture_class_id,
+ SetUpTestCaseFunc set_up_tc,
+ TearDownTestCaseFunc tear_down_tc,
+ TestFactoryBase* factory) {
+ TestInfo* const test_info =
+ new TestInfo(test_case_name, name, test_case_comment, comment,
+ fixture_class_id, factory);
+ GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
+ return test_info;
+}
+
+#if GTEST_HAS_PARAM_TEST
+void ReportInvalidTestCaseType(const char* test_case_name,
+ const char* file, int line) {
+ Message errors;
+ errors
+ << "Attempted redefinition of test case " << test_case_name << ".\n"
+ << "All tests in the same test case must use the same test fixture\n"
+ << "class. However, in test case " << test_case_name << ", you tried\n"
+ << "to define a test using a fixture class different from the one\n"
+ << "used earlier. This can happen if the two fixture classes are\n"
+ << "from different namespaces and have the same name. You should\n"
+ << "probably rename one of the classes to put the tests into different\n"
+ << "test cases.";
+
+ fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
+ errors.GetString().c_str());
+}
+#endif // GTEST_HAS_PARAM_TEST
+
+} // namespace internal
+
+// Returns the test case name.
+const char* TestInfo::test_case_name() const {
+ return impl_->test_case_name();
+}
+
+// Returns the test name.
+const char* TestInfo::name() const {
+ return impl_->name();
+}
+
+// Returns the test case comment.
+const char* TestInfo::test_case_comment() const {
+ return impl_->test_case_comment();
+}
+
+// Returns the test comment.
+const char* TestInfo::comment() const {
+ return impl_->comment();
+}
+
+// Returns true if this test should run.
+bool TestInfo::should_run() const { return impl_->should_run(); }
+
+// Returns true if this test matches the user-specified filter.
+bool TestInfo::matches_filter() const { return impl_->matches_filter(); }
+
+// Returns the result of the test.
+const TestResult* TestInfo::result() const { return impl_->result(); }
+
+// Increments the number of death tests encountered in this test so
+// far.
+int TestInfo::increment_death_test_count() {
+ return impl_->result()->increment_death_test_count();
+}
+
+namespace {
+
+// A predicate that checks the test name of a TestInfo against a known
+// value.
+//
+// This is used for implementation of the TestCase class only. We put
+// it in the anonymous namespace to prevent polluting the outer
+// namespace.
+//
+// TestNameIs is copyable.
+class TestNameIs {
+ public:
+ // Constructor.
+ //
+ // TestNameIs has NO default constructor.
+ explicit TestNameIs(const char* name)
+ : name_(name) {}
+
+ // Returns true iff the test name of test_info matches name_.
+ bool operator()(const TestInfo * test_info) const {
+ return test_info && internal::String(test_info->name()).Compare(name_) == 0;
+ }
+
+ private:
+ internal::String name_;
+};
+
+} // namespace
+
+namespace internal {
+
+// This method expands all parameterized tests registered with macros TEST_P
+// and INSTANTIATE_TEST_CASE_P into regular tests and registers those.
+// This will be done just once during the program runtime.
+void UnitTestImpl::RegisterParameterizedTests() {
+#if GTEST_HAS_PARAM_TEST
+ if (!parameterized_tests_registered_) {
+ parameterized_test_registry_.RegisterTests();
+ parameterized_tests_registered_ = true;
+ }
+#endif
+}
+
+// Creates the test object, runs it, records its result, and then
+// deletes it.
+void TestInfoImpl::Run() {
+ if (!should_run_) return;
+
+ // Tells UnitTest where to store test result.
+ UnitTestImpl* const impl = internal::GetUnitTestImpl();
+ impl->set_current_test_info(parent_);
+
+ TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
+
+ // Notifies the unit test event listeners that a test is about to start.
+ repeater->OnTestStart(*parent_);
+
+ const TimeInMillis start = GetTimeInMillis();
+
+ impl->os_stack_trace_getter()->UponLeavingGTest();
+#if GTEST_HAS_SEH
+ // Catch SEH-style exceptions.
+ Test* test = NULL;
+
+ __try {
+ // Creates the test object.
+ test = factory_->CreateTest();
+ } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+ GetExceptionCode())) {
+ AddExceptionThrownFailure(GetExceptionCode(),
+ "the test fixture's constructor");
+ return;
+ }
+#else // We are on a compiler or platform that doesn't support SEH.
+
+ // TODO(wan): If test->Run() throws, test won't be deleted. This is
+ // not a problem now as we don't use exceptions. If we were to
+ // enable exceptions, we should revise the following to be
+ // exception-safe.
+
+ // Creates the test object.
+ Test* test = factory_->CreateTest();
+#endif // GTEST_HAS_SEH
+
+ // Runs the test only if the constructor of the test fixture didn't
+ // generate a fatal failure.
+ if (!Test::HasFatalFailure()) {
+ test->Run();
+ }
+
+ // Deletes the test object.
+ impl->os_stack_trace_getter()->UponLeavingGTest();
+ delete test;
+ test = NULL;
+
+ result_.set_elapsed_time(GetTimeInMillis() - start);
+
+ // Notifies the unit test event listener that a test has just finished.
+ repeater->OnTestEnd(*parent_);
+
+ // Tells UnitTest to stop associating assertion results to this
+ // test.
+ impl->set_current_test_info(NULL);
+}
+
+} // namespace internal
+
+// class TestCase
+
+// Gets the number of successful tests in this test case.
+int TestCase::successful_test_count() const {
+ return CountIf(test_info_list_, TestPassed);
+}
+
+// Gets the number of failed tests in this test case.
+int TestCase::failed_test_count() const {
+ return CountIf(test_info_list_, TestFailed);
+}
+
+int TestCase::disabled_test_count() const {
+ return CountIf(test_info_list_, TestDisabled);
+}
+
+// Get the number of tests in this test case that should run.
+int TestCase::test_to_run_count() const {
+ return CountIf(test_info_list_, ShouldRunTest);
+}
+
+// Gets the number of all tests.
+int TestCase::total_test_count() const {
+ return static_cast<int>(test_info_list_.size());
+}
+
+// Creates a TestCase with the given name.
+//
+// Arguments:
+//
+// name: name of the test case
+// set_up_tc: pointer to the function that sets up the test case
+// tear_down_tc: pointer to the function that tears down the test case
+TestCase::TestCase(const char* a_name, const char* a_comment,
+ Test::SetUpTestCaseFunc set_up_tc,
+ Test::TearDownTestCaseFunc tear_down_tc)
+ : name_(a_name),
+ comment_(a_comment),
+ set_up_tc_(set_up_tc),
+ tear_down_tc_(tear_down_tc),
+ should_run_(false),
+ elapsed_time_(0) {
+}
+
+// Destructor of TestCase.
+TestCase::~TestCase() {
+ // Deletes every Test in the collection.
+ ForEach(test_info_list_, internal::Delete<TestInfo>);
+}
+
+// Returns the i-th test among all the tests. i can range from 0 to
+// total_test_count() - 1. If i is not in that range, returns NULL.
+const TestInfo* TestCase::GetTestInfo(int i) const {
+ const int index = GetElementOr(test_indices_, i, -1);
+ return index < 0 ? NULL : test_info_list_[index];
+}
+
+// Returns the i-th test among all the tests. i can range from 0 to
+// total_test_count() - 1. If i is not in that range, returns NULL.
+TestInfo* TestCase::GetMutableTestInfo(int i) {
+ const int index = GetElementOr(test_indices_, i, -1);
+ return index < 0 ? NULL : test_info_list_[index];
+}
+
+// Adds a test to this test case. Will delete the test upon
+// destruction of the TestCase object.
+void TestCase::AddTestInfo(TestInfo * test_info) {
+ test_info_list_.push_back(test_info);
+ test_indices_.push_back(static_cast<int>(test_indices_.size()));
+}
+
+// Runs every test in this TestCase.
+void TestCase::Run() {
+ if (!should_run_) return;
+
+ internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+ impl->set_current_test_case(this);
+
+ TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
+
+ repeater->OnTestCaseStart(*this);
+ impl->os_stack_trace_getter()->UponLeavingGTest();
+ set_up_tc_();
+
+ const internal::TimeInMillis start = internal::GetTimeInMillis();
+ for (int i = 0; i < total_test_count(); i++) {
+ GetMutableTestInfo(i)->impl()->Run();
+ }
+ elapsed_time_ = internal::GetTimeInMillis() - start;
+
+ impl->os_stack_trace_getter()->UponLeavingGTest();
+ tear_down_tc_();
+ repeater->OnTestCaseEnd(*this);
+ impl->set_current_test_case(NULL);
+}
+
+// Clears the results of all tests in this test case.
+void TestCase::ClearResult() {
+ ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult);
+}
+
+// Returns true iff test passed.
+bool TestCase::TestPassed(const TestInfo * test_info) {
+ const internal::TestInfoImpl* const impl = test_info->impl();
+ return impl->should_run() && impl->result()->Passed();
+}
+
+// Returns true iff test failed.
+bool TestCase::TestFailed(const TestInfo * test_info) {
+ const internal::TestInfoImpl* const impl = test_info->impl();
+ return impl->should_run() && impl->result()->Failed();
+}
+
+// Returns true iff test is disabled.
+bool TestCase::TestDisabled(const TestInfo * test_info) {
+ return test_info->impl()->is_disabled();
+}
+
+// Returns true if the given test should run.
+bool TestCase::ShouldRunTest(const TestInfo *test_info) {
+ return test_info->impl()->should_run();
+}
+
+// Shuffles the tests in this test case.
+void TestCase::ShuffleTests(internal::Random* random) {
+ Shuffle(random, &test_indices_);
+}
+
+// Restores the test order to before the first shuffle.
+void TestCase::UnshuffleTests() {
+ for (size_t i = 0; i < test_indices_.size(); i++) {
+ test_indices_[i] = static_cast<int>(i);
+ }
+}
+
+// Formats a countable noun. Depending on its quantity, either the
+// singular form or the plural form is used. e.g.
+//
+// FormatCountableNoun(1, "formula", "formuli") returns "1 formula".
+// FormatCountableNoun(5, "book", "books") returns "5 books".
+static internal::String FormatCountableNoun(int count,
+ const char * singular_form,
+ const char * plural_form) {
+ return internal::String::Format("%d %s", count,
+ count == 1 ? singular_form : plural_form);
+}
+
+// Formats the count of tests.
+static internal::String FormatTestCount(int test_count) {
+ return FormatCountableNoun(test_count, "test", "tests");
+}
+
+// Formats the count of test cases.
+static internal::String FormatTestCaseCount(int test_case_count) {
+ return FormatCountableNoun(test_case_count, "test case", "test cases");
+}
+
+// Converts a TestPartResult::Type enum to human-friendly string
+// representation. Both kNonFatalFailure and kFatalFailure are translated
+// to "Failure", as the user usually doesn't care about the difference
+// between the two when viewing the test result.
+static const char * TestPartResultTypeToString(TestPartResult::Type type) {
+ switch (type) {
+ case TestPartResult::kSuccess:
+ return "Success";
+
+ case TestPartResult::kNonFatalFailure:
+ case TestPartResult::kFatalFailure:
+#ifdef _MSC_VER
+ return "error: ";
+#else
+ return "Failure\n";
+#endif
+ }
+
+ return "Unknown result type";
+}
+
+// Prints a TestPartResult to a String.
+static internal::String PrintTestPartResultToString(
+ const TestPartResult& test_part_result) {
+ return (Message()
+ << internal::FormatFileLocation(test_part_result.file_name(),
+ test_part_result.line_number())
+ << " " << TestPartResultTypeToString(test_part_result.type())
+ << test_part_result.message()).GetString();
+}
+
+// Prints a TestPartResult.
+static void PrintTestPartResult(const TestPartResult& test_part_result) {
+ const internal::String& result =
+ PrintTestPartResultToString(test_part_result);
+ printf("%s\n", result.c_str());
+ fflush(stdout);
+ // If the test program runs in Visual Studio or a debugger, the
+ // following statements add the test part result message to the Output
+ // window such that the user can double-click on it to jump to the
+ // corresponding source code location; otherwise they do nothing.
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+ // We don't call OutputDebugString*() on Windows Mobile, as printing
+ // to stdout is done by OutputDebugString() there already - we don't
+ // want the same message printed twice.
+ ::OutputDebugStringA(result.c_str());
+ ::OutputDebugStringA("\n");
+#endif
+}
+
+// class PrettyUnitTestResultPrinter
+
+namespace internal {
+
+enum GTestColor {
+ COLOR_DEFAULT,
+ COLOR_RED,
+ COLOR_GREEN,
+ COLOR_YELLOW
+};
+
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+
+// Returns the character attribute for the given color.
+WORD GetColorAttribute(GTestColor color) {
+ switch (color) {
+ case COLOR_RED: return FOREGROUND_RED;
+ case COLOR_GREEN: return FOREGROUND_GREEN;
+ case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
+ default: return 0;
+ }
+}
+
+#else
+
+// Returns the ANSI color code for the given color. COLOR_DEFAULT is
+// an invalid input.
+const char* GetAnsiColorCode(GTestColor color) {
+ switch (color) {
+ case COLOR_RED: return "1";
+ case COLOR_GREEN: return "2";
+ case COLOR_YELLOW: return "3";
+ default: return NULL;
+ };
+}
+
+#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+
+// Returns true iff Google Test should use colors in the output.
+bool ShouldUseColor(bool stdout_is_tty) {
+ const char* const gtest_color = GTEST_FLAG(color).c_str();
+
+ if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) {
+#if GTEST_OS_WINDOWS
+ // On Windows the TERM variable is usually not set, but the
+ // console there does support colors.
+ return stdout_is_tty;
+#else
+ // On non-Windows platforms, we rely on the TERM variable.
+ const char* const term = posix::GetEnv("TERM");
+ const bool term_supports_color =
+ String::CStringEquals(term, "xterm") ||
+ String::CStringEquals(term, "xterm-color") ||
+ String::CStringEquals(term, "xterm-256color") ||
+ String::CStringEquals(term, "linux") ||
+ String::CStringEquals(term, "cygwin");
+ return stdout_is_tty && term_supports_color;
+#endif // GTEST_OS_WINDOWS
+ }
+
+ return String::CaseInsensitiveCStringEquals(gtest_color, "yes") ||
+ String::CaseInsensitiveCStringEquals(gtest_color, "true") ||
+ String::CaseInsensitiveCStringEquals(gtest_color, "t") ||
+ String::CStringEquals(gtest_color, "1");
+ // We take "yes", "true", "t", and "1" as meaning "yes". If the
+ // value is neither one of these nor "auto", we treat it as "no" to
+ // be conservative.
+}
+
+// Helpers for printing colored strings to stdout. Note that on Windows, we
+// cannot simply emit special characters and have the terminal change colors.
+// This routine must actually emit the characters rather than return a string
+// that would be colored when printed, as can be done on Linux.
+void ColoredPrintf(GTestColor color, const char* fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+
+#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
+ const bool use_color = false;
+#else
+ static const bool in_color_mode =
+ ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
+ const bool use_color = in_color_mode && (color != COLOR_DEFAULT);
+#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
+ // The '!= 0' comparison is necessary to satisfy MSVC 7.1.
+
+ if (!use_color) {
+ vprintf(fmt, args);
+ va_end(args);
+ return;
+ }
+
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+ const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ // Gets the current text color.
+ CONSOLE_SCREEN_BUFFER_INFO buffer_info;
+ GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
+ const WORD old_color_attrs = buffer_info.wAttributes;
+
+ // We need to flush the stream buffers into the console before each
+ // SetConsoleTextAttribute call lest it affect the text that is already
+ // printed but has not yet reached the console.
+ fflush(stdout);
+ SetConsoleTextAttribute(stdout_handle,
+ GetColorAttribute(color) | FOREGROUND_INTENSITY);
+ vprintf(fmt, args);
+
+ fflush(stdout);
+ // Restores the text color.
+ SetConsoleTextAttribute(stdout_handle, old_color_attrs);
+#else
+ printf("\033[0;3%sm", GetAnsiColorCode(color));
+ vprintf(fmt, args);
+ printf("\033[m"); // Resets the terminal to default.
+#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+ va_end(args);
+}
+
+// This class implements the TestEventListener interface.
+//
+// Class PrettyUnitTestResultPrinter is copyable.
+class PrettyUnitTestResultPrinter : public TestEventListener {
+ public:
+ PrettyUnitTestResultPrinter() {}
+ static void PrintTestName(const char * test_case, const char * test) {
+ printf("%s.%s", test_case, test);
+ }
+
+ // The following methods override what's in the TestEventListener class.
+ virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
+ virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
+ virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
+ virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
+ virtual void OnTestCaseStart(const TestCase& test_case);
+ virtual void OnTestStart(const TestInfo& test_info);
+ virtual void OnTestPartResult(const TestPartResult& result);
+ virtual void OnTestEnd(const TestInfo& test_info);
+ virtual void OnTestCaseEnd(const TestCase& test_case);
+ virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
+ virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
+ virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+ virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+
+ private:
+ static void PrintFailedTests(const UnitTest& unit_test);
+
+ internal::String test_case_name_;
+};
+
+ // Fired before each iteration of tests starts.
+void PrettyUnitTestResultPrinter::OnTestIterationStart(
+ const UnitTest& unit_test, int iteration) {
+ if (GTEST_FLAG(repeat) != 1)
+ printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1);
+
+ const char* const filter = GTEST_FLAG(filter).c_str();
+
+ // Prints the filter if it's not *. This reminds the user that some
+ // tests may be skipped.
+ if (!internal::String::CStringEquals(filter, kUniversalFilter)) {
+ ColoredPrintf(COLOR_YELLOW,
+ "Note: %s filter = %s\n", GTEST_NAME_, filter);
+ }
+
+ if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {
+ ColoredPrintf(COLOR_YELLOW,
+ "Note: This is test shard %s of %s.\n",
+ internal::posix::GetEnv(kTestShardIndex),
+ internal::posix::GetEnv(kTestTotalShards));
+ }
+
+ if (GTEST_FLAG(shuffle)) {
+ ColoredPrintf(COLOR_YELLOW,
+ "Note: Randomizing tests' orders with a seed of %d .\n",
+ unit_test.random_seed());
+ }
+
+ ColoredPrintf(COLOR_GREEN, "[==========] ");
+ printf("Running %s from %s.\n",
+ FormatTestCount(unit_test.test_to_run_count()).c_str(),
+ FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+ fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(
+ const UnitTest& /*unit_test*/) {
+ ColoredPrintf(COLOR_GREEN, "[----------] ");
+ printf("Global test environment set-up.\n");
+ fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
+ test_case_name_ = test_case.name();
+ const internal::String counts =
+ FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
+ ColoredPrintf(COLOR_GREEN, "[----------] ");
+ printf("%s from %s", counts.c_str(), test_case_name_.c_str());
+ if (test_case.comment()[0] == '\0') {
+ printf("\n");
+ } else {
+ printf(", where %s\n", test_case.comment());
+ }
+ fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
+ ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
+ PrintTestName(test_case_name_.c_str(), test_info.name());
+ if (test_info.comment()[0] == '\0') {
+ printf("\n");
+ } else {
+ printf(", where %s\n", test_info.comment());
+ }
+ fflush(stdout);
+}
+
+// Called after an assertion failure.
+void PrettyUnitTestResultPrinter::OnTestPartResult(
+ const TestPartResult& result) {
+ // If the test part succeeded, we don't need to do anything.
+ if (result.type() == TestPartResult::kSuccess)
+ return;
+
+ // Print failure message from the assertion (e.g. expected this and got that).
+ PrintTestPartResult(result);
+ fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
+ if (test_info.result()->Passed()) {
+ ColoredPrintf(COLOR_GREEN, "[ OK ] ");
+ } else {
+ ColoredPrintf(COLOR_RED, "[ FAILED ] ");
+ }
+ PrintTestName(test_case_name_.c_str(), test_info.name());
+ if (GTEST_FLAG(print_time)) {
+ printf(" (%s ms)\n", internal::StreamableToString(
+ test_info.result()->elapsed_time()).c_str());
+ } else {
+ printf("\n");
+ }
+ fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
+ if (!GTEST_FLAG(print_time)) return;
+
+ test_case_name_ = test_case.name();
+ const internal::String counts =
+ FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
+ ColoredPrintf(COLOR_GREEN, "[----------] ");
+ printf("%s from %s (%s ms total)\n\n",
+ counts.c_str(), test_case_name_.c_str(),
+ internal::StreamableToString(test_case.elapsed_time()).c_str());
+ fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(
+ const UnitTest& /*unit_test*/) {
+ ColoredPrintf(COLOR_GREEN, "[----------] ");
+ printf("Global test environment tear-down\n");
+ fflush(stdout);
+}
+
+// Internal helper for printing the list of failed tests.
+void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {
+ const int failed_test_count = unit_test.failed_test_count();
+ if (failed_test_count == 0) {
+ return;
+ }
+
+ for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
+ const TestCase& test_case = *unit_test.GetTestCase(i);
+ if (!test_case.should_run() || (test_case.failed_test_count() == 0)) {
+ continue;
+ }
+ for (int j = 0; j < test_case.total_test_count(); ++j) {
+ const TestInfo& test_info = *test_case.GetTestInfo(j);
+ if (!test_info.should_run() || test_info.result()->Passed()) {
+ continue;
+ }
+ ColoredPrintf(COLOR_RED, "[ FAILED ] ");
+ printf("%s.%s", test_case.name(), test_info.name());
+ if (test_case.comment()[0] != '\0' ||
+ test_info.comment()[0] != '\0') {
+ printf(", where %s", test_case.comment());
+ if (test_case.comment()[0] != '\0' &&
+ test_info.comment()[0] != '\0') {
+ printf(" and ");
+ }
+ }
+ printf("%s\n", test_info.comment());
+ }
+ }
+}
+
+ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
+ int /*iteration*/) {
+ ColoredPrintf(COLOR_GREEN, "[==========] ");
+ printf("%s from %s ran.",
+ FormatTestCount(unit_test.test_to_run_count()).c_str(),
+ FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+ if (GTEST_FLAG(print_time)) {
+ printf(" (%s ms total)",
+ internal::StreamableToString(unit_test.elapsed_time()).c_str());
+ }
+ printf("\n");
+ ColoredPrintf(COLOR_GREEN, "[ PASSED ] ");
+ printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str());
+
+ int num_failures = unit_test.failed_test_count();
+ if (!unit_test.Passed()) {
+ const int failed_test_count = unit_test.failed_test_count();
+ ColoredPrintf(COLOR_RED, "[ FAILED ] ");
+ printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str());
+ PrintFailedTests(unit_test);
+ printf("\n%2d FAILED %s\n", num_failures,
+ num_failures == 1 ? "TEST" : "TESTS");
+ }
+
+ int num_disabled = unit_test.disabled_test_count();
+ if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {
+ if (!num_failures) {
+ printf("\n"); // Add a spacer if no FAILURE banner is displayed.
+ }
+ ColoredPrintf(COLOR_YELLOW,
+ " YOU HAVE %d DISABLED %s\n\n",
+ num_disabled,
+ num_disabled == 1 ? "TEST" : "TESTS");
+ }
+ // Ensure that Google Test output is printed before, e.g., heapchecker output.
+ fflush(stdout);
+}
+
+// End PrettyUnitTestResultPrinter
+
+// class TestEventRepeater
+//
+// This class forwards events to other event listeners.
+class TestEventRepeater : public TestEventListener {
+ public:
+ TestEventRepeater() : forwarding_enabled_(true) {}
+ virtual ~TestEventRepeater();
+ void Append(TestEventListener *listener);
+ TestEventListener* Release(TestEventListener* listener);
+
+ // Controls whether events will be forwarded to listeners_. Set to false
+ // in death test child processes.
+ bool forwarding_enabled() const { return forwarding_enabled_; }
+ void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }
+
+ virtual void OnTestProgramStart(const UnitTest& unit_test);
+ virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
+ virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
+ virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test);
+ virtual void OnTestCaseStart(const TestCase& test_case);
+ virtual void OnTestStart(const TestInfo& test_info);
+ virtual void OnTestPartResult(const TestPartResult& result);
+ virtual void OnTestEnd(const TestInfo& test_info);
+ virtual void OnTestCaseEnd(const TestCase& test_case);
+ virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
+ virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test);
+ virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+ virtual void OnTestProgramEnd(const UnitTest& unit_test);
+
+ private:
+ // Controls whether events will be forwarded to listeners_. Set to false
+ // in death test child processes.
+ bool forwarding_enabled_;
+ // The list of listeners that receive events.
+ std::vector<TestEventListener*> listeners_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater);
+};
+
+TestEventRepeater::~TestEventRepeater() {
+ ForEach(listeners_, Delete<TestEventListener>);
+}
+
+void TestEventRepeater::Append(TestEventListener *listener) {
+ listeners_.push_back(listener);
+}
+
+// TODO(vladl@google.com): Factor the search functionality into Vector::Find.
+TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
+ for (size_t i = 0; i < listeners_.size(); ++i) {
+ if (listeners_[i] == listener) {
+ listeners_.erase(listeners_.begin() + i);
+ return listener;
+ }
+ }
+
+ return NULL;
+}
+
+// Since most methods are very similar, use macros to reduce boilerplate.
+// This defines a member that forwards the call to all listeners.
+#define GTEST_REPEATER_METHOD_(Name, Type) \
+void TestEventRepeater::Name(const Type& parameter) { \
+ if (forwarding_enabled_) { \
+ for (size_t i = 0; i < listeners_.size(); i++) { \
+ listeners_[i]->Name(parameter); \
+ } \
+ } \
+}
+// This defines a member that forwards the call to all listeners in reverse
+// order.
+#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \
+void TestEventRepeater::Name(const Type& parameter) { \
+ if (forwarding_enabled_) { \
+ for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \
+ listeners_[i]->Name(parameter); \
+ } \
+ } \
+}
+
+GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest)
+GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest)
+GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase)
+GTEST_REPEATER_METHOD_(OnTestStart, TestInfo)
+GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)
+GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)
+
+#undef GTEST_REPEATER_METHOD_
+#undef GTEST_REVERSE_REPEATER_METHOD_
+
+void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,
+ int iteration) {
+ if (forwarding_enabled_) {
+ for (size_t i = 0; i < listeners_.size(); i++) {
+ listeners_[i]->OnTestIterationStart(unit_test, iteration);
+ }
+ }
+}
+
+void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,
+ int iteration) {
+ if (forwarding_enabled_) {
+ for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) {
+ listeners_[i]->OnTestIterationEnd(unit_test, iteration);
+ }
+ }
+}
+
+// End TestEventRepeater
+
+// This class generates an XML output file.
+class XmlUnitTestResultPrinter : public EmptyTestEventListener {
+ public:
+ explicit XmlUnitTestResultPrinter(const char* output_file);
+
+ virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+
+ private:
+ // Is c a whitespace character that is normalized to a space character
+ // when it appears in an XML attribute value?
+ static bool IsNormalizableWhitespace(char c) {
+ return c == 0x9 || c == 0xA || c == 0xD;
+ }
+
+ // May c appear in a well-formed XML document?
+ static bool IsValidXmlCharacter(char c) {
+ return IsNormalizableWhitespace(c) || c >= 0x20;
+ }
+
+ // Returns an XML-escaped copy of the input string str. If
+ // is_attribute is true, the text is meant to appear as an attribute
+ // value, and normalizable whitespace is preserved by replacing it
+ // with character references.
+ static String EscapeXml(const char* str, bool is_attribute);
+
+ // Returns the given string with all characters invalid in XML removed.
+ static String RemoveInvalidXmlCharacters(const char* str);
+
+ // Convenience wrapper around EscapeXml when str is an attribute value.
+ static String EscapeXmlAttribute(const char* str) {
+ return EscapeXml(str, true);
+ }
+
+ // Convenience wrapper around EscapeXml when str is not an attribute value.
+ static String EscapeXmlText(const char* str) { return EscapeXml(str, false); }
+
+ // Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
+ static void OutputXmlCDataSection(::std::ostream* stream, const char* data);
+
+ // Streams an XML representation of a TestInfo object.
+ static void OutputXmlTestInfo(::std::ostream* stream,
+ const char* test_case_name,
+ const TestInfo& test_info);
+
+ // Prints an XML representation of a TestCase object
+ static void PrintXmlTestCase(FILE* out, const TestCase& test_case);
+
+ // Prints an XML summary of unit_test to output stream out.
+ static void PrintXmlUnitTest(FILE* out, const UnitTest& unit_test);
+
+ // Produces a string representing the test properties in a result as space
+ // delimited XML attributes based on the property key="value" pairs.
+ // When the String is not empty, it includes a space at the beginning,
+ // to delimit this attribute from prior attributes.
+ static String TestPropertiesAsXmlAttributes(const TestResult& result);
+
+ // The output file.
+ const String output_file_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter);
+};
+
+// Creates a new XmlUnitTestResultPrinter.
+XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
+ : output_file_(output_file) {
+ if (output_file_.c_str() == NULL || output_file_.empty()) {
+ fprintf(stderr, "XML output file may not be null\n");
+ fflush(stderr);
+ exit(EXIT_FAILURE);
+ }
+}
+
+// Called after the unit test ends.
+void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
+ int /*iteration*/) {
+ FILE* xmlout = NULL;
+ FilePath output_file(output_file_);
+ FilePath output_dir(output_file.RemoveFileName());
+
+ if (output_dir.CreateDirectoriesRecursively()) {
+ xmlout = posix::FOpen(output_file_.c_str(), "w");
+ }
+ if (xmlout == NULL) {
+ // TODO(wan): report the reason of the failure.
+ //
+ // We don't do it for now as:
+ //
+ // 1. There is no urgent need for it.
+ // 2. It's a bit involved to make the errno variable thread-safe on
+ // all three operating systems (Linux, Windows, and Mac OS).
+ // 3. To interpret the meaning of errno in a thread-safe way,
+ // we need the strerror_r() function, which is not available on
+ // Windows.
+ fprintf(stderr,
+ "Unable to open file \"%s\"\n",
+ output_file_.c_str());
+ fflush(stderr);
+ exit(EXIT_FAILURE);
+ }
+ PrintXmlUnitTest(xmlout, unit_test);
+ fclose(xmlout);
+}
+
+// Returns an XML-escaped copy of the input string str. If is_attribute
+// is true, the text is meant to appear as an attribute value, and
+// normalizable whitespace is preserved by replacing it with character
+// references.
+//
+// Invalid XML characters in str, if any, are stripped from the output.
+// It is expected that most, if not all, of the text processed by this
+// module will consist of ordinary English text.
+// If this module is ever modified to produce version 1.1 XML output,
+// most invalid characters can be retained using character references.
+// TODO(wan): It might be nice to have a minimally invasive, human-readable
+// escaping scheme for invalid characters, rather than dropping them.
+String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) {
+ Message m;
+
+ if (str != NULL) {
+ for (const char* src = str; *src; ++src) {
+ switch (*src) {
+ case '<':
+ m << "&lt;";
+ break;
+ case '>':
+ m << "&gt;";
+ break;
+ case '&':
+ m << "&amp;";
+ break;
+ case '\'':
+ if (is_attribute)
+ m << "&apos;";
+ else
+ m << '\'';
+ break;
+ case '"':
+ if (is_attribute)
+ m << "&quot;";
+ else
+ m << '"';
+ break;
+ default:
+ if (IsValidXmlCharacter(*src)) {
+ if (is_attribute && IsNormalizableWhitespace(*src))
+ m << String::Format("&#x%02X;", unsigned(*src));
+ else
+ m << *src;
+ }
+ break;
+ }
+ }
+ }
+
+ return m.GetString();
+}
+
+// Returns the given string with all characters invalid in XML removed.
+// Currently invalid characters are dropped from the string. An
+// alternative is to replace them with certain characters such as . or ?.
+String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) {
+ char* const output = new char[strlen(str) + 1];
+ char* appender = output;
+ for (char ch = *str; ch != '\0'; ch = *++str)
+ if (IsValidXmlCharacter(ch))
+ *appender++ = ch;
+ *appender = '\0';
+
+ String ret_value(output);
+ delete[] output;
+ return ret_value;
+}
+
+// The following routines generate an XML representation of a UnitTest
+// object.
+//
+// This is how Google Test concepts map to the DTD:
+//
+// <testsuites name="AllTests"> <-- corresponds to a UnitTest object
+// <testsuite name="testcase-name"> <-- corresponds to a TestCase object
+// <testcase name="test-name"> <-- corresponds to a TestInfo object
+// <failure message="...">...</failure>
+// <failure message="...">...</failure>
+// <failure message="...">...</failure>
+// <-- individual assertion failures
+// </testcase>
+// </testsuite>
+// </testsuites>
+
+// Formats the given time in milliseconds as seconds.
+std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
+ ::std::stringstream ss;
+ ss << ms/1000.0;
+ return ss.str();
+}
+
+// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
+void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,
+ const char* data) {
+ const char* segment = data;
+ *stream << "<![CDATA[";
+ for (;;) {
+ const char* const next_segment = strstr(segment, "]]>");
+ if (next_segment != NULL) {
+ stream->write(
+ segment, static_cast<std::streamsize>(next_segment - segment));
+ *stream << "]]>]]&gt;<![CDATA[";
+ segment = next_segment + strlen("]]>");
+ } else {
+ *stream << segment;
+ break;
+ }
+ }
+ *stream << "]]>";
+}
+
+// Prints an XML representation of a TestInfo object.
+// TODO(wan): There is also value in printing properties with the plain printer.
+void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
+ const char* test_case_name,
+ const TestInfo& test_info) {
+ const TestResult& result = *test_info.result();
+ *stream << " <testcase name=\""
+ << EscapeXmlAttribute(test_info.name()).c_str()
+ << "\" status=\""
+ << (test_info.should_run() ? "run" : "notrun")
+ << "\" time=\""
+ << FormatTimeInMillisAsSeconds(result.elapsed_time())
+ << "\" classname=\"" << EscapeXmlAttribute(test_case_name).c_str()
+ << "\"" << TestPropertiesAsXmlAttributes(result).c_str();
+
+ int failures = 0;
+ for (int i = 0; i < result.total_part_count(); ++i) {
+ const TestPartResult& part = result.GetTestPartResult(i);
+ if (part.failed()) {
+ if (++failures == 1)
+ *stream << ">\n";
+ *stream << " <failure message=\""
+ << EscapeXmlAttribute(part.summary()).c_str()
+ << "\" type=\"\">";
+ const String message = RemoveInvalidXmlCharacters(String::Format(
+ "%s:%d\n%s",
+ part.file_name(), part.line_number(),
+ part.message()).c_str());
+ OutputXmlCDataSection(stream, message.c_str());
+ *stream << "</failure>\n";
+ }
+ }
+
+ if (failures == 0)
+ *stream << " />\n";
+ else
+ *stream << " </testcase>\n";
+}
+
+// Prints an XML representation of a TestCase object
+void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,
+ const TestCase& test_case) {
+ fprintf(out,
+ " <testsuite name=\"%s\" tests=\"%d\" failures=\"%d\" "
+ "disabled=\"%d\" ",
+ EscapeXmlAttribute(test_case.name()).c_str(),
+ test_case.total_test_count(),
+ test_case.failed_test_count(),
+ test_case.disabled_test_count());
+ fprintf(out,
+ "errors=\"0\" time=\"%s\">\n",
+ FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str());
+ for (int i = 0; i < test_case.total_test_count(); ++i) {
+ StrStream stream;
+ OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i));
+ fprintf(out, "%s", StrStreamToString(&stream).c_str());
+ }
+ fprintf(out, " </testsuite>\n");
+}
+
+// Prints an XML summary of unit_test to output stream out.
+void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
+ const UnitTest& unit_test) {
+ fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ fprintf(out,
+ "<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" "
+ "errors=\"0\" time=\"%s\" ",
+ unit_test.total_test_count(),
+ unit_test.failed_test_count(),
+ unit_test.disabled_test_count(),
+ FormatTimeInMillisAsSeconds(unit_test.elapsed_time()).c_str());
+ if (GTEST_FLAG(shuffle)) {
+ fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed());
+ }
+ fprintf(out, "name=\"AllTests\">\n");
+ for (int i = 0; i < unit_test.total_test_case_count(); ++i)
+ PrintXmlTestCase(out, *unit_test.GetTestCase(i));
+ fprintf(out, "</testsuites>\n");
+}
+
+// Produces a string representing the test properties in a result as space
+// delimited XML attributes based on the property key="value" pairs.
+String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
+ const TestResult& result) {
+ Message attributes;
+ for (int i = 0; i < result.test_property_count(); ++i) {
+ const TestProperty& property = result.GetTestProperty(i);
+ attributes << " " << property.key() << "="
+ << "\"" << EscapeXmlAttribute(property.value()) << "\"";
+ }
+ return attributes.GetString();
+}
+
+// End XmlUnitTestResultPrinter
+
+// Class ScopedTrace
+
+// Pushes the given source file location and message onto a per-thread
+// trace stack maintained by Google Test.
+// L < UnitTest::mutex_
+ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) {
+ TraceInfo trace;
+ trace.file = file;
+ trace.line = line;
+ trace.message = message.GetString();
+
+ UnitTest::GetInstance()->PushGTestTrace(trace);
+}
+
+// Pops the info pushed by the c'tor.
+// L < UnitTest::mutex_
+ScopedTrace::~ScopedTrace() {
+ UnitTest::GetInstance()->PopGTestTrace();
+}
+
+
+// class OsStackTraceGetter
+
+// Returns the current OS stack trace as a String. Parameters:
+//
+// max_depth - the maximum number of stack frames to be included
+// in the trace.
+// skip_count - the number of top frames to be skipped; doesn't count
+// against max_depth.
+//
+// L < mutex_
+// We use "L < mutex_" to denote that the function may acquire mutex_.
+String OsStackTraceGetter::CurrentStackTrace(int, int) {
+ return String("");
+}
+
+// L < mutex_
+void OsStackTraceGetter::UponLeavingGTest() {
+}
+
+const char* const
+OsStackTraceGetter::kElidedFramesMarker =
+ "... " GTEST_NAME_ " internal frames ...";
+
+} // namespace internal
+
+// class TestEventListeners
+
+TestEventListeners::TestEventListeners()
+ : repeater_(new internal::TestEventRepeater()),
+ default_result_printer_(NULL),
+ default_xml_generator_(NULL) {
+}
+
+TestEventListeners::~TestEventListeners() { delete repeater_; }
+
+// Returns the standard listener responsible for the default console
+// output. Can be removed from the listeners list to shut down default
+// console output. Note that removing this object from the listener list
+// with Release transfers its ownership to the user.
+void TestEventListeners::Append(TestEventListener* listener) {
+ repeater_->Append(listener);
+}
+
+// Removes the given event listener from the list and returns it. It then
+// becomes the caller's responsibility to delete the listener. Returns
+// NULL if the listener is not found in the list.
+TestEventListener* TestEventListeners::Release(TestEventListener* listener) {
+ if (listener == default_result_printer_)
+ default_result_printer_ = NULL;
+ else if (listener == default_xml_generator_)
+ default_xml_generator_ = NULL;
+ return repeater_->Release(listener);
+}
+
+// Returns repeater that broadcasts the TestEventListener events to all
+// subscribers.
+TestEventListener* TestEventListeners::repeater() { return repeater_; }
+
+// Sets the default_result_printer attribute to the provided listener.
+// The listener is also added to the listener list and previous
+// default_result_printer is removed from it and deleted. The listener can
+// also be NULL in which case it will not be added to the list. Does
+// nothing if the previous and the current listener objects are the same.
+void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) {
+ if (default_result_printer_ != listener) {
+ // It is an error to pass this method a listener that is already in the
+ // list.
+ delete Release(default_result_printer_);
+ default_result_printer_ = listener;
+ if (listener != NULL)
+ Append(listener);
+ }
+}
+
+// Sets the default_xml_generator attribute to the provided listener. The
+// listener is also added to the listener list and previous
+// default_xml_generator is removed from it and deleted. The listener can
+// also be NULL in which case it will not be added to the list. Does
+// nothing if the previous and the current listener objects are the same.
+void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {
+ if (default_xml_generator_ != listener) {
+ // It is an error to pass this method a listener that is already in the
+ // list.
+ delete Release(default_xml_generator_);
+ default_xml_generator_ = listener;
+ if (listener != NULL)
+ Append(listener);
+ }
+}
+
+// Controls whether events will be forwarded by the repeater to the
+// listeners in the list.
+bool TestEventListeners::EventForwardingEnabled() const {
+ return repeater_->forwarding_enabled();
+}
+
+void TestEventListeners::SuppressEventForwarding() {
+ repeater_->set_forwarding_enabled(false);
+}
+
+// class UnitTest
+
+// Gets the singleton UnitTest object. The first time this method is
+// called, a UnitTest object is constructed and returned. Consecutive
+// calls will return the same object.
+//
+// We don't protect this under mutex_ as a user is not supposed to
+// call this before main() starts, from which point on the return
+// value will never change.
+UnitTest * UnitTest::GetInstance() {
+ // When compiled with MSVC 7.1 in optimized mode, destroying the
+ // UnitTest object upon exiting the program messes up the exit code,
+ // causing successful tests to appear failed. We have to use a
+ // different implementation in this case to bypass the compiler bug.
+ // This implementation makes the compiler happy, at the cost of
+ // leaking the UnitTest object.
+
+ // CodeGear C++Builder insists on a public destructor for the
+ // default implementation. Use this implementation to keep good OO
+ // design with private destructor.
+
+#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+ static UnitTest* const instance = new UnitTest;
+ return instance;
+#else
+ static UnitTest instance;
+ return &instance;
+#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+}
+
+// Gets the number of successful test cases.
+int UnitTest::successful_test_case_count() const {
+ return impl()->successful_test_case_count();
+}
+
+// Gets the number of failed test cases.
+int UnitTest::failed_test_case_count() const {
+ return impl()->failed_test_case_count();
+}
+
+// Gets the number of all test cases.
+int UnitTest::total_test_case_count() const {
+ return impl()->total_test_case_count();
+}
+
+// Gets the number of all test cases that contain at least one test
+// that should run.
+int UnitTest::test_case_to_run_count() const {
+ return impl()->test_case_to_run_count();
+}
+
+// Gets the number of successful tests.
+int UnitTest::successful_test_count() const {
+ return impl()->successful_test_count();
+}
+
+// Gets the number of failed tests.
+int UnitTest::failed_test_count() const { return impl()->failed_test_count(); }
+
+// Gets the number of disabled tests.
+int UnitTest::disabled_test_count() const {
+ return impl()->disabled_test_count();
+}
+
+// Gets the number of all tests.
+int UnitTest::total_test_count() const { return impl()->total_test_count(); }
+
+// Gets the number of tests that should run.
+int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }
+
+// Gets the elapsed time, in milliseconds.
+internal::TimeInMillis UnitTest::elapsed_time() const {
+ return impl()->elapsed_time();
+}
+
+// Returns true iff the unit test passed (i.e. all test cases passed).
+bool UnitTest::Passed() const { return impl()->Passed(); }
+
+// Returns true iff the unit test failed (i.e. some test case failed
+// or something outside of all tests failed).
+bool UnitTest::Failed() const { return impl()->Failed(); }
+
+// Gets the i-th test case among all the test cases. i can range from 0 to
+// total_test_case_count() - 1. If i is not in that range, returns NULL.
+const TestCase* UnitTest::GetTestCase(int i) const {
+ return impl()->GetTestCase(i);
+}
+
+// Gets the i-th test case among all the test cases. i can range from 0 to
+// total_test_case_count() - 1. If i is not in that range, returns NULL.
+TestCase* UnitTest::GetMutableTestCase(int i) {
+ return impl()->GetMutableTestCase(i);
+}
+
+// Returns the list of event listeners that can be used to track events
+// inside Google Test.
+TestEventListeners& UnitTest::listeners() {
+ return *impl()->listeners();
+}
+
+// Registers and returns a global test environment. When a test
+// program is run, all global test environments will be set-up in the
+// order they were registered. After all tests in the program have
+// finished, all global test environments will be torn-down in the
+// *reverse* order they were registered.
+//
+// The UnitTest object takes ownership of the given environment.
+//
+// We don't protect this under mutex_, as we only support calling it
+// from the main thread.
+Environment* UnitTest::AddEnvironment(Environment* env) {
+ if (env == NULL) {
+ return NULL;
+ }
+
+ impl_->environments().push_back(env);
+ return env;
+}
+
+#if GTEST_HAS_EXCEPTIONS
+// A failed Google Test assertion will throw an exception of this type
+// when exceptions are enabled. We derive it from std::runtime_error,
+// which is for errors presumably detectable only at run time. Since
+// std::runtime_error inherits from std::exception, many testing
+// frameworks know how to extract and print the message inside it.
+class GoogleTestFailureException : public ::std::runtime_error {
+ public:
+ explicit GoogleTestFailureException(const TestPartResult& failure)
+ : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {}
+};
+#endif
+
+// Adds a TestPartResult to the current TestResult object. All Google Test
+// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call
+// this to report their results. The user code should use the
+// assertion macros instead of calling this directly.
+// L < mutex_
+void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
+ const char* file_name,
+ int line_number,
+ const internal::String& message,
+ const internal::String& os_stack_trace) {
+ Message msg;
+ msg << message;
+
+ internal::MutexLock lock(&mutex_);
+ if (impl_->gtest_trace_stack().size() > 0) {
+ msg << "\n" << GTEST_NAME_ << " trace:";
+
+ for (int i = static_cast<int>(impl_->gtest_trace_stack().size());
+ i > 0; --i) {
+ const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];
+ msg << "\n" << internal::FormatFileLocation(trace.file, trace.line)
+ << " " << trace.message;
+ }
+ }
+
+ if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) {
+ msg << internal::kStackTraceMarker << os_stack_trace;
+ }
+
+ const TestPartResult result =
+ TestPartResult(result_type, file_name, line_number,
+ msg.GetString().c_str());
+ impl_->GetTestPartResultReporterForCurrentThread()->
+ ReportTestPartResult(result);
+
+ if (result_type != TestPartResult::kSuccess) {
+ // gtest_break_on_failure takes precedence over
+ // gtest_throw_on_failure. This allows a user to set the latter
+ // in the code (perhaps in order to use Google Test assertions
+ // with another testing framework) and specify the former on the
+ // command line for debugging.
+ if (GTEST_FLAG(break_on_failure)) {
+#if GTEST_OS_WINDOWS
+ // Using DebugBreak on Windows allows gtest to still break into a debugger
+ // when a failure happens and both the --gtest_break_on_failure and
+ // the --gtest_catch_exceptions flags are specified.
+ DebugBreak();
+#else
+ *static_cast<int*>(NULL) = 1;
+#endif // GTEST_OS_WINDOWS
+ } else if (GTEST_FLAG(throw_on_failure)) {
+#if GTEST_HAS_EXCEPTIONS
+ throw GoogleTestFailureException(result);
+#else
+ // We cannot call abort() as it generates a pop-up in debug mode
+ // that cannot be suppressed in VC 7.1 or below.
+ exit(1);
+#endif
+ }
+ }
+}
+
+// Creates and adds a property to the current TestResult. If a property matching
+// the supplied value already exists, updates its value instead.
+void UnitTest::RecordPropertyForCurrentTest(const char* key,
+ const char* value) {
+ const TestProperty test_property(key, value);
+ impl_->current_test_result()->RecordProperty(test_property);
+}
+
+// Runs all tests in this UnitTest object and prints the result.
+// Returns 0 if successful, or 1 otherwise.
+//
+// We don't protect this under mutex_, as we only support calling it
+// from the main thread.
+int UnitTest::Run() {
+#if GTEST_HAS_SEH
+ // Catch SEH-style exceptions.
+
+ const bool in_death_test_child_process =
+ internal::GTEST_FLAG(internal_run_death_test).length() > 0;
+
+ // Either the user wants Google Test to catch exceptions thrown by the
+ // tests or this is executing in the context of death test child
+ // process. In either case the user does not want to see pop-up dialogs
+ // about crashes - they are expected..
+ if (GTEST_FLAG(catch_exceptions) || in_death_test_child_process) {
+#if !GTEST_OS_WINDOWS_MOBILE
+ // SetErrorMode doesn't exist on CE.
+ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
+ SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
+#endif // !GTEST_OS_WINDOWS_MOBILE
+
+#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE
+ // Death test children can be terminated with _abort(). On Windows,
+ // _abort() can show a dialog with a warning message. This forces the
+ // abort message to go to stderr instead.
+ _set_error_mode(_OUT_TO_STDERR);
+#endif
+
+#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE
+ // In the debug version, Visual Studio pops up a separate dialog
+ // offering a choice to debug the aborted program. We need to suppress
+ // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement
+ // executed. Google Test will notify the user of any unexpected
+ // failure via stderr.
+ //
+ // VC++ doesn't define _set_abort_behavior() prior to the version 8.0.
+ // Users of prior VC versions shall suffer the agony and pain of
+ // clicking through the countless debug dialogs.
+ // TODO(vladl@google.com): find a way to suppress the abort dialog() in the
+ // debug mode when compiled with VC 7.1 or lower.
+ if (!GTEST_FLAG(break_on_failure))
+ _set_abort_behavior(
+ 0x0, // Clear the following flags:
+ _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump.
+#endif
+ }
+
+ __try {
+ return impl_->RunAllTests();
+ } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+ GetExceptionCode())) {
+ printf("Exception thrown with code 0x%x.\nFAIL\n", GetExceptionCode());
+ fflush(stdout);
+ return 1;
+ }
+
+#else // We are on a compiler or platform that doesn't support SEH.
+
+ return impl_->RunAllTests();
+#endif // GTEST_HAS_SEH
+}
+
+// Returns the working directory when the first TEST() or TEST_F() was
+// executed.
+const char* UnitTest::original_working_dir() const {
+ return impl_->original_working_dir_.c_str();
+}
+
+// Returns the TestCase object for the test that's currently running,
+// or NULL if no test is running.
+// L < mutex_
+const TestCase* UnitTest::current_test_case() const {
+ internal::MutexLock lock(&mutex_);
+ return impl_->current_test_case();
+}
+
+// Returns the TestInfo object for the test that's currently running,
+// or NULL if no test is running.
+// L < mutex_
+const TestInfo* UnitTest::current_test_info() const {
+ internal::MutexLock lock(&mutex_);
+ return impl_->current_test_info();
+}
+
+// Returns the random seed used at the start of the current test run.
+int UnitTest::random_seed() const { return impl_->random_seed(); }
+
+#if GTEST_HAS_PARAM_TEST
+// Returns ParameterizedTestCaseRegistry object used to keep track of
+// value-parameterized tests and instantiate and register them.
+// L < mutex_
+internal::ParameterizedTestCaseRegistry&
+ UnitTest::parameterized_test_registry() {
+ return impl_->parameterized_test_registry();
+}
+#endif // GTEST_HAS_PARAM_TEST
+
+// Creates an empty UnitTest.
+UnitTest::UnitTest() {
+ impl_ = new internal::UnitTestImpl(this);
+}
+
+// Destructor of UnitTest.
+UnitTest::~UnitTest() {
+ delete impl_;
+}
+
+// Pushes a trace defined by SCOPED_TRACE() on to the per-thread
+// Google Test trace stack.
+// L < mutex_
+void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) {
+ internal::MutexLock lock(&mutex_);
+ impl_->gtest_trace_stack().push_back(trace);
+}
+
+// Pops a trace from the per-thread Google Test trace stack.
+// L < mutex_
+void UnitTest::PopGTestTrace() {
+ internal::MutexLock lock(&mutex_);
+ impl_->gtest_trace_stack().pop_back();
+}
+
+namespace internal {
+
+UnitTestImpl::UnitTestImpl(UnitTest* parent)
+ : parent_(parent),
+#ifdef _MSC_VER
+#pragma warning(push) // Saves the current warning state.
+#pragma warning(disable:4355) // Temporarily disables warning 4355
+ // (using this in initializer).
+ default_global_test_part_result_reporter_(this),
+ default_per_thread_test_part_result_reporter_(this),
+#pragma warning(pop) // Restores the warning state again.
+#else
+ default_global_test_part_result_reporter_(this),
+ default_per_thread_test_part_result_reporter_(this),
+#endif // _MSC_VER
+ global_test_part_result_repoter_(
+ &default_global_test_part_result_reporter_),
+ per_thread_test_part_result_reporter_(
+ &default_per_thread_test_part_result_reporter_),
+#if GTEST_HAS_PARAM_TEST
+ parameterized_test_registry_(),
+ parameterized_tests_registered_(false),
+#endif // GTEST_HAS_PARAM_TEST
+ last_death_test_case_(-1),
+ current_test_case_(NULL),
+ current_test_info_(NULL),
+ ad_hoc_test_result_(),
+ os_stack_trace_getter_(NULL),
+ post_flag_parse_init_performed_(false),
+ random_seed_(0), // Will be overridden by the flag before first use.
+ random_(0), // Will be reseeded before first use.
+#if GTEST_HAS_DEATH_TEST
+ elapsed_time_(0),
+ internal_run_death_test_flag_(NULL),
+ death_test_factory_(new DefaultDeathTestFactory) {
+#else
+ elapsed_time_(0) {
+#endif // GTEST_HAS_DEATH_TEST
+ listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);
+}
+
+UnitTestImpl::~UnitTestImpl() {
+ // Deletes every TestCase.
+ ForEach(test_cases_, internal::Delete<TestCase>);
+
+ // Deletes every Environment.
+ ForEach(environments_, internal::Delete<Environment>);
+
+ delete os_stack_trace_getter_;
+}
+
+#if GTEST_HAS_DEATH_TEST
+// Disables event forwarding if the control is currently in a death test
+// subprocess. Must not be called before InitGoogleTest.
+void UnitTestImpl::SuppressTestEventsIfInSubprocess() {
+ if (internal_run_death_test_flag_.get() != NULL)
+ listeners()->SuppressEventForwarding();
+}
+#endif // GTEST_HAS_DEATH_TEST
+
+// Initializes event listeners performing XML output as specified by
+// UnitTestOptions. Must not be called before InitGoogleTest.
+void UnitTestImpl::ConfigureXmlOutput() {
+ const String& output_format = UnitTestOptions::GetOutputFormat();
+ if (output_format == "xml") {
+ listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
+ UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
+ } else if (output_format != "") {
+ printf("WARNING: unrecognized output format \"%s\" ignored.\n",
+ output_format.c_str());
+ fflush(stdout);
+ }
+}
+
+// Performs initialization dependent upon flag values obtained in
+// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to
+// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest
+// this function is also called from RunAllTests. Since this function can be
+// called more than once, it has to be idempotent.
+void UnitTestImpl::PostFlagParsingInit() {
+ // Ensures that this function does not execute more than once.
+ if (!post_flag_parse_init_performed_) {
+ post_flag_parse_init_performed_ = true;
+
+#if GTEST_HAS_DEATH_TEST
+ InitDeathTestSubprocessControlInfo();
+ SuppressTestEventsIfInSubprocess();
+#endif // GTEST_HAS_DEATH_TEST
+
+ // Registers parameterized tests. This makes parameterized tests
+ // available to the UnitTest reflection API without running
+ // RUN_ALL_TESTS.
+ RegisterParameterizedTests();
+
+ // Configures listeners for XML output. This makes it possible for users
+ // to shut down the default XML output before invoking RUN_ALL_TESTS.
+ ConfigureXmlOutput();
+ }
+}
+
+// A predicate that checks the name of a TestCase against a known
+// value.
+//
+// This is used for implementation of the UnitTest class only. We put
+// it in the anonymous namespace to prevent polluting the outer
+// namespace.
+//
+// TestCaseNameIs is copyable.
+class TestCaseNameIs {
+ public:
+ // Constructor.
+ explicit TestCaseNameIs(const String& name)
+ : name_(name) {}
+
+ // Returns true iff the name of test_case matches name_.
+ bool operator()(const TestCase* test_case) const {
+ return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0;
+ }
+
+ private:
+ String name_;
+};
+
+// Finds and returns a TestCase with the given name. If one doesn't
+// exist, creates one and returns it. It's the CALLER'S
+// RESPONSIBILITY to ensure that this function is only called WHEN THE
+// TESTS ARE NOT SHUFFLED.
+//
+// Arguments:
+//
+// test_case_name: name of the test case
+// set_up_tc: pointer to the function that sets up the test case
+// tear_down_tc: pointer to the function that tears down the test case
+TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
+ const char* comment,
+ Test::SetUpTestCaseFunc set_up_tc,
+ Test::TearDownTestCaseFunc tear_down_tc) {
+ // Can we find a TestCase with the given name?
+ const std::vector<TestCase*>::const_iterator test_case =
+ std::find_if(test_cases_.begin(), test_cases_.end(),
+ TestCaseNameIs(test_case_name));
+
+ if (test_case != test_cases_.end())
+ return *test_case;
+
+ // No. Let's create one.
+ TestCase* const new_test_case =
+ new TestCase(test_case_name, comment, set_up_tc, tear_down_tc);
+
+ // Is this a death test case?
+ if (internal::UnitTestOptions::MatchesFilter(String(test_case_name),
+ kDeathTestCaseFilter)) {
+ // Yes. Inserts the test case after the last death test case
+ // defined so far. This only works when the test cases haven't
+ // been shuffled. Otherwise we may end up running a death test
+ // after a non-death test.
+ ++last_death_test_case_;
+ test_cases_.insert(test_cases_.begin() + last_death_test_case_,
+ new_test_case);
+ } else {
+ // No. Appends to the end of the list.
+ test_cases_.push_back(new_test_case);
+ }
+
+ test_case_indices_.push_back(static_cast<int>(test_case_indices_.size()));
+ return new_test_case;
+}
+
+// Helpers for setting up / tearing down the given environment. They
+// are for use in the ForEach() function.
+static void SetUpEnvironment(Environment* env) { env->SetUp(); }
+static void TearDownEnvironment(Environment* env) { env->TearDown(); }
+
+// Runs all tests in this UnitTest object, prints the result, and
+// returns 0 if all tests are successful, or 1 otherwise. If any
+// exception is thrown during a test on Windows, this test is
+// considered to be failed, but the rest of the tests will still be
+// run. (We disable exceptions on Linux and Mac OS X, so the issue
+// doesn't apply there.)
+// When parameterized tests are enabled, it expands and registers
+// parameterized tests first in RegisterParameterizedTests().
+// All other functions called from RunAllTests() may safely assume that
+// parameterized tests are ready to be counted and run.
+int UnitTestImpl::RunAllTests() {
+ // Makes sure InitGoogleTest() was called.
+ if (!GTestIsInitialized()) {
+ printf("%s",
+ "\nThis test program did NOT call ::testing::InitGoogleTest "
+ "before calling RUN_ALL_TESTS(). Please fix it.\n");
+ return 1;
+ }
+
+ // Do not run any test if the --help flag was specified.
+ if (g_help_flag)
+ return 0;
+
+ // Repeats the call to the post-flag parsing initialization in case the
+ // user didn't call InitGoogleTest.
+ PostFlagParsingInit();
+
+ // Even if sharding is not on, test runners may want to use the
+ // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
+ // protocol.
+ internal::WriteToShardStatusFileIfNeeded();
+
+ // True iff we are in a subprocess for running a thread-safe-style
+ // death test.
+ bool in_subprocess_for_death_test = false;
+
+#if GTEST_HAS_DEATH_TEST
+ in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
+#endif // GTEST_HAS_DEATH_TEST
+
+ const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
+ in_subprocess_for_death_test);
+
+ // Compares the full test names with the filter to decide which
+ // tests to run.
+ const bool has_tests_to_run = FilterTests(should_shard
+ ? HONOR_SHARDING_PROTOCOL
+ : IGNORE_SHARDING_PROTOCOL) > 0;
+
+ // Lists the tests and exits if the --gtest_list_tests flag was specified.
+ if (GTEST_FLAG(list_tests)) {
+ // This must be called *after* FilterTests() has been called.
+ ListTestsMatchingFilter();
+ return 0;
+ }
+
+ random_seed_ = GTEST_FLAG(shuffle) ?
+ GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0;
+
+ // True iff at least one test has failed.
+ bool failed = false;
+
+ TestEventListener* repeater = listeners()->repeater();
+
+ repeater->OnTestProgramStart(*parent_);
+
+ // How many times to repeat the tests? We don't want to repeat them
+ // when we are inside the subprocess of a death test.
+ const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat);
+ // Repeats forever if the repeat count is negative.
+ const bool forever = repeat < 0;
+ for (int i = 0; forever || i != repeat; i++) {
+ ClearResult();
+
+ const TimeInMillis start = GetTimeInMillis();
+
+ // Shuffles test cases and tests if requested.
+ if (has_tests_to_run && GTEST_FLAG(shuffle)) {
+ random()->Reseed(random_seed_);
+ // This should be done before calling OnTestIterationStart(),
+ // such that a test event listener can see the actual test order
+ // in the event.
+ ShuffleTests();
+ }
+
+ // Tells the unit test event listeners that the tests are about to start.
+ repeater->OnTestIterationStart(*parent_, i);
+
+ // Runs each test case if there is at least one test to run.
+ if (has_tests_to_run) {
+ // Sets up all environments beforehand.
+ repeater->OnEnvironmentsSetUpStart(*parent_);
+ ForEach(environments_, SetUpEnvironment);
+ repeater->OnEnvironmentsSetUpEnd(*parent_);
+
+ // Runs the tests only if there was no fatal failure during global
+ // set-up.
+ if (!Test::HasFatalFailure()) {
+ for (int test_index = 0; test_index < total_test_case_count();
+ test_index++) {
+ GetMutableTestCase(test_index)->Run();
+ }
+ }
+
+ // Tears down all environments in reverse order afterwards.
+ repeater->OnEnvironmentsTearDownStart(*parent_);
+ std::for_each(environments_.rbegin(), environments_.rend(),
+ TearDownEnvironment);
+ repeater->OnEnvironmentsTearDownEnd(*parent_);
+ }
+
+ elapsed_time_ = GetTimeInMillis() - start;
+
+ // Tells the unit test event listener that the tests have just finished.
+ repeater->OnTestIterationEnd(*parent_, i);
+
+ // Gets the result and clears it.
+ if (!Passed()) {
+ failed = true;
+ }
+
+ // Restores the original test order after the iteration. This
+ // allows the user to quickly repro a failure that happens in the
+ // N-th iteration without repeating the first (N - 1) iterations.
+ // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in
+ // case the user somehow changes the value of the flag somewhere
+ // (it's always safe to unshuffle the tests).
+ UnshuffleTests();
+
+ if (GTEST_FLAG(shuffle)) {
+ // Picks a new random seed for each iteration.
+ random_seed_ = GetNextRandomSeed(random_seed_);
+ }
+ }
+
+ repeater->OnTestProgramEnd(*parent_);
+
+ // Returns 0 if all tests passed, or 1 other wise.
+ return failed ? 1 : 0;
+}
+
+// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
+// if the variable is present. If a file already exists at this location, this
+// function will write over it. If the variable is present, but the file cannot
+// be created, prints an error and exits.
+void WriteToShardStatusFileIfNeeded() {
+ const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);
+ if (test_shard_file != NULL) {
+ FILE* const file = posix::FOpen(test_shard_file, "w");
+ if (file == NULL) {
+ ColoredPrintf(COLOR_RED,
+ "Could not write to the test shard status file \"%s\" "
+ "specified by the %s environment variable.\n",
+ test_shard_file, kTestShardStatusFile);
+ fflush(stdout);
+ exit(EXIT_FAILURE);
+ }
+ fclose(file);
+ }
+}
+
+// Checks whether sharding is enabled by examining the relevant
+// environment variable values. If the variables are present,
+// but inconsistent (i.e., shard_index >= total_shards), prints
+// an error and exits. If in_subprocess_for_death_test, sharding is
+// disabled because it must only be applied to the original test
+// process. Otherwise, we could filter out death tests we intended to execute.
+bool ShouldShard(const char* total_shards_env,
+ const char* shard_index_env,
+ bool in_subprocess_for_death_test) {
+ if (in_subprocess_for_death_test) {
+ return false;
+ }
+
+ const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1);
+ const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1);
+
+ if (total_shards == -1 && shard_index == -1) {
+ return false;
+ } else if (total_shards == -1 && shard_index != -1) {
+ const Message msg = Message()
+ << "Invalid environment variables: you have "
+ << kTestShardIndex << " = " << shard_index
+ << ", but have left " << kTestTotalShards << " unset.\n";
+ ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+ fflush(stdout);
+ exit(EXIT_FAILURE);
+ } else if (total_shards != -1 && shard_index == -1) {
+ const Message msg = Message()
+ << "Invalid environment variables: you have "
+ << kTestTotalShards << " = " << total_shards
+ << ", but have left " << kTestShardIndex << " unset.\n";
+ ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+ fflush(stdout);
+ exit(EXIT_FAILURE);
+ } else if (shard_index < 0 || shard_index >= total_shards) {
+ const Message msg = Message()
+ << "Invalid environment variables: we require 0 <= "
+ << kTestShardIndex << " < " << kTestTotalShards
+ << ", but you have " << kTestShardIndex << "=" << shard_index
+ << ", " << kTestTotalShards << "=" << total_shards << ".\n";
+ ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+ fflush(stdout);
+ exit(EXIT_FAILURE);
+ }
+
+ return total_shards > 1;
+}
+
+// Parses the environment variable var as an Int32. If it is unset,
+// returns default_val. If it is not an Int32, prints an error
+// and aborts.
+Int32 Int32FromEnvOrDie(const char* const var, Int32 default_val) {
+ const char* str_val = posix::GetEnv(var);
+ if (str_val == NULL) {
+ return default_val;
+ }
+
+ Int32 result;
+ if (!ParseInt32(Message() << "The value of environment variable " << var,
+ str_val, &result)) {
+ exit(EXIT_FAILURE);
+ }
+ return result;
+}
+
+// Given the total number of shards, the shard index, and the test id,
+// returns true iff the test should be run on this shard. The test id is
+// some arbitrary but unique non-negative integer assigned to each test
+// method. Assumes that 0 <= shard_index < total_shards.
+bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
+ return (test_id % total_shards) == shard_index;
+}
+
+// Compares the name of each test with the user-specified filter to
+// decide whether the test should be run, then records the result in
+// each TestCase and TestInfo object.
+// If shard_tests == true, further filters tests based on sharding
+// variables in the environment - see
+// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide.
+// Returns the number of tests that should run.
+int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
+ const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ?
+ Int32FromEnvOrDie(kTestTotalShards, -1) : -1;
+ const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ?
+ Int32FromEnvOrDie(kTestShardIndex, -1) : -1;
+
+ // num_runnable_tests are the number of tests that will
+ // run across all shards (i.e., match filter and are not disabled).
+ // num_selected_tests are the number of tests to be run on
+ // this shard.
+ int num_runnable_tests = 0;
+ int num_selected_tests = 0;
+ for (size_t i = 0; i < test_cases_.size(); i++) {
+ TestCase* const test_case = test_cases_[i];
+ const String &test_case_name = test_case->name();
+ test_case->set_should_run(false);
+
+ for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
+ TestInfo* const test_info = test_case->test_info_list()[j];
+ const String test_name(test_info->name());
+ // A test is disabled if test case name or test name matches
+ // kDisableTestFilter.
+ const bool is_disabled =
+ internal::UnitTestOptions::MatchesFilter(test_case_name,
+ kDisableTestFilter) ||
+ internal::UnitTestOptions::MatchesFilter(test_name,
+ kDisableTestFilter);
+ test_info->impl()->set_is_disabled(is_disabled);
+
+ const bool matches_filter =
+ internal::UnitTestOptions::FilterMatchesTest(test_case_name,
+ test_name);
+ test_info->impl()->set_matches_filter(matches_filter);
+
+ const bool is_runnable =
+ (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
+ matches_filter;
+
+ const bool is_selected = is_runnable &&
+ (shard_tests == IGNORE_SHARDING_PROTOCOL ||
+ ShouldRunTestOnShard(total_shards, shard_index,
+ num_runnable_tests));
+
+ num_runnable_tests += is_runnable;
+ num_selected_tests += is_selected;
+
+ test_info->impl()->set_should_run(is_selected);
+ test_case->set_should_run(test_case->should_run() || is_selected);
+ }
+ }
+ return num_selected_tests;
+}
+
+// Prints the names of the tests matching the user-specified filter flag.
+void UnitTestImpl::ListTestsMatchingFilter() {
+ for (size_t i = 0; i < test_cases_.size(); i++) {
+ const TestCase* const test_case = test_cases_[i];
+ bool printed_test_case_name = false;
+
+ for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
+ const TestInfo* const test_info =
+ test_case->test_info_list()[j];
+ if (test_info->matches_filter()) {
+ if (!printed_test_case_name) {
+ printed_test_case_name = true;
+ printf("%s.\n", test_case->name());
+ }
+ printf(" %s\n", test_info->name());
+ }
+ }
+ }
+ fflush(stdout);
+}
+
+// Sets the OS stack trace getter.
+//
+// Does nothing if the input and the current OS stack trace getter are
+// the same; otherwise, deletes the old getter and makes the input the
+// current getter.
+void UnitTestImpl::set_os_stack_trace_getter(
+ OsStackTraceGetterInterface* getter) {
+ if (os_stack_trace_getter_ != getter) {
+ delete os_stack_trace_getter_;
+ os_stack_trace_getter_ = getter;
+ }
+}
+
+// Returns the current OS stack trace getter if it is not NULL;
+// otherwise, creates an OsStackTraceGetter, makes it the current
+// getter, and returns it.
+OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
+ if (os_stack_trace_getter_ == NULL) {
+ os_stack_trace_getter_ = new OsStackTraceGetter;
+ }
+
+ return os_stack_trace_getter_;
+}
+
+// Returns the TestResult for the test that's currently running, or
+// the TestResult for the ad hoc test if no test is running.
+TestResult* UnitTestImpl::current_test_result() {
+ return current_test_info_ ?
+ current_test_info_->impl()->result() : &ad_hoc_test_result_;
+}
+
+// Shuffles all test cases, and the tests within each test case,
+// making sure that death tests are still run first.
+void UnitTestImpl::ShuffleTests() {
+ // Shuffles the death test cases.
+ ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_);
+
+ // Shuffles the non-death test cases.
+ ShuffleRange(random(), last_death_test_case_ + 1,
+ static_cast<int>(test_cases_.size()), &test_case_indices_);
+
+ // Shuffles the tests inside each test case.
+ for (size_t i = 0; i < test_cases_.size(); i++) {
+ test_cases_[i]->ShuffleTests(random());
+ }
+}
+
+// Restores the test cases and tests to their order before the first shuffle.
+void UnitTestImpl::UnshuffleTests() {
+ for (size_t i = 0; i < test_cases_.size(); i++) {
+ // Unshuffles the tests in each test case.
+ test_cases_[i]->UnshuffleTests();
+ // Resets the index of each test case.
+ test_case_indices_[i] = static_cast<int>(i);
+ }
+}
+
+// TestInfoImpl constructor. The new instance assumes ownership of the test
+// factory object.
+TestInfoImpl::TestInfoImpl(TestInfo* parent,
+ const char* a_test_case_name,
+ const char* a_name,
+ const char* a_test_case_comment,
+ const char* a_comment,
+ TypeId a_fixture_class_id,
+ internal::TestFactoryBase* factory) :
+ parent_(parent),
+ test_case_name_(String(a_test_case_name)),
+ name_(String(a_name)),
+ test_case_comment_(String(a_test_case_comment)),
+ comment_(String(a_comment)),
+ fixture_class_id_(a_fixture_class_id),
+ should_run_(false),
+ is_disabled_(false),
+ matches_filter_(false),
+ factory_(factory) {
+}
+
+// TestInfoImpl destructor.
+TestInfoImpl::~TestInfoImpl() {
+ delete factory_;
+}
+
+// Returns the current OS stack trace as a String.
+//
+// The maximum number of stack frames to be included is specified by
+// the gtest_stack_trace_depth flag. The skip_count parameter
+// specifies the number of top frames to be skipped, which doesn't
+// count against the number of frames to be included.
+//
+// For example, if Foo() calls Bar(), which in turn calls
+// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
+// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
+String GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/,
+ int skip_count) {
+ // We pass skip_count + 1 to skip this wrapper function in addition
+ // to what the user really wants to skip.
+ return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);
+}
+
+// Used by the GTEST_HIDE_UNREACHABLE_CODE_ macro to suppress unreachable
+// code warnings.
+namespace {
+class ClassUniqueToAlwaysTrue {};
+}
+
+bool IsTrue(bool condition) { return condition; }
+
+bool AlwaysTrue() {
+#if GTEST_HAS_EXCEPTIONS
+ // This condition is always false so AlwaysTrue() never actually throws,
+ // but it makes the compiler think that it may throw.
+ if (IsTrue(false))
+ throw ClassUniqueToAlwaysTrue();
+#endif // GTEST_HAS_EXCEPTIONS
+ return true;
+}
+
+// If *pstr starts with the given prefix, modifies *pstr to be right
+// past the prefix and returns true; otherwise leaves *pstr unchanged
+// and returns false. None of pstr, *pstr, and prefix can be NULL.
+bool SkipPrefix(const char* prefix, const char** pstr) {
+ const size_t prefix_len = strlen(prefix);
+ if (strncmp(*pstr, prefix, prefix_len) == 0) {
+ *pstr += prefix_len;
+ return true;
+ }
+ return false;
+}
+
+// Parses a string as a command line flag. The string should have
+// the format "--flag=value". When def_optional is true, the "=value"
+// part can be omitted.
+//
+// Returns the value of the flag, or NULL if the parsing failed.
+const char* ParseFlagValue(const char* str,
+ const char* flag,
+ bool def_optional) {
+ // str and flag must not be NULL.
+ if (str == NULL || flag == NULL) return NULL;
+
+ // The flag must start with "--" followed by GTEST_FLAG_PREFIX_.
+ const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX_, flag);
+ const size_t flag_len = flag_str.length();
+ if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
+
+ // Skips the flag name.
+ const char* flag_end = str + flag_len;
+
+ // When def_optional is true, it's OK to not have a "=value" part.
+ if (def_optional && (flag_end[0] == '\0')) {
+ return flag_end;
+ }
+
+ // If def_optional is true and there are more characters after the
+ // flag name, or if def_optional is false, there must be a '=' after
+ // the flag name.
+ if (flag_end[0] != '=') return NULL;
+
+ // Returns the string after "=".
+ return flag_end + 1;
+}
+
+// Parses a string for a bool flag, in the form of either
+// "--flag=value" or "--flag".
+//
+// In the former case, the value is taken as true as long as it does
+// not start with '0', 'f', or 'F'.
+//
+// In the latter case, the value is taken as true.
+//
+// On success, stores the value of the flag in *value, and returns
+// true. On failure, returns false without changing *value.
+bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
+ // Gets the value of the flag as a string.
+ const char* const value_str = ParseFlagValue(str, flag, true);
+
+ // Aborts if the parsing failed.
+ if (value_str == NULL) return false;
+
+ // Converts the string value to a bool.
+ *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
+ return true;
+}
+
+// Parses a string for an Int32 flag, in the form of
+// "--flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true. On failure, returns false without changing *value.
+bool ParseInt32Flag(const char* str, const char* flag, Int32* value) {
+ // Gets the value of the flag as a string.
+ const char* const value_str = ParseFlagValue(str, flag, false);
+
+ // Aborts if the parsing failed.
+ if (value_str == NULL) return false;
+
+ // Sets *value to the value of the flag.
+ return ParseInt32(Message() << "The value of flag --" << flag,
+ value_str, value);
+}
+
+// Parses a string for a string flag, in the form of
+// "--flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true. On failure, returns false without changing *value.
+bool ParseStringFlag(const char* str, const char* flag, String* value) {
+ // Gets the value of the flag as a string.
+ const char* const value_str = ParseFlagValue(str, flag, false);
+
+ // Aborts if the parsing failed.
+ if (value_str == NULL) return false;
+
+ // Sets *value to the value of the flag.
+ *value = value_str;
+ return true;
+}
+
+// Determines whether a string has a prefix that Google Test uses for its
+// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_.
+// If Google Test detects that a command line flag has its prefix but is not
+// recognized, it will print its help message. Flags starting with
+// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test
+// internal flags and do not trigger the help message.
+static bool HasGoogleTestFlagPrefix(const char* str) {
+ return (SkipPrefix("--", &str) ||
+ SkipPrefix("-", &str) ||
+ SkipPrefix("/", &str)) &&
+ !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) &&
+ (SkipPrefix(GTEST_FLAG_PREFIX_, &str) ||
+ SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str));
+}
+
+// Prints a string containing code-encoded text. The following escape
+// sequences can be used in the string to control the text color:
+//
+// @@ prints a single '@' character.
+// @R changes the color to red.
+// @G changes the color to green.
+// @Y changes the color to yellow.
+// @D changes to the default terminal text color.
+//
+// TODO(wan@google.com): Write tests for this once we add stdout
+// capturing to Google Test.
+static void PrintColorEncoded(const char* str) {
+ GTestColor color = COLOR_DEFAULT; // The current color.
+
+ // Conceptually, we split the string into segments divided by escape
+ // sequences. Then we print one segment at a time. At the end of
+ // each iteration, the str pointer advances to the beginning of the
+ // next segment.
+ for (;;) {
+ const char* p = strchr(str, '@');
+ if (p == NULL) {
+ ColoredPrintf(color, "%s", str);
+ return;
+ }
+
+ ColoredPrintf(color, "%s", String(str, p - str).c_str());
+
+ const char ch = p[1];
+ str = p + 2;
+ if (ch == '@') {
+ ColoredPrintf(color, "@");
+ } else if (ch == 'D') {
+ color = COLOR_DEFAULT;
+ } else if (ch == 'R') {
+ color = COLOR_RED;
+ } else if (ch == 'G') {
+ color = COLOR_GREEN;
+ } else if (ch == 'Y') {
+ color = COLOR_YELLOW;
+ } else {
+ --str;
+ }
+ }
+}
+
+static const char kColorEncodedHelpMessage[] =
+"This program contains tests written using " GTEST_NAME_ ". You can use the\n"
+"following command line flags to control its behavior:\n"
+"\n"
+"Test Selection:\n"
+" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n"
+" List the names of all tests instead of running them. The name of\n"
+" TEST(Foo, Bar) is \"Foo.Bar\".\n"
+" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS"
+ "[@G-@YNEGATIVE_PATTERNS]@D\n"
+" Run only the tests whose name matches one of the positive patterns but\n"
+" none of the negative patterns. '?' matches any single character; '*'\n"
+" matches any substring; ':' separates two patterns.\n"
+" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n"
+" Run all disabled tests too.\n"
+"\n"
+"Test Execution:\n"
+" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n"
+" Run the tests repeatedly; use a negative count to repeat forever.\n"
+" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n"
+" Randomize tests' orders on every iteration.\n"
+" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n"
+" Random number seed to use for shuffling test orders (between 1 and\n"
+" 99999, or 0 to use a seed based on the current time).\n"
+"\n"
+"Test Output:\n"
+" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n"
+" Enable/disable colored output. The default is @Gauto@D.\n"
+" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
+" Don't print the elapsed time of each test.\n"
+" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G"
+ GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
+" Generate an XML report in the given directory or with the given file\n"
+" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n"
+"\n"
+"Assertion Behavior:\n"
+#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
+" Set the default death test style.\n"
+#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n"
+" Turn assertion failures into debugger break-points.\n"
+" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n"
+" Turn assertion failures into C++ exceptions.\n"
+#if GTEST_OS_WINDOWS
+" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions@D\n"
+" Suppress pop-ups caused by exceptions.\n"
+#endif // GTEST_OS_WINDOWS
+"\n"
+"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set "
+ "the corresponding\n"
+"environment variable of a flag (all letters in upper-case). For example, to\n"
+"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_
+ "color=no@D or set\n"
+"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n"
+"\n"
+"For more information, please read the " GTEST_NAME_ " documentation at\n"
+"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n"
+"(not one in your own code or tests), please report it to\n"
+"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test. The type parameter CharType can be
+// instantiated to either char or wchar_t.
+template <typename CharType>
+void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
+ for (int i = 1; i < *argc; i++) {
+ const String arg_string = StreamableToString(argv[i]);
+ const char* const arg = arg_string.c_str();
+
+ using internal::ParseBoolFlag;
+ using internal::ParseInt32Flag;
+ using internal::ParseStringFlag;
+
+ // Do we see a Google Test flag?
+ if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
+ &GTEST_FLAG(also_run_disabled_tests)) ||
+ ParseBoolFlag(arg, kBreakOnFailureFlag,
+ &GTEST_FLAG(break_on_failure)) ||
+ ParseBoolFlag(arg, kCatchExceptionsFlag,
+ &GTEST_FLAG(catch_exceptions)) ||
+ ParseStringFlag(arg, kColorFlag, &GTEST_FLAG(color)) ||
+ ParseStringFlag(arg, kDeathTestStyleFlag,
+ &GTEST_FLAG(death_test_style)) ||
+ ParseBoolFlag(arg, kDeathTestUseFork,
+ &GTEST_FLAG(death_test_use_fork)) ||
+ ParseStringFlag(arg, kFilterFlag, &GTEST_FLAG(filter)) ||
+ ParseStringFlag(arg, kInternalRunDeathTestFlag,
+ &GTEST_FLAG(internal_run_death_test)) ||
+ ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) ||
+ ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) ||
+ ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) ||
+ ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) ||
+ ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||
+ ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||
+ ParseInt32Flag(arg, kStackTraceDepthFlag,
+ &GTEST_FLAG(stack_trace_depth)) ||
+ ParseBoolFlag(arg, kThrowOnFailureFlag, &GTEST_FLAG(throw_on_failure))
+ ) {
+ // Yes. Shift the remainder of the argv list left by one. Note
+ // that argv has (*argc + 1) elements, the last one always being
+ // NULL. The following loop moves the trailing NULL element as
+ // well.
+ for (int j = i; j != *argc; j++) {
+ argv[j] = argv[j + 1];
+ }
+
+ // Decrements the argument count.
+ (*argc)--;
+
+ // We also need to decrement the iterator as we just removed
+ // an element.
+ i--;
+ } else if (arg_string == "--help" || arg_string == "-h" ||
+ arg_string == "-?" || arg_string == "/?" ||
+ HasGoogleTestFlagPrefix(arg)) {
+ // Both help flag and unrecognized Google Test flags (excluding
+ // internal ones) trigger help display.
+ g_help_flag = true;
+ }
+ }
+
+ if (g_help_flag) {
+ // We print the help here instead of in RUN_ALL_TESTS(), as the
+ // latter may not be called at all if the user is using Google
+ // Test with another testing framework.
+ PrintColorEncoded(kColorEncodedHelpMessage);
+ }
+}
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.
+void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
+ ParseGoogleTestFlagsOnlyImpl(argc, argv);
+}
+void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
+ ParseGoogleTestFlagsOnlyImpl(argc, argv);
+}
+
+// The internal implementation of InitGoogleTest().
+//
+// The type parameter CharType can be instantiated to either char or
+// wchar_t.
+template <typename CharType>
+void InitGoogleTestImpl(int* argc, CharType** argv) {
+ g_init_gtest_count++;
+
+ // We don't want to run the initialization code twice.
+ if (g_init_gtest_count != 1) return;
+
+ if (*argc <= 0) return;
+
+ internal::g_executable_path = internal::StreamableToString(argv[0]);
+
+#if GTEST_HAS_DEATH_TEST
+ g_argvs.clear();
+ for (int i = 0; i != *argc; i++) {
+ g_argvs.push_back(StreamableToString(argv[i]));
+ }
+#endif // GTEST_HAS_DEATH_TEST
+
+ ParseGoogleTestFlagsOnly(argc, argv);
+ GetUnitTestImpl()->PostFlagParsingInit();
+}
+
+} // namespace internal
+
+// Initializes Google Test. This must be called before calling
+// RUN_ALL_TESTS(). In particular, it parses a command line for the
+// flags that Google Test recognizes. Whenever a Google Test flag is
+// seen, it is removed from argv, and *argc is decremented.
+//
+// No value is returned. Instead, the Google Test flag variables are
+// updated.
+//
+// Calling the function for the second time has no user-visible effect.
+void InitGoogleTest(int* argc, char** argv) {
+ internal::InitGoogleTestImpl(argc, argv);
+}
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+void InitGoogleTest(int* argc, wchar_t** argv) {
+ internal::InitGoogleTestImpl(argc, argv);
+}
+
+} // namespace testing
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// 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: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev)
+//
+// This file implements death tests.
+
+
+#if GTEST_HAS_DEATH_TEST
+
+#if GTEST_OS_MAC
+#include <crt_externs.h>
+#endif // GTEST_OS_MAC
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdarg.h>
+
+#if GTEST_OS_WINDOWS
+#include <windows.h>
+#else
+#include <sys/mman.h>
+#include <sys/wait.h>
+#endif // GTEST_OS_WINDOWS
+
+#endif // GTEST_HAS_DEATH_TEST
+
+
+// Indicates that this translation unit is part of Google Test's
+// implementation. It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error. This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION_ 1
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+
+// Constants.
+
+// The default death test style.
+static const char kDefaultDeathTestStyle[] = "fast";
+
+GTEST_DEFINE_string_(
+ death_test_style,
+ internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle),
+ "Indicates how to run a death test in a forked child process: "
+ "\"threadsafe\" (child process re-executes the test binary "
+ "from the beginning, running only the specific death test) or "
+ "\"fast\" (child process runs the death test immediately "
+ "after forking).");
+
+GTEST_DEFINE_bool_(
+ death_test_use_fork,
+ internal::BoolFromGTestEnv("death_test_use_fork", false),
+ "Instructs to use fork()/_exit() instead of clone() in death tests. "
+ "Ignored and always uses fork() on POSIX systems where clone() is not "
+ "implemented. Useful when running under valgrind or similar tools if "
+ "those do not support clone(). Valgrind 3.3.1 will just fail if "
+ "it sees an unsupported combination of clone() flags. "
+ "It is not recommended to use this flag w/o valgrind though it will "
+ "work in 99% of the cases. Once valgrind is fixed, this flag will "
+ "most likely be removed.");
+
+namespace internal {
+GTEST_DEFINE_string_(
+ internal_run_death_test, "",
+ "Indicates the file, line number, temporal index of "
+ "the single death test to run, and a file descriptor to "
+ "which a success code may be sent, all separated by "
+ "colons. This flag is specified if and only if the current "
+ "process is a sub-process launched for running a thread-safe "
+ "death test. FOR INTERNAL USE ONLY.");
+} // namespace internal
+
+#if GTEST_HAS_DEATH_TEST
+
+// ExitedWithCode constructor.
+ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {
+}
+
+// ExitedWithCode function-call operator.
+bool ExitedWithCode::operator()(int exit_status) const {
+#if GTEST_OS_WINDOWS
+ return exit_status == exit_code_;
+#else
+ return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;
+#endif // GTEST_OS_WINDOWS
+}
+
+#if !GTEST_OS_WINDOWS
+// KilledBySignal constructor.
+KilledBySignal::KilledBySignal(int signum) : signum_(signum) {
+}
+
+// KilledBySignal function-call operator.
+bool KilledBySignal::operator()(int exit_status) const {
+ return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;
+}
+#endif // !GTEST_OS_WINDOWS
+
+namespace internal {
+
+// Utilities needed for death tests.
+
+// Generates a textual description of a given exit code, in the format
+// specified by wait(2).
+static String ExitSummary(int exit_code) {
+ Message m;
+#if GTEST_OS_WINDOWS
+ m << "Exited with exit status " << exit_code;
+#else
+ if (WIFEXITED(exit_code)) {
+ m << "Exited with exit status " << WEXITSTATUS(exit_code);
+ } else if (WIFSIGNALED(exit_code)) {
+ m << "Terminated by signal " << WTERMSIG(exit_code);
+ }
+#ifdef WCOREDUMP
+ if (WCOREDUMP(exit_code)) {
+ m << " (core dumped)";
+ }
+#endif
+#endif // GTEST_OS_WINDOWS
+ return m.GetString();
+}
+
+// Returns true if exit_status describes a process that was terminated
+// by a signal, or exited normally with a nonzero exit code.
+bool ExitedUnsuccessfully(int exit_status) {
+ return !ExitedWithCode(0)(exit_status);
+}
+
+#if !GTEST_OS_WINDOWS
+// Generates a textual failure message when a death test finds more than
+// one thread running, or cannot determine the number of threads, prior
+// to executing the given statement. It is the responsibility of the
+// caller not to pass a thread_count of 1.
+static String DeathTestThreadWarning(size_t thread_count) {
+ Message msg;
+ msg << "Death tests use fork(), which is unsafe particularly"
+ << " in a threaded context. For this test, " << GTEST_NAME_ << " ";
+ if (thread_count == 0)
+ msg << "couldn't detect the number of threads.";
+ else
+ msg << "detected " << thread_count << " threads.";
+ return msg.GetString();
+}
+#endif // !GTEST_OS_WINDOWS
+
+// Flag characters for reporting a death test that did not die.
+static const char kDeathTestLived = 'L';
+static const char kDeathTestReturned = 'R';
+static const char kDeathTestInternalError = 'I';
+
+// An enumeration describing all of the possible ways that a death test
+// can conclude. DIED means that the process died while executing the
+// test code; LIVED means that process lived beyond the end of the test
+// code; and RETURNED means that the test statement attempted a "return,"
+// which is not allowed. IN_PROGRESS means the test has not yet
+// concluded.
+enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED };
+
+// Routine for aborting the program which is safe to call from an
+// exec-style death test child process, in which case the error
+// message is propagated back to the parent process. Otherwise, the
+// message is simply printed to stderr. In either case, the program
+// then exits with status 1.
+void DeathTestAbort(const String& message) {
+ // On a POSIX system, this function may be called from a threadsafe-style
+ // death test child process, which operates on a very small stack. Use
+ // the heap for any additional non-minuscule memory requirements.
+ const InternalRunDeathTestFlag* const flag =
+ GetUnitTestImpl()->internal_run_death_test_flag();
+ if (flag != NULL) {
+ FILE* parent = posix::FDOpen(flag->write_fd(), "w");
+ fputc(kDeathTestInternalError, parent);
+ fprintf(parent, "%s", message.c_str());
+ fflush(parent);
+ _exit(1);
+ } else {
+ fprintf(stderr, "%s", message.c_str());
+ fflush(stderr);
+ abort();
+ }
+}
+
+// A replacement for CHECK that calls DeathTestAbort if the assertion
+// fails.
+#define GTEST_DEATH_TEST_CHECK_(expression) \
+ do { \
+ if (!::testing::internal::IsTrue(expression)) { \
+ DeathTestAbort(::testing::internal::String::Format( \
+ "CHECK failed: File %s, line %d: %s", \
+ __FILE__, __LINE__, #expression)); \
+ } \
+ } while (::testing::internal::AlwaysFalse())
+
+// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for
+// evaluating any system call that fulfills two conditions: it must return
+// -1 on failure, and set errno to EINTR when it is interrupted and
+// should be tried again. The macro expands to a loop that repeatedly
+// evaluates the expression as long as it evaluates to -1 and sets
+// errno to EINTR. If the expression evaluates to -1 but errno is
+// something other than EINTR, DeathTestAbort is called.
+#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \
+ do { \
+ int gtest_retval; \
+ do { \
+ gtest_retval = (expression); \
+ } while (gtest_retval == -1 && errno == EINTR); \
+ if (gtest_retval == -1) { \
+ DeathTestAbort(::testing::internal::String::Format( \
+ "CHECK failed: File %s, line %d: %s != -1", \
+ __FILE__, __LINE__, #expression)); \
+ } \
+ } while (::testing::internal::AlwaysFalse())
+
+// Returns the message describing the last system error in errno.
+String GetLastErrnoDescription() {
+ return String(errno == 0 ? "" : posix::StrError(errno));
+}
+
+// This is called from a death test parent process to read a failure
+// message from the death test child process and log it with the FATAL
+// severity. On Windows, the message is read from a pipe handle. On other
+// platforms, it is read from a file descriptor.
+static void FailFromInternalError(int fd) {
+ Message error;
+ char buffer[256];
+ int num_read;
+
+ do {
+ while ((num_read = posix::Read(fd, buffer, 255)) > 0) {
+ buffer[num_read] = '\0';
+ error << buffer;
+ }
+ } while (num_read == -1 && errno == EINTR);
+
+ if (num_read == 0) {
+ GTEST_LOG_(FATAL) << error.GetString();
+ } else {
+ const int last_error = errno;
+ GTEST_LOG_(FATAL) << "Error while reading death test internal: "
+ << GetLastErrnoDescription() << " [" << last_error << "]";
+ }
+}
+
+// Death test constructor. Increments the running death test count
+// for the current test.
+DeathTest::DeathTest() {
+ TestInfo* const info = GetUnitTestImpl()->current_test_info();
+ if (info == NULL) {
+ DeathTestAbort("Cannot run a death test outside of a TEST or "
+ "TEST_F construct");
+ }
+}
+
+// Creates and returns a death test by dispatching to the current
+// death test factory.
+bool DeathTest::Create(const char* statement, const RE* regex,
+ const char* file, int line, DeathTest** test) {
+ return GetUnitTestImpl()->death_test_factory()->Create(
+ statement, regex, file, line, test);
+}
+
+const char* DeathTest::LastMessage() {
+ return last_death_test_message_.c_str();
+}
+
+void DeathTest::set_last_death_test_message(const String& message) {
+ last_death_test_message_ = message;
+}
+
+String DeathTest::last_death_test_message_;
+
+// Provides cross platform implementation for some death functionality.
+class DeathTestImpl : public DeathTest {
+ protected:
+ DeathTestImpl(const char* a_statement, const RE* a_regex)
+ : statement_(a_statement),
+ regex_(a_regex),
+ spawned_(false),
+ status_(-1),
+ outcome_(IN_PROGRESS),
+ read_fd_(-1),
+ write_fd_(-1) {}
+
+ // read_fd_ is expected to be closed and cleared by a derived class.
+ ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }
+
+ void Abort(AbortReason reason);
+ virtual bool Passed(bool status_ok);
+
+ const char* statement() const { return statement_; }
+ const RE* regex() const { return regex_; }
+ bool spawned() const { return spawned_; }
+ void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
+ int status() const { return status_; }
+ void set_status(int a_status) { status_ = a_status; }
+ DeathTestOutcome outcome() const { return outcome_; }
+ void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; }
+ int read_fd() const { return read_fd_; }
+ void set_read_fd(int fd) { read_fd_ = fd; }
+ int write_fd() const { return write_fd_; }
+ void set_write_fd(int fd) { write_fd_ = fd; }
+
+ // Called in the parent process only. Reads the result code of the death
+ // test child process via a pipe, interprets it to set the outcome_
+ // member, and closes read_fd_. Outputs diagnostics and terminates in
+ // case of unexpected codes.
+ void ReadAndInterpretStatusByte();
+
+ private:
+ // The textual content of the code this object is testing. This class
+ // doesn't own this string and should not attempt to delete it.
+ const char* const statement_;
+ // The regular expression which test output must match. DeathTestImpl
+ // doesn't own this object and should not attempt to delete it.
+ const RE* const regex_;
+ // True if the death test child process has been successfully spawned.
+ bool spawned_;
+ // The exit status of the child process.
+ int status_;
+ // How the death test concluded.
+ DeathTestOutcome outcome_;
+ // Descriptor to the read end of the pipe to the child process. It is
+ // always -1 in the child process. The child keeps its write end of the
+ // pipe in write_fd_.
+ int read_fd_;
+ // Descriptor to the child's write end of the pipe to the parent process.
+ // It is always -1 in the parent process. The parent keeps its end of the
+ // pipe in read_fd_.
+ int write_fd_;
+};
+
+// Called in the parent process only. Reads the result code of the death
+// test child process via a pipe, interprets it to set the outcome_
+// member, and closes read_fd_. Outputs diagnostics and terminates in
+// case of unexpected codes.
+void DeathTestImpl::ReadAndInterpretStatusByte() {
+ char flag;
+ int bytes_read;
+
+ // The read() here blocks until data is available (signifying the
+ // failure of the death test) or until the pipe is closed (signifying
+ // its success), so it's okay to call this in the parent before
+ // the child process has exited.
+ do {
+ bytes_read = posix::Read(read_fd(), &flag, 1);
+ } while (bytes_read == -1 && errno == EINTR);
+
+ if (bytes_read == 0) {
+ set_outcome(DIED);
+ } else if (bytes_read == 1) {
+ switch (flag) {
+ case kDeathTestReturned:
+ set_outcome(RETURNED);
+ break;
+ case kDeathTestLived:
+ set_outcome(LIVED);
+ break;
+ case kDeathTestInternalError:
+ FailFromInternalError(read_fd()); // Does not return.
+ break;
+ default:
+ GTEST_LOG_(FATAL) << "Death test child process reported "
+ << "unexpected status byte ("
+ << static_cast<unsigned int>(flag) << ")";
+ }
+ } else {
+ GTEST_LOG_(FATAL) << "Read from death test child process failed: "
+ << GetLastErrnoDescription();
+ }
+ GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));
+ set_read_fd(-1);
+}
+
+// Signals that the death test code which should have exited, didn't.
+// Should be called only in a death test child process.
+// Writes a status byte to the child's status file descriptor, then
+// calls _exit(1).
+void DeathTestImpl::Abort(AbortReason reason) {
+ // The parent process considers the death test to be a failure if
+ // it finds any data in our pipe. So, here we write a single flag byte
+ // to the pipe, then exit.
+ const char status_ch =
+ reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned;
+ GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
+ GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(write_fd()));
+ _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
+}
+
+// Assesses the success or failure of a death test, using both private
+// members which have previously been set, and one argument:
+//
+// Private data members:
+// outcome: An enumeration describing how the death test
+// concluded: DIED, LIVED, or RETURNED. The death test fails
+// in the latter two cases.
+// status: The exit status of the child process. On *nix, it is in the
+// in the format specified by wait(2). On Windows, this is the
+// value supplied to the ExitProcess() API or a numeric code
+// of the exception that terminated the program.
+// regex: A regular expression object to be applied to
+// the test's captured standard error output; the death test
+// fails if it does not match.
+//
+// Argument:
+// status_ok: true if exit_status is acceptable in the context of
+// this particular death test, which fails if it is false
+//
+// Returns true iff all of the above conditions are met. Otherwise, the
+// first failing condition, in the order given above, is the one that is
+// reported. Also sets the last death test message string.
+bool DeathTestImpl::Passed(bool status_ok) {
+ if (!spawned())
+ return false;
+
+ const String error_message = GetCapturedStderr();
+
+ bool success = false;
+ Message buffer;
+
+ buffer << "Death test: " << statement() << "\n";
+ switch (outcome()) {
+ case LIVED:
+ buffer << " Result: failed to die.\n"
+ << " Error msg: " << error_message;
+ break;
+ case RETURNED:
+ buffer << " Result: illegal return in test statement.\n"
+ << " Error msg: " << error_message;
+ break;
+ case DIED:
+ if (status_ok) {
+ const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
+ if (matched) {
+ success = true;
+ } else {
+ buffer << " Result: died but not with expected error.\n"
+ << " Expected: " << regex()->pattern() << "\n"
+ << "Actual msg: " << error_message;
+ }
+ } else {
+ buffer << " Result: died but not with expected exit code:\n"
+ << " " << ExitSummary(status()) << "\n";
+ }
+ break;
+ case IN_PROGRESS:
+ default:
+ GTEST_LOG_(FATAL)
+ << "DeathTest::Passed somehow called before conclusion of test";
+ }
+
+ DeathTest::set_last_death_test_message(buffer.GetString());
+ return success;
+}
+
+#if GTEST_OS_WINDOWS
+// WindowsDeathTest implements death tests on Windows. Due to the
+// specifics of starting new processes on Windows, death tests there are
+// always threadsafe, and Google Test considers the
+// --gtest_death_test_style=fast setting to be equivalent to
+// --gtest_death_test_style=threadsafe there.
+//
+// A few implementation notes: Like the Linux version, the Windows
+// implementation uses pipes for child-to-parent communication. But due to
+// the specifics of pipes on Windows, some extra steps are required:
+//
+// 1. The parent creates a communication pipe and stores handles to both
+// ends of it.
+// 2. The parent starts the child and provides it with the information
+// necessary to acquire the handle to the write end of the pipe.
+// 3. The child acquires the write end of the pipe and signals the parent
+// using a Windows event.
+// 4. Now the parent can release the write end of the pipe on its side. If
+// this is done before step 3, the object's reference count goes down to
+// 0 and it is destroyed, preventing the child from acquiring it. The
+// parent now has to release it, or read operations on the read end of
+// the pipe will not return when the child terminates.
+// 5. The parent reads child's output through the pipe (outcome code and
+// any possible error messages) from the pipe, and its stderr and then
+// determines whether to fail the test.
+//
+// Note: to distinguish Win32 API calls from the local method and function
+// calls, the former are explicitly resolved in the global namespace.
+//
+class WindowsDeathTest : public DeathTestImpl {
+ public:
+ WindowsDeathTest(const char* statement,
+ const RE* regex,
+ const char* file,
+ int line)
+ : DeathTestImpl(statement, regex), file_(file), line_(line) {}
+
+ // All of these virtual functions are inherited from DeathTest.
+ virtual int Wait();
+ virtual TestRole AssumeRole();
+
+ private:
+ // The name of the file in which the death test is located.
+ const char* const file_;
+ // The line number on which the death test is located.
+ const int line_;
+ // Handle to the write end of the pipe to the child process.
+ AutoHandle write_handle_;
+ // Child process handle.
+ AutoHandle child_handle_;
+ // Event the child process uses to signal the parent that it has
+ // acquired the handle to the write end of the pipe. After seeing this
+ // event the parent can release its own handles to make sure its
+ // ReadFile() calls return when the child terminates.
+ AutoHandle event_handle_;
+};
+
+// Waits for the child in a death test to exit, returning its exit
+// status, or 0 if no child process exists. As a side effect, sets the
+// outcome data member.
+int WindowsDeathTest::Wait() {
+ if (!spawned())
+ return 0;
+
+ // Wait until the child either signals that it has acquired the write end
+ // of the pipe or it dies.
+ const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() };
+ switch (::WaitForMultipleObjects(2,
+ wait_handles,
+ FALSE, // Waits for any of the handles.
+ INFINITE)) {
+ case WAIT_OBJECT_0:
+ case WAIT_OBJECT_0 + 1:
+ break;
+ default:
+ GTEST_DEATH_TEST_CHECK_(false); // Should not get here.
+ }
+
+ // The child has acquired the write end of the pipe or exited.
+ // We release the handle on our side and continue.
+ write_handle_.Reset();
+ event_handle_.Reset();
+
+ ReadAndInterpretStatusByte();
+
+ // Waits for the child process to exit if it haven't already. This
+ // returns immediately if the child has already exited, regardless of
+ // whether previous calls to WaitForMultipleObjects synchronized on this
+ // handle or not.
+ GTEST_DEATH_TEST_CHECK_(
+ WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(),
+ INFINITE));
+ DWORD status;
+ GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), &status)
+ != FALSE);
+ child_handle_.Reset();
+ set_status(static_cast<int>(status));
+ return this->status();
+}
+
+// The AssumeRole process for a Windows death test. It creates a child
+// process with the same executable as the current process to run the
+// death test. The child process is given the --gtest_filter and
+// --gtest_internal_run_death_test flags such that it knows to run the
+// current death test only.
+DeathTest::TestRole WindowsDeathTest::AssumeRole() {
+ const UnitTestImpl* const impl = GetUnitTestImpl();
+ const InternalRunDeathTestFlag* const flag =
+ impl->internal_run_death_test_flag();
+ const TestInfo* const info = impl->current_test_info();
+ const int death_test_index = info->result()->death_test_count();
+
+ if (flag != NULL) {
+ // ParseInternalRunDeathTestFlag() has performed all the necessary
+ // processing.
+ set_write_fd(flag->write_fd());
+ return EXECUTE_TEST;
+ }
+
+ // WindowsDeathTest uses an anonymous pipe to communicate results of
+ // a death test.
+ SECURITY_ATTRIBUTES handles_are_inheritable = {
+ sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
+ HANDLE read_handle, write_handle;
+ GTEST_DEATH_TEST_CHECK_(
+ ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable,
+ 0) // Default buffer size.
+ != FALSE);
+ set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle),
+ O_RDONLY));
+ write_handle_.Reset(write_handle);
+ event_handle_.Reset(::CreateEvent(
+ &handles_are_inheritable,
+ TRUE, // The event will automatically reset to non-signaled state.
+ FALSE, // The initial state is non-signalled.
+ NULL)); // The even is unnamed.
+ GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL);
+ const String filter_flag = String::Format("--%s%s=%s.%s",
+ GTEST_FLAG_PREFIX_, kFilterFlag,
+ info->test_case_name(),
+ info->name());
+ const String internal_flag = String::Format(
+ "--%s%s=%s|%d|%d|%u|%Iu|%Iu",
+ GTEST_FLAG_PREFIX_,
+ kInternalRunDeathTestFlag,
+ file_, line_,
+ death_test_index,
+ static_cast<unsigned int>(::GetCurrentProcessId()),
+ // size_t has the same with as pointers on both 32-bit and 64-bit
+ // Windows platforms.
+ // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
+ reinterpret_cast<size_t>(write_handle),
+ reinterpret_cast<size_t>(event_handle_.Get()));
+
+ char executable_path[_MAX_PATH + 1]; // NOLINT
+ GTEST_DEATH_TEST_CHECK_(
+ _MAX_PATH + 1 != ::GetModuleFileNameA(NULL,
+ executable_path,
+ _MAX_PATH));
+
+ String command_line = String::Format("%s %s \"%s\"",
+ ::GetCommandLineA(),
+ filter_flag.c_str(),
+ internal_flag.c_str());
+
+ DeathTest::set_last_death_test_message("");
+
+ CaptureStderr();
+ // Flush the log buffers since the log streams are shared with the child.
+ FlushInfoLog();
+
+ // The child process will share the standard handles with the parent.
+ STARTUPINFOA startup_info;
+ memset(&startup_info, 0, sizeof(STARTUPINFO));
+ startup_info.dwFlags = STARTF_USESTDHANDLES;
+ startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);
+ startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
+ startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
+
+ PROCESS_INFORMATION process_info;
+ GTEST_DEATH_TEST_CHECK_(::CreateProcessA(
+ executable_path,
+ const_cast<char*>(command_line.c_str()),
+ NULL, // Retuned process handle is not inheritable.
+ NULL, // Retuned thread handle is not inheritable.
+ TRUE, // Child inherits all inheritable handles (for write_handle_).
+ 0x0, // Default creation flags.
+ NULL, // Inherit the parent's environment.
+ UnitTest::GetInstance()->original_working_dir(),
+ &startup_info,
+ &process_info) != FALSE);
+ child_handle_.Reset(process_info.hProcess);
+ ::CloseHandle(process_info.hThread);
+ set_spawned(true);
+ return OVERSEE_TEST;
+}
+#else // We are not on Windows.
+
+// ForkingDeathTest provides implementations for most of the abstract
+// methods of the DeathTest interface. Only the AssumeRole method is
+// left undefined.
+class ForkingDeathTest : public DeathTestImpl {
+ public:
+ ForkingDeathTest(const char* statement, const RE* regex);
+
+ // All of these virtual functions are inherited from DeathTest.
+ virtual int Wait();
+
+ protected:
+ void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
+
+ private:
+ // PID of child process during death test; 0 in the child process itself.
+ pid_t child_pid_;
+};
+
+// Constructs a ForkingDeathTest.
+ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex)
+ : DeathTestImpl(a_statement, a_regex),
+ child_pid_(-1) {}
+
+// Waits for the child in a death test to exit, returning its exit
+// status, or 0 if no child process exists. As a side effect, sets the
+// outcome data member.
+int ForkingDeathTest::Wait() {
+ if (!spawned())
+ return 0;
+
+ ReadAndInterpretStatusByte();
+
+ int status_value;
+ GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0));
+ set_status(status_value);
+ return status_value;
+}
+
+// A concrete death test class that forks, then immediately runs the test
+// in the child process.
+class NoExecDeathTest : public ForkingDeathTest {
+ public:
+ NoExecDeathTest(const char* a_statement, const RE* a_regex) :
+ ForkingDeathTest(a_statement, a_regex) { }
+ virtual TestRole AssumeRole();
+};
+
+// The AssumeRole process for a fork-and-run death test. It implements a
+// straightforward fork, with a simple pipe to transmit the status byte.
+DeathTest::TestRole NoExecDeathTest::AssumeRole() {
+ const size_t thread_count = GetThreadCount();
+ if (thread_count != 1) {
+ GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count);
+ }
+
+ int pipe_fd[2];
+ GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);
+
+ DeathTest::set_last_death_test_message("");
+ CaptureStderr();
+ // When we fork the process below, the log file buffers are copied, but the
+ // file descriptors are shared. We flush all log files here so that closing
+ // the file descriptors in the child process doesn't throw off the
+ // synchronization between descriptors and buffers in the parent process.
+ // This is as close to the fork as possible to avoid a race condition in case
+ // there are multiple threads running before the death test, and another
+ // thread writes to the log file.
+ FlushInfoLog();
+
+ const pid_t child_pid = fork();
+ GTEST_DEATH_TEST_CHECK_(child_pid != -1);
+ set_child_pid(child_pid);
+ if (child_pid == 0) {
+ GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0]));
+ set_write_fd(pipe_fd[1]);
+ // Redirects all logging to stderr in the child process to prevent
+ // concurrent writes to the log files. We capture stderr in the parent
+ // process and append the child process' output to a log.
+ LogToStderr();
+ // Event forwarding to the listeners of event listener API mush be shut
+ // down in death test subprocesses.
+ GetUnitTestImpl()->listeners()->SuppressEventForwarding();
+ return EXECUTE_TEST;
+ } else {
+ GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
+ set_read_fd(pipe_fd[0]);
+ set_spawned(true);
+ return OVERSEE_TEST;
+ }
+}
+
+// A concrete death test class that forks and re-executes the main
+// program from the beginning, with command-line flags set that cause
+// only this specific death test to be run.
+class ExecDeathTest : public ForkingDeathTest {
+ public:
+ ExecDeathTest(const char* a_statement, const RE* a_regex,
+ const char* file, int line) :
+ ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { }
+ virtual TestRole AssumeRole();
+ private:
+ // The name of the file in which the death test is located.
+ const char* const file_;
+ // The line number on which the death test is located.
+ const int line_;
+};
+
+// Utility class for accumulating command-line arguments.
+class Arguments {
+ public:
+ Arguments() {
+ args_.push_back(NULL);
+ }
+
+ ~Arguments() {
+ for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
+ ++i) {
+ free(*i);
+ }
+ }
+ void AddArgument(const char* argument) {
+ args_.insert(args_.end() - 1, posix::StrDup(argument));
+ }
+
+ template <typename Str>
+ void AddArguments(const ::std::vector<Str>& arguments) {
+ for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
+ i != arguments.end();
+ ++i) {
+ args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
+ }
+ }
+ char* const* Argv() {
+ return &args_[0];
+ }
+ private:
+ std::vector<char*> args_;
+};
+
+// A struct that encompasses the arguments to the child process of a
+// threadsafe-style death test process.
+struct ExecDeathTestArgs {
+ char* const* argv; // Command-line arguments for the child's call to exec
+ int close_fd; // File descriptor to close; the read end of a pipe
+};
+
+#if GTEST_OS_MAC
+inline char** GetEnviron() {
+ // When Google Test is built as a framework on MacOS X, the environ variable
+ // is unavailable. Apple's documentation (man environ) recommends using
+ // _NSGetEnviron() instead.
+ return *_NSGetEnviron();
+}
+#else
+// Some POSIX platforms expect you to declare environ. extern "C" makes
+// it reside in the global namespace.
+extern "C" char** environ;
+inline char** GetEnviron() { return environ; }
+#endif // GTEST_OS_MAC
+
+// The main function for a threadsafe-style death test child process.
+// This function is called in a clone()-ed process and thus must avoid
+// any potentially unsafe operations like malloc or libc functions.
+static int ExecDeathTestChildMain(void* child_arg) {
+ ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg);
+ GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd));
+
+ // We need to execute the test program in the same environment where
+ // it was originally invoked. Therefore we change to the original
+ // working directory first.
+ const char* const original_dir =
+ UnitTest::GetInstance()->original_working_dir();
+ // We can safely call chdir() as it's a direct system call.
+ if (chdir(original_dir) != 0) {
+ DeathTestAbort(String::Format("chdir(\"%s\") failed: %s",
+ original_dir,
+ GetLastErrnoDescription().c_str()));
+ return EXIT_FAILURE;
+ }
+
+ // We can safely call execve() as it's a direct system call. We
+ // cannot use execvp() as it's a libc function and thus potentially
+ // unsafe. Since execve() doesn't search the PATH, the user must
+ // invoke the test program via a valid path that contains at least
+ // one path separator.
+ execve(args->argv[0], args->argv, GetEnviron());
+ DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s",
+ args->argv[0],
+ original_dir,
+ GetLastErrnoDescription().c_str()));
+ return EXIT_FAILURE;
+}
+
+// Two utility routines that together determine the direction the stack
+// grows.
+// This could be accomplished more elegantly by a single recursive
+// function, but we want to guard against the unlikely possibility of
+// a smart compiler optimizing the recursion away.
+bool StackLowerThanAddress(const void* ptr) {
+ int dummy;
+ return &dummy < ptr;
+}
+
+bool StackGrowsDown() {
+ int dummy;
+ return StackLowerThanAddress(&dummy);
+}
+
+// A threadsafe implementation of fork(2) for threadsafe-style death tests
+// that uses clone(2). It dies with an error message if anything goes
+// wrong.
+static pid_t ExecDeathTestFork(char* const* argv, int close_fd) {
+ ExecDeathTestArgs args = { argv, close_fd };
+ pid_t child_pid = -1;
+
+#if GTEST_HAS_CLONE
+ const bool use_fork = GTEST_FLAG(death_test_use_fork);
+
+ if (!use_fork) {
+ static const bool stack_grows_down = StackGrowsDown();
+ const size_t stack_size = getpagesize();
+ // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.
+ void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE, -1, 0);
+ GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);
+ void* const stack_top =
+ static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0);
+
+ child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);
+
+ GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);
+ }
+#else
+ const bool use_fork = true;
+#endif // GTEST_HAS_CLONE
+
+ if (use_fork && (child_pid = fork()) == 0) {
+ ExecDeathTestChildMain(&args);
+ _exit(0);
+ }
+
+ GTEST_DEATH_TEST_CHECK_(child_pid != -1);
+ return child_pid;
+}
+
+// The AssumeRole process for a fork-and-exec death test. It re-executes the
+// main program from the beginning, setting the --gtest_filter
+// and --gtest_internal_run_death_test flags to cause only the current
+// death test to be re-run.
+DeathTest::TestRole ExecDeathTest::AssumeRole() {
+ const UnitTestImpl* const impl = GetUnitTestImpl();
+ const InternalRunDeathTestFlag* const flag =
+ impl->internal_run_death_test_flag();
+ const TestInfo* const info = impl->current_test_info();
+ const int death_test_index = info->result()->death_test_count();
+
+ if (flag != NULL) {
+ set_write_fd(flag->write_fd());
+ return EXECUTE_TEST;
+ }
+
+ int pipe_fd[2];
+ GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);
+ // Clear the close-on-exec flag on the write end of the pipe, lest
+ // it be closed when the child process does an exec:
+ GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
+
+ const String filter_flag =
+ String::Format("--%s%s=%s.%s",
+ GTEST_FLAG_PREFIX_, kFilterFlag,
+ info->test_case_name(), info->name());
+ const String internal_flag =
+ String::Format("--%s%s=%s|%d|%d|%d",
+ GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag,
+ file_, line_, death_test_index, pipe_fd[1]);
+ Arguments args;
+ args.AddArguments(GetArgvs());
+ args.AddArgument(filter_flag.c_str());
+ args.AddArgument(internal_flag.c_str());
+
+ DeathTest::set_last_death_test_message("");
+
+ CaptureStderr();
+ // See the comment in NoExecDeathTest::AssumeRole for why the next line
+ // is necessary.
+ FlushInfoLog();
+
+ const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]);
+ GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
+ set_child_pid(child_pid);
+ set_read_fd(pipe_fd[0]);
+ set_spawned(true);
+ return OVERSEE_TEST;
+}
+
+#endif // !GTEST_OS_WINDOWS
+
+// Creates a concrete DeathTest-derived class that depends on the
+// --gtest_death_test_style flag, and sets the pointer pointed to
+// by the "test" argument to its address. If the test should be
+// skipped, sets that pointer to NULL. Returns true, unless the
+// flag is set to an invalid value.
+bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
+ const char* file, int line,
+ DeathTest** test) {
+ UnitTestImpl* const impl = GetUnitTestImpl();
+ const InternalRunDeathTestFlag* const flag =
+ impl->internal_run_death_test_flag();
+ const int death_test_index = impl->current_test_info()
+ ->increment_death_test_count();
+
+ if (flag != NULL) {
+ if (death_test_index > flag->index()) {
+ DeathTest::set_last_death_test_message(String::Format(
+ "Death test count (%d) somehow exceeded expected maximum (%d)",
+ death_test_index, flag->index()));
+ return false;
+ }
+
+ if (!(flag->file() == file && flag->line() == line &&
+ flag->index() == death_test_index)) {
+ *test = NULL;
+ return true;
+ }
+ }
+
+#if GTEST_OS_WINDOWS
+ if (GTEST_FLAG(death_test_style) == "threadsafe" ||
+ GTEST_FLAG(death_test_style) == "fast") {
+ *test = new WindowsDeathTest(statement, regex, file, line);
+ }
+#else
+ if (GTEST_FLAG(death_test_style) == "threadsafe") {
+ *test = new ExecDeathTest(statement, regex, file, line);
+ } else if (GTEST_FLAG(death_test_style) == "fast") {
+ *test = new NoExecDeathTest(statement, regex);
+ }
+#endif // GTEST_OS_WINDOWS
+ else { // NOLINT - this is more readable than unbalanced brackets inside #if.
+ DeathTest::set_last_death_test_message(String::Format(
+ "Unknown death test style \"%s\" encountered",
+ GTEST_FLAG(death_test_style).c_str()));
+ return false;
+ }
+
+ return true;
+}
+
+// Splits a given string on a given delimiter, populating a given
+// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have
+// ::std::string, so we can use it here.
+static void SplitString(const ::std::string& str, char delimiter,
+ ::std::vector< ::std::string>* dest) {
+ ::std::vector< ::std::string> parsed;
+ ::std::string::size_type pos = 0;
+ while (::testing::internal::AlwaysTrue()) {
+ const ::std::string::size_type colon = str.find(delimiter, pos);
+ if (colon == ::std::string::npos) {
+ parsed.push_back(str.substr(pos));
+ break;
+ } else {
+ parsed.push_back(str.substr(pos, colon - pos));
+ pos = colon + 1;
+ }
+ }
+ dest->swap(parsed);
+}
+
+#if GTEST_OS_WINDOWS
+// Recreates the pipe and event handles from the provided parameters,
+// signals the event, and returns a file descriptor wrapped around the pipe
+// handle. This function is called in the child process only.
+int GetStatusFileDescriptor(unsigned int parent_process_id,
+ size_t write_handle_as_size_t,
+ size_t event_handle_as_size_t) {
+ AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
+ FALSE, // Non-inheritable.
+ parent_process_id));
+ if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {
+ DeathTestAbort(String::Format("Unable to open parent process %u",
+ parent_process_id));
+ }
+
+ // TODO(vladl@google.com): Replace the following check with a
+ // compile-time assertion when available.
+ GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
+
+ const HANDLE write_handle =
+ reinterpret_cast<HANDLE>(write_handle_as_size_t);
+ HANDLE dup_write_handle;
+
+ // The newly initialized handle is accessible only in in the parent
+ // process. To obtain one accessible within the child, we need to use
+ // DuplicateHandle.
+ if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,
+ ::GetCurrentProcess(), &dup_write_handle,
+ 0x0, // Requested privileges ignored since
+ // DUPLICATE_SAME_ACCESS is used.
+ FALSE, // Request non-inheritable handler.
+ DUPLICATE_SAME_ACCESS)) {
+ DeathTestAbort(String::Format(
+ "Unable to duplicate the pipe handle %Iu from the parent process %u",
+ write_handle_as_size_t, parent_process_id));
+ }
+
+ const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);
+ HANDLE dup_event_handle;
+
+ if (!::DuplicateHandle(parent_process_handle.Get(), event_handle,
+ ::GetCurrentProcess(), &dup_event_handle,
+ 0x0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS)) {
+ DeathTestAbort(String::Format(
+ "Unable to duplicate the event handle %Iu from the parent process %u",
+ event_handle_as_size_t, parent_process_id));
+ }
+
+ const int write_fd =
+ ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND);
+ if (write_fd == -1) {
+ DeathTestAbort(String::Format(
+ "Unable to convert pipe handle %Iu to a file descriptor",
+ write_handle_as_size_t));
+ }
+
+ // Signals the parent that the write end of the pipe has been acquired
+ // so the parent can release its own write end.
+ ::SetEvent(dup_event_handle);
+
+ return write_fd;
+}
+#endif // GTEST_OS_WINDOWS
+
+// Returns a newly created InternalRunDeathTestFlag object with fields
+// initialized from the GTEST_FLAG(internal_run_death_test) flag if
+// the flag is specified; otherwise returns NULL.
+InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
+ if (GTEST_FLAG(internal_run_death_test) == "") return NULL;
+
+ // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
+ // can use it here.
+ int line = -1;
+ int index = -1;
+ ::std::vector< ::std::string> fields;
+ SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields);
+ int write_fd = -1;
+
+#if GTEST_OS_WINDOWS
+ unsigned int parent_process_id = 0;
+ size_t write_handle_as_size_t = 0;
+ size_t event_handle_as_size_t = 0;
+
+ if (fields.size() != 6
+ || !ParseNaturalNumber(fields[1], &line)
+ || !ParseNaturalNumber(fields[2], &index)
+ || !ParseNaturalNumber(fields[3], &parent_process_id)
+ || !ParseNaturalNumber(fields[4], &write_handle_as_size_t)
+ || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
+ DeathTestAbort(String::Format(
+ "Bad --gtest_internal_run_death_test flag: %s",
+ GTEST_FLAG(internal_run_death_test).c_str()));
+ }
+ write_fd = GetStatusFileDescriptor(parent_process_id,
+ write_handle_as_size_t,
+ event_handle_as_size_t);
+#else
+ if (fields.size() != 4
+ || !ParseNaturalNumber(fields[1], &line)
+ || !ParseNaturalNumber(fields[2], &index)
+ || !ParseNaturalNumber(fields[3], &write_fd)) {
+ DeathTestAbort(String::Format(
+ "Bad --gtest_internal_run_death_test flag: %s",
+ GTEST_FLAG(internal_run_death_test).c_str()));
+ }
+#endif // GTEST_OS_WINDOWS
+ return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);
+}
+
+} // namespace internal
+
+#endif // GTEST_HAS_DEATH_TEST
+
+} // namespace testing
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// 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.
+//
+// Authors: keith.ray@gmail.com (Keith Ray)
+
+
+#include <stdlib.h>
+
+#if GTEST_OS_WINDOWS_MOBILE
+#include <windows.h>
+#elif GTEST_OS_WINDOWS
+#include <direct.h>
+#include <io.h>
+#elif GTEST_OS_SYMBIAN
+// Symbian OpenC has PATH_MAX in sys/syslimits.h
+#include <sys/syslimits.h>
+#else
+#include <limits.h>
+#include <climits> // Some Linux distributions define PATH_MAX here.
+#endif // GTEST_OS_WINDOWS_MOBILE
+
+#if GTEST_OS_WINDOWS
+#define GTEST_PATH_MAX_ _MAX_PATH
+#elif defined(PATH_MAX)
+#define GTEST_PATH_MAX_ PATH_MAX
+#elif defined(_XOPEN_PATH_MAX)
+#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
+#else
+#define GTEST_PATH_MAX_ _POSIX_PATH_MAX
+#endif // GTEST_OS_WINDOWS
+
+
+namespace testing {
+namespace internal {
+
+#if GTEST_OS_WINDOWS
+// On Windows, '\\' is the standard path separator, but many tools and the
+// Windows API also accept '/' as an alternate path separator. Unless otherwise
+// noted, a file path can contain either kind of path separators, or a mixture
+// of them.
+const char kPathSeparator = '\\';
+const char kAlternatePathSeparator = '/';
+const char kPathSeparatorString[] = "\\";
+const char kAlternatePathSeparatorString[] = "/";
+#if GTEST_OS_WINDOWS_MOBILE
+// Windows CE doesn't have a current directory. You should not use
+// the current directory in tests on Windows CE, but this at least
+// provides a reasonable fallback.
+const char kCurrentDirectoryString[] = "\\";
+// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
+const DWORD kInvalidFileAttributes = 0xffffffff;
+#else
+const char kCurrentDirectoryString[] = ".\\";
+#endif // GTEST_OS_WINDOWS_MOBILE
+#else
+const char kPathSeparator = '/';
+const char kPathSeparatorString[] = "/";
+const char kCurrentDirectoryString[] = "./";
+#endif // GTEST_OS_WINDOWS
+
+// Returns whether the given character is a valid path separator.
+static bool IsPathSeparator(char c) {
+#if GTEST_HAS_ALT_PATH_SEP_
+ return (c == kPathSeparator) || (c == kAlternatePathSeparator);
+#else
+ return c == kPathSeparator;
+#endif
+}
+
+// Returns the current working directory, or "" if unsuccessful.
+FilePath FilePath::GetCurrentDir() {
+#if GTEST_OS_WINDOWS_MOBILE
+ // Windows CE doesn't have a current directory, so we just return
+ // something reasonable.
+ return FilePath(kCurrentDirectoryString);
+#elif GTEST_OS_WINDOWS
+ char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
+ return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
+#else
+ char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
+ return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
+#endif // GTEST_OS_WINDOWS_MOBILE
+}
+
+// Returns a copy of the FilePath with the case-insensitive extension removed.
+// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
+// FilePath("dir/file"). If a case-insensitive extension is not
+// found, returns a copy of the original FilePath.
+FilePath FilePath::RemoveExtension(const char* extension) const {
+ String dot_extension(String::Format(".%s", extension));
+ if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) {
+ return FilePath(String(pathname_.c_str(), pathname_.length() - 4));
+ }
+ return *this;
+}
+
+// Returns a pointer to the last occurence of a valid path separator in
+// the FilePath. On Windows, for example, both '/' and '\' are valid path
+// separators. Returns NULL if no path separator was found.
+const char* FilePath::FindLastPathSeparator() const {
+ const char* const last_sep = strrchr(c_str(), kPathSeparator);
+#if GTEST_HAS_ALT_PATH_SEP_
+ const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
+ // Comparing two pointers of which only one is NULL is undefined.
+ if (last_alt_sep != NULL &&
+ (last_sep == NULL || last_alt_sep > last_sep)) {
+ return last_alt_sep;
+ }
+#endif
+ return last_sep;
+}
+
+// Returns a copy of the FilePath with the directory part removed.
+// Example: FilePath("path/to/file").RemoveDirectoryName() returns
+// FilePath("file"). If there is no directory part ("just_a_file"), it returns
+// the FilePath unmodified. If there is no file part ("just_a_dir/") it
+// returns an empty FilePath ("").
+// On Windows platform, '\' is the path separator, otherwise it is '/'.
+FilePath FilePath::RemoveDirectoryName() const {
+ const char* const last_sep = FindLastPathSeparator();
+ return last_sep ? FilePath(String(last_sep + 1)) : *this;
+}
+
+// RemoveFileName returns the directory path with the filename removed.
+// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
+// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
+// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
+// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
+// On Windows platform, '\' is the path separator, otherwise it is '/'.
+FilePath FilePath::RemoveFileName() const {
+ const char* const last_sep = FindLastPathSeparator();
+ String dir;
+ if (last_sep) {
+ dir = String(c_str(), last_sep + 1 - c_str());
+ } else {
+ dir = kCurrentDirectoryString;
+ }
+ return FilePath(dir);
+}
+
+// Helper functions for naming files in a directory for xml output.
+
+// Given directory = "dir", base_name = "test", number = 0,
+// extension = "xml", returns "dir/test.xml". If number is greater
+// than zero (e.g., 12), returns "dir/test_12.xml".
+// On Windows platform, uses \ as the separator rather than /.
+FilePath FilePath::MakeFileName(const FilePath& directory,
+ const FilePath& base_name,
+ int number,
+ const char* extension) {
+ String file;
+ if (number == 0) {
+ file = String::Format("%s.%s", base_name.c_str(), extension);
+ } else {
+ file = String::Format("%s_%d.%s", base_name.c_str(), number, extension);
+ }
+ return ConcatPaths(directory, FilePath(file));
+}
+
+// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
+// On Windows, uses \ as the separator rather than /.
+FilePath FilePath::ConcatPaths(const FilePath& directory,
+ const FilePath& relative_path) {
+ if (directory.IsEmpty())
+ return relative_path;
+ const FilePath dir(directory.RemoveTrailingPathSeparator());
+ return FilePath(String::Format("%s%c%s", dir.c_str(), kPathSeparator,
+ relative_path.c_str()));
+}
+
+// Returns true if pathname describes something findable in the file-system,
+// either a file, directory, or whatever.
+bool FilePath::FileOrDirectoryExists() const {
+#if GTEST_OS_WINDOWS_MOBILE
+ LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
+ const DWORD attributes = GetFileAttributes(unicode);
+ delete [] unicode;
+ return attributes != kInvalidFileAttributes;
+#else
+ posix::StatStruct file_stat;
+ return posix::Stat(pathname_.c_str(), &file_stat) == 0;
+#endif // GTEST_OS_WINDOWS_MOBILE
+}
+
+// Returns true if pathname describes a directory in the file-system
+// that exists.
+bool FilePath::DirectoryExists() const {
+ bool result = false;
+#if GTEST_OS_WINDOWS
+ // Don't strip off trailing separator if path is a root directory on
+ // Windows (like "C:\\").
+ const FilePath& path(IsRootDirectory() ? *this :
+ RemoveTrailingPathSeparator());
+#else
+ const FilePath& path(*this);
+#endif
+
+#if GTEST_OS_WINDOWS_MOBILE
+ LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
+ const DWORD attributes = GetFileAttributes(unicode);
+ delete [] unicode;
+ if ((attributes != kInvalidFileAttributes) &&
+ (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ result = true;
+ }
+#else
+ posix::StatStruct file_stat;
+ result = posix::Stat(path.c_str(), &file_stat) == 0 &&
+ posix::IsDir(file_stat);
+#endif // GTEST_OS_WINDOWS_MOBILE
+
+ return result;
+}
+
+// Returns true if pathname describes a root directory. (Windows has one
+// root directory per disk drive.)
+bool FilePath::IsRootDirectory() const {
+#if GTEST_OS_WINDOWS
+ // TODO(wan@google.com): on Windows a network share like
+ // \\server\share can be a root directory, although it cannot be the
+ // current directory. Handle this properly.
+ return pathname_.length() == 3 && IsAbsolutePath();
+#else
+ return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
+#endif
+}
+
+// Returns true if pathname describes an absolute path.
+bool FilePath::IsAbsolutePath() const {
+ const char* const name = pathname_.c_str();
+#if GTEST_OS_WINDOWS
+ return pathname_.length() >= 3 &&
+ ((name[0] >= 'a' && name[0] <= 'z') ||
+ (name[0] >= 'A' && name[0] <= 'Z')) &&
+ name[1] == ':' &&
+ IsPathSeparator(name[2]);
+#else
+ return IsPathSeparator(name[0]);
+#endif
+}
+
+// Returns a pathname for a file that does not currently exist. The pathname
+// will be directory/base_name.extension or
+// directory/base_name_<number>.extension if directory/base_name.extension
+// already exists. The number will be incremented until a pathname is found
+// that does not already exist.
+// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
+// There could be a race condition if two or more processes are calling this
+// function at the same time -- they could both pick the same filename.
+FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
+ const FilePath& base_name,
+ const char* extension) {
+ FilePath full_pathname;
+ int number = 0;
+ do {
+ full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
+ } while (full_pathname.FileOrDirectoryExists());
+ return full_pathname;
+}
+
+// Returns true if FilePath ends with a path separator, which indicates that
+// it is intended to represent a directory. Returns false otherwise.
+// This does NOT check that a directory (or file) actually exists.
+bool FilePath::IsDirectory() const {
+ return !pathname_.empty() &&
+ IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
+}
+
+// Create directories so that path exists. Returns true if successful or if
+// the directories already exist; returns false if unable to create directories
+// for any reason.
+bool FilePath::CreateDirectoriesRecursively() const {
+ if (!this->IsDirectory()) {
+ return false;
+ }
+
+ if (pathname_.length() == 0 || this->DirectoryExists()) {
+ return true;
+ }
+
+ const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
+ return parent.CreateDirectoriesRecursively() && this->CreateFolder();
+}
+
+// Create the directory so that path exists. Returns true if successful or
+// if the directory already exists; returns false if unable to create the
+// directory for any reason, including if the parent directory does not
+// exist. Not named "CreateDirectory" because that's a macro on Windows.
+bool FilePath::CreateFolder() const {
+#if GTEST_OS_WINDOWS_MOBILE
+ FilePath removed_sep(this->RemoveTrailingPathSeparator());
+ LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
+ int result = CreateDirectory(unicode, NULL) ? 0 : -1;
+ delete [] unicode;
+#elif GTEST_OS_WINDOWS
+ int result = _mkdir(pathname_.c_str());
+#else
+ int result = mkdir(pathname_.c_str(), 0777);
+#endif // GTEST_OS_WINDOWS_MOBILE
+
+ if (result == -1) {
+ return this->DirectoryExists(); // An error is OK if the directory exists.
+ }
+ return true; // No error.
+}
+
+// If input name has a trailing separator character, remove it and return the
+// name, otherwise return the name string unmodified.
+// On Windows platform, uses \ as the separator, other platforms use /.
+FilePath FilePath::RemoveTrailingPathSeparator() const {
+ return IsDirectory()
+ ? FilePath(String(pathname_.c_str(), pathname_.length() - 1))
+ : *this;
+}
+
+// Removes any redundant separators that might be in the pathname.
+// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
+// redundancies that might be in a pathname involving "." or "..".
+// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
+void FilePath::Normalize() {
+ if (pathname_.c_str() == NULL) {
+ pathname_ = "";
+ return;
+ }
+ const char* src = pathname_.c_str();
+ char* const dest = new char[pathname_.length() + 1];
+ char* dest_ptr = dest;
+ memset(dest_ptr, 0, pathname_.length() + 1);
+
+ while (*src != '\0') {
+ *dest_ptr = *src;
+ if (!IsPathSeparator(*src)) {
+ src++;
+ } else {
+#if GTEST_HAS_ALT_PATH_SEP_
+ if (*dest_ptr == kAlternatePathSeparator) {
+ *dest_ptr = kPathSeparator;
+ }
+#endif
+ while (IsPathSeparator(*src))
+ src++;
+ }
+ dest_ptr++;
+ }
+ *dest_ptr = '\0';
+ pathname_ = dest;
+ delete[] dest;
+}
+
+} // namespace internal
+} // namespace testing
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// 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: wan@google.com (Zhanyong Wan)
+
+
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#if GTEST_OS_WINDOWS_MOBILE
+#include <windows.h> // For TerminateProcess()
+#elif GTEST_OS_WINDOWS
+#include <io.h>
+#include <sys/stat.h>
+#else
+#include <unistd.h>
+#endif // GTEST_OS_WINDOWS_MOBILE
+
+#if GTEST_OS_MAC
+#include <mach/mach_init.h>
+#include <mach/task.h>
+#include <mach/vm_map.h>
+#endif // GTEST_OS_MAC
+
+
+// Indicates that this translation unit is part of Google Test's
+// implementation. It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error. This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION_ 1
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+namespace internal {
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// MSVC and C++Builder do not provide a definition of STDERR_FILENO.
+const int kStdOutFileno = 1;
+const int kStdErrFileno = 2;
+#else
+const int kStdOutFileno = STDOUT_FILENO;
+const int kStdErrFileno = STDERR_FILENO;
+#endif // _MSC_VER
+
+#if GTEST_OS_MAC
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+size_t GetThreadCount() {
+ const task_t task = mach_task_self();
+ mach_msg_type_number_t thread_count;
+ thread_act_array_t thread_list;
+ const kern_return_t status = task_threads(task, &thread_list, &thread_count);
+ if (status == KERN_SUCCESS) {
+ // task_threads allocates resources in thread_list and we need to free them
+ // to avoid leaks.
+ vm_deallocate(task,
+ reinterpret_cast<vm_address_t>(thread_list),
+ sizeof(thread_t) * thread_count);
+ return static_cast<size_t>(thread_count);
+ } else {
+ return 0;
+ }
+}
+
+#else
+
+size_t GetThreadCount() {
+ // There's no portable way to detect the number of threads, so we just
+ // return 0 to indicate that we cannot detect it.
+ return 0;
+}
+
+#endif // GTEST_OS_MAC
+
+#if GTEST_USES_POSIX_RE
+
+// Implements RE. Currently only needed for death tests.
+
+RE::~RE() {
+ if (is_valid_) {
+ // regfree'ing an invalid regex might crash because the content
+ // of the regex is undefined. Since the regex's are essentially
+ // the same, one cannot be valid (or invalid) without the other
+ // being so too.
+ regfree(&partial_regex_);
+ regfree(&full_regex_);
+ }
+ free(const_cast<char*>(pattern_));
+}
+
+// Returns true iff regular expression re matches the entire str.
+bool RE::FullMatch(const char* str, const RE& re) {
+ if (!re.is_valid_) return false;
+
+ regmatch_t match;
+ return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
+}
+
+// Returns true iff regular expression re matches a substring of str
+// (including str itself).
+bool RE::PartialMatch(const char* str, const RE& re) {
+ if (!re.is_valid_) return false;
+
+ regmatch_t match;
+ return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
+}
+
+// Initializes an RE from its string representation.
+void RE::Init(const char* regex) {
+ pattern_ = posix::StrDup(regex);
+
+ // Reserves enough bytes to hold the regular expression used for a
+ // full match.
+ const size_t full_regex_len = strlen(regex) + 10;
+ char* const full_pattern = new char[full_regex_len];
+
+ snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
+ is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
+ // We want to call regcomp(&partial_regex_, ...) even if the
+ // previous expression returns false. Otherwise partial_regex_ may
+ // not be properly initialized can may cause trouble when it's
+ // freed.
+ //
+ // Some implementation of POSIX regex (e.g. on at least some
+ // versions of Cygwin) doesn't accept the empty string as a valid
+ // regex. We change it to an equivalent form "()" to be safe.
+ if (is_valid_) {
+ const char* const partial_regex = (*regex == '\0') ? "()" : regex;
+ is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
+ }
+ EXPECT_TRUE(is_valid_)
+ << "Regular expression \"" << regex
+ << "\" is not a valid POSIX Extended regular expression.";
+
+ delete[] full_pattern;
+}
+
+#elif GTEST_USES_SIMPLE_RE
+
+// Returns true iff ch appears anywhere in str (excluding the
+// terminating '\0' character).
+bool IsInSet(char ch, const char* str) {
+ return ch != '\0' && strchr(str, ch) != NULL;
+}
+
+// Returns true iff ch belongs to the given classification. Unlike
+// similar functions in <ctype.h>, these aren't affected by the
+// current locale.
+bool IsDigit(char ch) { return '0' <= ch && ch <= '9'; }
+bool IsPunct(char ch) {
+ return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
+}
+bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
+bool IsWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
+bool IsWordChar(char ch) {
+ return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
+ ('0' <= ch && ch <= '9') || ch == '_';
+}
+
+// Returns true iff "\\c" is a supported escape sequence.
+bool IsValidEscape(char c) {
+ return (IsPunct(c) || IsInSet(c, "dDfnrsStvwW"));
+}
+
+// Returns true iff the given atom (specified by escaped and pattern)
+// matches ch. The result is undefined if the atom is invalid.
+bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
+ if (escaped) { // "\\p" where p is pattern_char.
+ switch (pattern_char) {
+ case 'd': return IsDigit(ch);
+ case 'D': return !IsDigit(ch);
+ case 'f': return ch == '\f';
+ case 'n': return ch == '\n';
+ case 'r': return ch == '\r';
+ case 's': return IsWhiteSpace(ch);
+ case 'S': return !IsWhiteSpace(ch);
+ case 't': return ch == '\t';
+ case 'v': return ch == '\v';
+ case 'w': return IsWordChar(ch);
+ case 'W': return !IsWordChar(ch);
+ }
+ return IsPunct(pattern_char) && pattern_char == ch;
+ }
+
+ return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
+}
+
+// Helper function used by ValidateRegex() to format error messages.
+String FormatRegexSyntaxError(const char* regex, int index) {
+ return (Message() << "Syntax error at index " << index
+ << " in simple regular expression \"" << regex << "\": ").GetString();
+}
+
+// Generates non-fatal failures and returns false if regex is invalid;
+// otherwise returns true.
+bool ValidateRegex(const char* regex) {
+ if (regex == NULL) {
+ // TODO(wan@google.com): fix the source file location in the
+ // assertion failures to match where the regex is used in user
+ // code.
+ ADD_FAILURE() << "NULL is not a valid simple regular expression.";
+ return false;
+ }
+
+ bool is_valid = true;
+
+ // True iff ?, *, or + can follow the previous atom.
+ bool prev_repeatable = false;
+ for (int i = 0; regex[i]; i++) {
+ if (regex[i] == '\\') { // An escape sequence
+ i++;
+ if (regex[i] == '\0') {
+ ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
+ << "'\\' cannot appear at the end.";
+ return false;
+ }
+
+ if (!IsValidEscape(regex[i])) {
+ ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
+ << "invalid escape sequence \"\\" << regex[i] << "\".";
+ is_valid = false;
+ }
+ prev_repeatable = true;
+ } else { // Not an escape sequence.
+ const char ch = regex[i];
+
+ if (ch == '^' && i > 0) {
+ ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+ << "'^' can only appear at the beginning.";
+ is_valid = false;
+ } else if (ch == '$' && regex[i + 1] != '\0') {
+ ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+ << "'$' can only appear at the end.";
+ is_valid = false;
+ } else if (IsInSet(ch, "()[]{}|")) {
+ ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+ << "'" << ch << "' is unsupported.";
+ is_valid = false;
+ } else if (IsRepeat(ch) && !prev_repeatable) {
+ ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+ << "'" << ch << "' can only follow a repeatable token.";
+ is_valid = false;
+ }
+
+ prev_repeatable = !IsInSet(ch, "^$?*+");
+ }
+ }
+
+ return is_valid;
+}
+
+// Matches a repeated regex atom followed by a valid simple regular
+// expression. The regex atom is defined as c if escaped is false,
+// or \c otherwise. repeat is the repetition meta character (?, *,
+// or +). The behavior is undefined if str contains too many
+// characters to be indexable by size_t, in which case the test will
+// probably time out anyway. We are fine with this limitation as
+// std::string has it too.
+bool MatchRepetitionAndRegexAtHead(
+ bool escaped, char c, char repeat, const char* regex,
+ const char* str) {
+ const size_t min_count = (repeat == '+') ? 1 : 0;
+ const size_t max_count = (repeat == '?') ? 1 :
+ static_cast<size_t>(-1) - 1;
+ // We cannot call numeric_limits::max() as it conflicts with the
+ // max() macro on Windows.
+
+ for (size_t i = 0; i <= max_count; ++i) {
+ // We know that the atom matches each of the first i characters in str.
+ if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
+ // We have enough matches at the head, and the tail matches too.
+ // Since we only care about *whether* the pattern matches str
+ // (as opposed to *how* it matches), there is no need to find a
+ // greedy match.
+ return true;
+ }
+ if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i]))
+ return false;
+ }
+ return false;
+}
+
+// Returns true iff regex matches a prefix of str. regex must be a
+// valid simple regular expression and not start with "^", or the
+// result is undefined.
+bool MatchRegexAtHead(const char* regex, const char* str) {
+ if (*regex == '\0') // An empty regex matches a prefix of anything.
+ return true;
+
+ // "$" only matches the end of a string. Note that regex being
+ // valid guarantees that there's nothing after "$" in it.
+ if (*regex == '$')
+ return *str == '\0';
+
+ // Is the first thing in regex an escape sequence?
+ const bool escaped = *regex == '\\';
+ if (escaped)
+ ++regex;
+ if (IsRepeat(regex[1])) {
+ // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
+ // here's an indirect recursion. It terminates as the regex gets
+ // shorter in each recursion.
+ return MatchRepetitionAndRegexAtHead(
+ escaped, regex[0], regex[1], regex + 2, str);
+ } else {
+ // regex isn't empty, isn't "$", and doesn't start with a
+ // repetition. We match the first atom of regex with the first
+ // character of str and recurse.
+ return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
+ MatchRegexAtHead(regex + 1, str + 1);
+ }
+}
+
+// Returns true iff regex matches any substring of str. regex must be
+// a valid simple regular expression, or the result is undefined.
+//
+// The algorithm is recursive, but the recursion depth doesn't exceed
+// the regex length, so we won't need to worry about running out of
+// stack space normally. In rare cases the time complexity can be
+// exponential with respect to the regex length + the string length,
+// but usually it's must faster (often close to linear).
+bool MatchRegexAnywhere(const char* regex, const char* str) {
+ if (regex == NULL || str == NULL)
+ return false;
+
+ if (*regex == '^')
+ return MatchRegexAtHead(regex + 1, str);
+
+ // A successful match can be anywhere in str.
+ do {
+ if (MatchRegexAtHead(regex, str))
+ return true;
+ } while (*str++ != '\0');
+ return false;
+}
+
+// Implements the RE class.
+
+RE::~RE() {
+ free(const_cast<char*>(pattern_));
+ free(const_cast<char*>(full_pattern_));
+}
+
+// Returns true iff regular expression re matches the entire str.
+bool RE::FullMatch(const char* str, const RE& re) {
+ return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
+}
+
+// Returns true iff regular expression re matches a substring of str
+// (including str itself).
+bool RE::PartialMatch(const char* str, const RE& re) {
+ return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
+}
+
+// Initializes an RE from its string representation.
+void RE::Init(const char* regex) {
+ pattern_ = full_pattern_ = NULL;
+ if (regex != NULL) {
+ pattern_ = posix::StrDup(regex);
+ }
+
+ is_valid_ = ValidateRegex(regex);
+ if (!is_valid_) {
+ // No need to calculate the full pattern when the regex is invalid.
+ return;
+ }
+
+ const size_t len = strlen(regex);
+ // Reserves enough bytes to hold the regular expression used for a
+ // full match: we need space to prepend a '^', append a '$', and
+ // terminate the string with '\0'.
+ char* buffer = static_cast<char*>(malloc(len + 3));
+ full_pattern_ = buffer;
+
+ if (*regex != '^')
+ *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'.
+
+ // We don't use snprintf or strncpy, as they trigger a warning when
+ // compiled with VC++ 8.0.
+ memcpy(buffer, regex, len);
+ buffer += len;
+
+ if (len == 0 || regex[len - 1] != '$')
+ *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'.
+
+ *buffer = '\0';
+}
+
+#endif // GTEST_USES_POSIX_RE
+
+
+GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
+ : severity_(severity) {
+ const char* const marker =
+ severity == GTEST_INFO ? "[ INFO ]" :
+ severity == GTEST_WARNING ? "[WARNING]" :
+ severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]";
+ GetStream() << ::std::endl << marker << " "
+ << FormatFileLocation(file, line).c_str() << ": ";
+}
+
+// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
+GTestLog::~GTestLog() {
+ GetStream() << ::std::endl;
+ if (severity_ == GTEST_FATAL) {
+ fflush(stderr);
+ posix::Abort();
+ }
+}
+// Disable Microsoft deprecation warnings for POSIX functions called from
+// this class (creat, dup, dup2, and close)
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4996)
+#endif // _MSC_VER
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+
+// Object that captures an output stream (stdout/stderr).
+class CapturedStream {
+ public:
+ // The ctor redirects the stream to a temporary file.
+ CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
+#if GTEST_OS_WINDOWS
+ char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT
+ char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT
+
+ ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
+ const UINT success = ::GetTempFileNameA(temp_dir_path,
+ "gtest_redir",
+ 0, // Generate unique file name.
+ temp_file_path);
+ GTEST_CHECK_(success != 0)
+ << "Unable to create a temporary file in " << temp_dir_path;
+ const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
+ GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
+ << temp_file_path;
+ filename_ = temp_file_path;
+#else
+ // There's no guarantee that a test has write access to the
+ // current directory, so we create the temporary file in the /tmp
+ // directory instead.
+ char name_template[] = "/tmp/captured_stream.XXXXXX";
+ const int captured_fd = mkstemp(name_template);
+ filename_ = name_template;
+#endif // GTEST_OS_WINDOWS
+ fflush(NULL);
+ dup2(captured_fd, fd_);
+ close(captured_fd);
+ }
+
+ ~CapturedStream() {
+ remove(filename_.c_str());
+ }
+
+ String GetCapturedString() {
+ if (uncaptured_fd_ != -1) {
+ // Restores the original stream.
+ fflush(NULL);
+ dup2(uncaptured_fd_, fd_);
+ close(uncaptured_fd_);
+ uncaptured_fd_ = -1;
+ }
+
+ FILE* const file = posix::FOpen(filename_.c_str(), "r");
+ const String content = ReadEntireFile(file);
+ posix::FClose(file);
+ return content;
+ }
+
+ private:
+ // Reads the entire content of a file as a String.
+ static String ReadEntireFile(FILE* file);
+
+ // Returns the size (in bytes) of a file.
+ static size_t GetFileSize(FILE* file);
+
+ const int fd_; // A stream to capture.
+ int uncaptured_fd_;
+ // Name of the temporary file holding the stderr output.
+ ::std::string filename_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
+};
+
+// Returns the size (in bytes) of a file.
+size_t CapturedStream::GetFileSize(FILE* file) {
+ fseek(file, 0, SEEK_END);
+ return static_cast<size_t>(ftell(file));
+}
+
+// Reads the entire content of a file as a string.
+String CapturedStream::ReadEntireFile(FILE* file) {
+ const size_t file_size = GetFileSize(file);
+ char* const buffer = new char[file_size];
+
+ size_t bytes_last_read = 0; // # of bytes read in the last fread()
+ size_t bytes_read = 0; // # of bytes read so far
+
+ fseek(file, 0, SEEK_SET);
+
+ // Keeps reading the file until we cannot read further or the
+ // pre-determined file size is reached.
+ do {
+ bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
+ bytes_read += bytes_last_read;
+ } while (bytes_last_read > 0 && bytes_read < file_size);
+
+ const String content(buffer, bytes_read);
+ delete[] buffer;
+
+ return content;
+}
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif // _MSC_VER
+
+static CapturedStream* g_captured_stderr = NULL;
+static CapturedStream* g_captured_stdout = NULL;
+
+// Starts capturing an output stream (stdout/stderr).
+void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
+ if (*stream != NULL) {
+ GTEST_LOG_(FATAL) << "Only one " << stream_name
+ << " capturer can exist at a time.";
+ }
+ *stream = new CapturedStream(fd);
+}
+
+// Stops capturing the output stream and returns the captured string.
+String GetCapturedStream(CapturedStream** captured_stream) {
+ const String content = (*captured_stream)->GetCapturedString();
+
+ delete *captured_stream;
+ *captured_stream = NULL;
+
+ return content;
+}
+
+// Starts capturing stdout.
+void CaptureStdout() {
+ CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
+}
+
+// Starts capturing stderr.
+void CaptureStderr() {
+ CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
+}
+
+// Stops capturing stdout and returns the captured string.
+String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); }
+
+// Stops capturing stderr and returns the captured string.
+String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); }
+
+#endif // GTEST_HAS_STREAM_REDIRECTION_
+
+#if GTEST_HAS_DEATH_TEST
+
+// A copy of all command line arguments. Set by InitGoogleTest().
+::std::vector<String> g_argvs;
+
+// Returns the command line as a vector of strings.
+const ::std::vector<String>& GetArgvs() { return g_argvs; }
+
+#endif // GTEST_HAS_DEATH_TEST
+
+#if GTEST_OS_WINDOWS_MOBILE
+namespace posix {
+void Abort() {
+ DebugBreak();
+ TerminateProcess(GetCurrentProcess(), 1);
+}
+} // namespace posix
+#endif // GTEST_OS_WINDOWS_MOBILE
+
+// Returns the name of the environment variable corresponding to the
+// given flag. For example, FlagToEnvVar("foo") will return
+// "GTEST_FOO" in the open-source version.
+static String FlagToEnvVar(const char* flag) {
+ const String full_flag =
+ (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();
+
+ Message env_var;
+ for (size_t i = 0; i != full_flag.length(); i++) {
+ env_var << static_cast<char>(toupper(full_flag.c_str()[i]));
+ }
+
+ return env_var.GetString();
+}
+
+// Parses 'str' for a 32-bit signed integer. If successful, writes
+// the result to *value and returns true; otherwise leaves *value
+// unchanged and returns false.
+bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
+ // Parses the environment variable as a decimal integer.
+ char* end = NULL;
+ const long long_value = strtol(str, &end, 10); // NOLINT
+
+ // Has strtol() consumed all characters in the string?
+ if (*end != '\0') {
+ // No - an invalid character was encountered.
+ Message msg;
+ msg << "WARNING: " << src_text
+ << " is expected to be a 32-bit integer, but actually"
+ << " has value \"" << str << "\".\n";
+ printf("%s", msg.GetString().c_str());
+ fflush(stdout);
+ return false;
+ }
+
+ // Is the parsed value in the range of an Int32?
+ const Int32 result = static_cast<Int32>(long_value);
+ if (long_value == LONG_MAX || long_value == LONG_MIN ||
+ // The parsed value overflows as a long. (strtol() returns
+ // LONG_MAX or LONG_MIN when the input overflows.)
+ result != long_value
+ // The parsed value overflows as an Int32.
+ ) {
+ Message msg;
+ msg << "WARNING: " << src_text
+ << " is expected to be a 32-bit integer, but actually"
+ << " has value " << str << ", which overflows.\n";
+ printf("%s", msg.GetString().c_str());
+ fflush(stdout);
+ return false;
+ }
+
+ *value = result;
+ return true;
+}
+
+// Reads and returns the Boolean environment variable corresponding to
+// the given flag; if it's not set, returns default_value.
+//
+// The value is considered true iff it's not "0".
+bool BoolFromGTestEnv(const char* flag, bool default_value) {
+ const String env_var = FlagToEnvVar(flag);
+ const char* const string_value = posix::GetEnv(env_var.c_str());
+ return string_value == NULL ?
+ default_value : strcmp(string_value, "0") != 0;
+}
+
+// Reads and returns a 32-bit integer stored in the environment
+// variable corresponding to the given flag; if it isn't set or
+// doesn't represent a valid 32-bit integer, returns default_value.
+Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
+ const String env_var = FlagToEnvVar(flag);
+ const char* const string_value = posix::GetEnv(env_var.c_str());
+ if (string_value == NULL) {
+ // The environment variable is not set.
+ return default_value;
+ }
+
+ Int32 result = default_value;
+ if (!ParseInt32(Message() << "Environment variable " << env_var,
+ string_value, &result)) {
+ printf("The default value %s is used.\n",
+ (Message() << default_value).GetString().c_str());
+ fflush(stdout);
+ return default_value;
+ }
+
+ return result;
+}
+
+// Reads and returns the string environment variable corresponding to
+// the given flag; if it's not set, returns default_value.
+const char* StringFromGTestEnv(const char* flag, const char* default_value) {
+ const String env_var = FlagToEnvVar(flag);
+ const char* const value = posix::GetEnv(env_var.c_str());
+ return value == NULL ? default_value : value;
+}
+
+} // namespace internal
+} // namespace testing
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// 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: mheule@google.com (Markus Heule)
+//
+// The Google C++ Testing Framework (Google Test)
+
+
+// Indicates that this translation unit is part of Google Test's
+// implementation. It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error. This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION_ 1
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+
+using internal::GetUnitTestImpl;
+
+// Gets the summary of the failure message by omitting the stack trace
+// in it.
+internal::String TestPartResult::ExtractSummary(const char* message) {
+ const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
+ return stack_trace == NULL ? internal::String(message) :
+ internal::String(message, stack_trace - message);
+}
+
+// Prints a TestPartResult object.
+std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
+ return os
+ << result.file_name() << ":" << result.line_number() << ": "
+ << (result.type() == TestPartResult::kSuccess ? "Success" :
+ result.type() == TestPartResult::kFatalFailure ? "Fatal failure" :
+ "Non-fatal failure") << ":\n"
+ << result.message() << std::endl;
+}
+
+// Appends a TestPartResult to the array.
+void TestPartResultArray::Append(const TestPartResult& result) {
+ array_.push_back(result);
+}
+
+// Returns the TestPartResult at the given index (0-based).
+const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
+ if (index < 0 || index >= size()) {
+ printf("\nInvalid index (%d) into TestPartResultArray.\n", index);
+ internal::posix::Abort();
+ }
+
+ return array_[index];
+}
+
+// Returns the number of TestPartResult objects in the array.
+int TestPartResultArray::size() const {
+ return static_cast<int>(array_.size());
+}
+
+namespace internal {
+
+HasNewFatalFailureHelper::HasNewFatalFailureHelper()
+ : has_new_fatal_failure_(false),
+ original_reporter_(GetUnitTestImpl()->
+ GetTestPartResultReporterForCurrentThread()) {
+ GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
+}
+
+HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
+ GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(
+ original_reporter_);
+}
+
+void HasNewFatalFailureHelper::ReportTestPartResult(
+ const TestPartResult& result) {
+ if (result.fatally_failed())
+ has_new_fatal_failure_ = true;
+ original_reporter_->ReportTestPartResult(result);
+}
+
+} // namespace internal
+
+} // namespace testing
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// 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: wan@google.com (Zhanyong Wan)
+
+
+namespace testing {
+namespace internal {
+
+#if GTEST_HAS_TYPED_TEST_P
+
+// Skips to the first non-space char in str. Returns an empty string if str
+// contains only whitespace characters.
+static const char* SkipSpaces(const char* str) {
+ while (isspace(*str))
+ str++;
+ return str;
+}
+
+// Verifies that registered_tests match the test names in
+// defined_test_names_; returns registered_tests if successful, or
+// aborts the program otherwise.
+const char* TypedTestCasePState::VerifyRegisteredTestNames(
+ const char* file, int line, const char* registered_tests) {
+ typedef ::std::set<const char*>::const_iterator DefinedTestIter;
+ registered_ = true;
+
+ // Skip initial whitespace in registered_tests since some
+ // preprocessors prefix stringizied literals with whitespace.
+ registered_tests = SkipSpaces(registered_tests);
+
+ Message errors;
+ ::std::set<String> tests;
+ for (const char* names = registered_tests; names != NULL;
+ names = SkipComma(names)) {
+ const String name = GetPrefixUntilComma(names);
+ if (tests.count(name) != 0) {
+ errors << "Test " << name << " is listed more than once.\n";
+ continue;
+ }
+
+ bool found = false;
+ for (DefinedTestIter it = defined_test_names_.begin();
+ it != defined_test_names_.end();
+ ++it) {
+ if (name == *it) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ tests.insert(name);
+ } else {
+ errors << "No test named " << name
+ << " can be found in this test case.\n";
+ }
+ }
+
+ for (DefinedTestIter it = defined_test_names_.begin();
+ it != defined_test_names_.end();
+ ++it) {
+ if (tests.count(*it) == 0) {
+ errors << "You forgot to list test " << *it << ".\n";
+ }
+ }
+
+ const String& errors_str = errors.GetString();
+ if (errors_str != "") {
+ fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
+ errors_str.c_str());
+ fflush(stderr);
+ posix::Abort();
+ }
+
+ return registered_tests;
+}
+
+#endif // GTEST_HAS_TYPED_TEST_P
+
+} // namespace internal
+} // namespace testing
diff --git a/gtest/fused-src/gtest/gtest.h b/gtest/fused-src/gtest/gtest.h
new file mode 100644
index 0000000..c0a1902
--- /dev/null
+++ b/gtest/fused-src/gtest/gtest.h
@@ -0,0 +1,18007 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// 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: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines the public API for Google Test. It should be
+// included by any test program that uses Google Test.
+//
+// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
+// leave some internal implementation details in this header file.
+// They are clearly marked by comments like this:
+//
+// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+//
+// Such code is NOT meant to be used by a user directly, and is subject
+// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
+// program!
+//
+// Acknowledgment: Google Test borrowed the idea of automatic test
+// registration from Barthelemy Dagenais' (barthelemy@prologique.com)
+// easyUnit framework.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_H_
+
+#include <limits>
+#include <vector>
+
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// 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.
+//
+// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file declares functions and macros used internally by
+// Google Test. They are subject to change without notice.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// 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.
+//
+// Authors: wan@google.com (Zhanyong Wan)
+//
+// Low-level types and utilities for porting Google Test to various
+// platforms. They are subject to change without notice. DO NOT USE
+// THEM IN USER CODE.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
+
+// The user can define the following macros in the build script to
+// control Google Test's behavior. If the user doesn't define a macro
+// in this list, Google Test will define it.
+//
+// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2)
+// is/isn't available.
+// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions
+// are enabled.
+// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string
+// is/isn't available (some systems define
+// ::string, which is different to std::string).
+// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string
+// is/isn't available (some systems define
+// ::wstring, which is different to std::wstring).
+// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that <pthread.h>
+// is/isn't available.
+// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't
+// enabled.
+// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that
+// std::wstring does/doesn't work (Google Test can
+// be used where std::wstring is unavailable).
+// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple
+// is/isn't available.
+// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the
+// compiler supports Microsoft's "Structured
+// Exception Handling".
+// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google
+// Test's own tr1 tuple implementation should be
+// used. Unused when the user sets
+// GTEST_HAS_TR1_TUPLE to 0.
+// GTEST_LINKED_AS_SHARED_LIBRARY
+// - Define to 1 when compiling tests that use
+// Google Test as a shared library (known as
+// DLL on Windows).
+// GTEST_CREATE_SHARED_LIBRARY
+// - Define to 1 when compiling Google Test itself
+// as a shared library.
+
+// This header defines the following utilities:
+//
+// Macros indicating the current platform (defined to 1 if compiled on
+// the given platform; otherwise undefined):
+// GTEST_OS_AIX - IBM AIX
+// GTEST_OS_CYGWIN - Cygwin
+// GTEST_OS_LINUX - Linux
+// GTEST_OS_MAC - Mac OS X
+// GTEST_OS_SOLARIS - Sun Solaris
+// GTEST_OS_SYMBIAN - Symbian
+// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile)
+// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop
+// GTEST_OS_WINDOWS_MINGW - MinGW
+// GTEST_OS_WINDOWS_MOBILE - Windows Mobile
+// GTEST_OS_ZOS - z/OS
+//
+// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the
+// most stable support. Since core members of the Google Test project
+// don't have access to other platforms, support for them may be less
+// stable. If you notice any problems on your platform, please notify
+// googletestframework@googlegroups.com (patches for fixing them are
+// even more welcome!).
+//
+// Note that it is possible that none of the GTEST_OS_* macros are defined.
+//
+// Macros indicating available Google Test features (defined to 1 if
+// the corresponding feature is supported; otherwise undefined):
+// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized
+// tests)
+// GTEST_HAS_DEATH_TEST - death tests
+// GTEST_HAS_PARAM_TEST - value-parameterized tests
+// GTEST_HAS_TYPED_TEST - typed tests
+// GTEST_HAS_TYPED_TEST_P - type-parameterized tests
+// GTEST_USES_POSIX_RE - enhanced POSIX regex is used.
+// GTEST_USES_SIMPLE_RE - our own simple regex is used;
+// the above two are mutually exclusive.
+// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().
+//
+// Macros for basic C++ coding:
+// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
+// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a
+// variable don't have to be used.
+// GTEST_DISALLOW_ASSIGN_ - disables operator=.
+// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=.
+// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used.
+//
+// Synchronization:
+// Mutex, MutexLock, ThreadLocal, GetThreadCount()
+// - synchronization primitives.
+// GTEST_IS_THREADSAFE - defined to 1 to indicate that the above
+// synchronization primitives have real implementations
+// and Google Test is thread-safe; or 0 otherwise.
+//
+// Template meta programming:
+// is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only.
+//
+// Smart pointers:
+// scoped_ptr - as in TR2.
+//
+// Regular expressions:
+// RE - a simple regular expression class using the POSIX
+// Extended Regular Expression syntax. Not available on
+// Windows.
+//
+// Logging:
+// GTEST_LOG_() - logs messages at the specified severity level.
+// LogToStderr() - directs all log messages to stderr.
+// FlushInfoLog() - flushes informational log messages.
+//
+// Stdout and stderr capturing:
+// CaptureStdout() - starts capturing stdout.
+// GetCapturedStdout() - stops capturing stdout and returns the captured
+// string.
+// CaptureStderr() - starts capturing stderr.
+// GetCapturedStderr() - stops capturing stderr and returns the captured
+// string.
+//
+// Integer types:
+// TypeWithSize - maps an integer to a int type.
+// Int32, UInt32, Int64, UInt64, TimeInMillis
+// - integers of known sizes.
+// BiggestInt - the biggest signed integer type.
+//
+// Command-line utilities:
+// GTEST_FLAG() - references a flag.
+// GTEST_DECLARE_*() - declares a flag.
+// GTEST_DEFINE_*() - defines a flag.
+// GetArgvs() - returns the command line as a vector of strings.
+//
+// Environment variable utilities:
+// GetEnv() - gets the value of an environment variable.
+// BoolFromGTestEnv() - parses a bool environment variable.
+// Int32FromGTestEnv() - parses an Int32 environment variable.
+// StringFromGTestEnv() - parses a string environment variable.
+
+#include <stddef.h> // For ptrdiff_t
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#ifndef _WIN32_WCE
+#include <sys/stat.h>
+#endif // !_WIN32_WCE
+
+#include <iostream> // NOLINT
+#include <sstream> // NOLINT
+#include <string> // NOLINT
+
+#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
+#define GTEST_FLAG_PREFIX_ "gtest_"
+#define GTEST_FLAG_PREFIX_DASH_ "gtest-"
+#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_"
+#define GTEST_NAME_ "Google Test"
+#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/"
+
+// Determines the version of gcc that is used to compile this.
+#ifdef __GNUC__
+// 40302 means version 4.3.2.
+#define GTEST_GCC_VER_ \
+ (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)
+#endif // __GNUC__
+
+// Determines the platform on which Google Test is compiled.
+#ifdef __CYGWIN__
+#define GTEST_OS_CYGWIN 1
+#elif defined __SYMBIAN32__
+#define GTEST_OS_SYMBIAN 1
+#elif defined _WIN32
+#define GTEST_OS_WINDOWS 1
+#ifdef _WIN32_WCE
+#define GTEST_OS_WINDOWS_MOBILE 1
+#elif defined(__MINGW__) || defined(__MINGW32__)
+#define GTEST_OS_WINDOWS_MINGW 1
+#else
+#define GTEST_OS_WINDOWS_DESKTOP 1
+#endif // _WIN32_WCE
+#elif defined __APPLE__
+#define GTEST_OS_MAC 1
+#elif defined __linux__
+#define GTEST_OS_LINUX 1
+#elif defined __MVS__
+#define GTEST_OS_ZOS 1
+#elif defined(__sun) && defined(__SVR4)
+#define GTEST_OS_SOLARIS 1
+#elif defined(_AIX)
+#define GTEST_OS_AIX 1
+#endif // __CYGWIN__
+
+#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_SYMBIAN || \
+ GTEST_OS_SOLARIS || GTEST_OS_AIX
+
+// On some platforms, <regex.h> needs someone to define size_t, and
+// won't compile otherwise. We can #include it here as we already
+// included <stdlib.h>, which is guaranteed to define size_t through
+// <stddef.h>.
+#include <regex.h> // NOLINT
+#include <strings.h> // NOLINT
+#include <sys/types.h> // NOLINT
+#include <time.h> // NOLINT
+#include <unistd.h> // NOLINT
+
+#define GTEST_USES_POSIX_RE 1
+
+#elif GTEST_OS_WINDOWS
+
+#if !GTEST_OS_WINDOWS_MOBILE
+#include <direct.h> // NOLINT
+#include <io.h> // NOLINT
+#endif
+
+// <regex.h> is not available on Windows. Use our own simple regex
+// implementation instead.
+#define GTEST_USES_SIMPLE_RE 1
+
+#else
+
+// <regex.h> may not be available on this platform. Use our own
+// simple regex implementation instead.
+#define GTEST_USES_SIMPLE_RE 1
+
+#endif // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC ||
+ // GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS || GTEST_OS_AIX
+
+#ifndef GTEST_HAS_EXCEPTIONS
+// The user didn't tell us whether exceptions are enabled, so we need
+// to figure it out.
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS
+// macro to enable exceptions, so we'll do the same.
+// Assumes that exceptions are enabled by default.
+#ifndef _HAS_EXCEPTIONS
+#define _HAS_EXCEPTIONS 1
+#endif // _HAS_EXCEPTIONS
+#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
+#elif defined(__GNUC__) && __EXCEPTIONS
+// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled.
+#define GTEST_HAS_EXCEPTIONS 1
+#elif defined(__SUNPRO_CC)
+// Sun Pro CC supports exceptions. However, there is no compile-time way of
+// detecting whether they are enabled or not. Therefore, we assume that
+// they are enabled unless the user tells us otherwise.
+#define GTEST_HAS_EXCEPTIONS 1
+#elif defined(__IBMCPP__) && __EXCEPTIONS
+// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled.
+#define GTEST_HAS_EXCEPTIONS 1
+#else
+// For other compilers, we assume exceptions are disabled to be
+// conservative.
+#define GTEST_HAS_EXCEPTIONS 0
+#endif // defined(_MSC_VER) || defined(__BORLANDC__)
+#endif // GTEST_HAS_EXCEPTIONS
+
+#if !defined(GTEST_HAS_STD_STRING)
+// Even though we don't use this macro any longer, we keep it in case
+// some clients still depend on it.
+#define GTEST_HAS_STD_STRING 1
+#elif !GTEST_HAS_STD_STRING
+// The user told us that ::std::string isn't available.
+#error "Google Test cannot be used where ::std::string isn't available."
+#endif // !defined(GTEST_HAS_STD_STRING)
+
+#ifndef GTEST_HAS_GLOBAL_STRING
+// The user didn't tell us whether ::string is available, so we need
+// to figure it out.
+
+#define GTEST_HAS_GLOBAL_STRING 0
+
+#endif // GTEST_HAS_GLOBAL_STRING
+
+#ifndef GTEST_HAS_STD_WSTRING
+// The user didn't tell us whether ::std::wstring is available, so we need
+// to figure it out.
+// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring
+// is available.
+
+// Cygwin 1.5 and below doesn't support ::std::wstring.
+// Cygwin 1.7 might add wstring support; this should be updated when clear.
+// Solaris' libc++ doesn't support it either.
+#define GTEST_HAS_STD_WSTRING (!(GTEST_OS_CYGWIN || GTEST_OS_SOLARIS))
+
+#endif // GTEST_HAS_STD_WSTRING
+
+#ifndef GTEST_HAS_GLOBAL_WSTRING
+// The user didn't tell us whether ::wstring is available, so we need
+// to figure it out.
+#define GTEST_HAS_GLOBAL_WSTRING \
+ (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING)
+#endif // GTEST_HAS_GLOBAL_WSTRING
+
+// Determines whether RTTI is available.
+#ifndef GTEST_HAS_RTTI
+// The user didn't tell us whether RTTI is enabled, so we need to
+// figure it out.
+
+#ifdef _MSC_VER
+
+#ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled.
+#define GTEST_HAS_RTTI 1
+#else
+#define GTEST_HAS_RTTI 0
+#endif
+
+// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled.
+#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302)
+
+#ifdef __GXX_RTTI
+#define GTEST_HAS_RTTI 1
+#else
+#define GTEST_HAS_RTTI 0
+#endif // __GXX_RTTI
+
+// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if
+// both the typeid and dynamic_cast features are present.
+#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)
+
+#ifdef __RTTI_ALL__
+#define GTEST_HAS_RTTI 1
+#else
+#define GTEST_HAS_RTTI 0
+#endif
+
+#else
+
+// For all other compilers, we assume RTTI is enabled.
+#define GTEST_HAS_RTTI 1
+
+#endif // _MSC_VER
+
+#endif // GTEST_HAS_RTTI
+
+// It's this header's responsibility to #include <typeinfo> when RTTI
+// is enabled.
+#if GTEST_HAS_RTTI
+#include <typeinfo>
+#endif
+
+// Determines whether Google Test can use the pthreads library.
+#ifndef GTEST_HAS_PTHREAD
+// The user didn't tell us explicitly, so we assume pthreads support is
+// available on Linux and Mac.
+//
+// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
+// to your compiler flags.
+#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC)
+#endif // GTEST_HAS_PTHREAD
+
+// Determines whether Google Test can use tr1/tuple. You can define
+// this macro to 0 to prevent Google Test from using tuple (any
+// feature depending on tuple with be disabled in this mode).
+#ifndef GTEST_HAS_TR1_TUPLE
+// The user didn't tell us not to do it, so we assume it's OK.
+#define GTEST_HAS_TR1_TUPLE 1
+#endif // GTEST_HAS_TR1_TUPLE
+
+// Determines whether Google Test's own tr1 tuple implementation
+// should be used.
+#ifndef GTEST_USE_OWN_TR1_TUPLE
+// The user didn't tell us, so we need to figure it out.
+
+// We use our own TR1 tuple if we aren't sure the user has an
+// implementation of it already. At this time, GCC 4.0.0+ and MSVC
+// 2010 are the only mainstream compilers that come with a TR1 tuple
+// implementation. NVIDIA's CUDA NVCC compiler pretends to be GCC by
+// defining __GNUC__ and friends, but cannot compile GCC's tuple
+// implementation. MSVC 2008 (9.0) provides TR1 tuple in a 323 MB
+// Feature Pack download, which we cannot assume the user has.
+#if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \
+ || _MSC_VER >= 1600
+#define GTEST_USE_OWN_TR1_TUPLE 0
+#else
+#define GTEST_USE_OWN_TR1_TUPLE 1
+#endif
+
+#endif // GTEST_USE_OWN_TR1_TUPLE
+
+// To avoid conditional compilation everywhere, we make it
+// gtest-port.h's responsibility to #include the header implementing
+// tr1/tuple.
+#if GTEST_HAS_TR1_TUPLE
+
+#if GTEST_USE_OWN_TR1_TUPLE
+// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
+
+// Copyright 2009 Google Inc.
+// All Rights Reserved.
+//
+// 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: wan@google.com (Zhanyong Wan)
+
+// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+
+#include <utility> // For ::std::pair.
+
+// The compiler used in Symbian has a bug that prevents us from declaring the
+// tuple template as a friend (it complains that tuple is redefined). This
+// hack bypasses the bug by declaring the members that should otherwise be
+// private as public.
+// Sun Studio versions < 12 also have the above bug.
+#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
+#else
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
+ template <GTEST_10_TYPENAMES_(U)> friend class tuple; \
+ private:
+#endif
+
+// GTEST_n_TUPLE_(T) is the type of an n-tuple.
+#define GTEST_0_TUPLE_(T) tuple<>
+#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
+ void, void, void>
+#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \
+ void, void, void>
+#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \
+ void, void, void>
+#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \
+ void, void, void>
+#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \
+ void, void, void>
+#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \
+ void, void, void>
+#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+ void, void, void>
+#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+ T##7, void, void>
+#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+ T##7, T##8, void>
+#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+ T##7, T##8, T##9>
+
+// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
+#define GTEST_0_TYPENAMES_(T)
+#define GTEST_1_TYPENAMES_(T) typename T##0
+#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1
+#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2
+#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+ typename T##3
+#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+ typename T##3, typename T##4
+#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+ typename T##3, typename T##4, typename T##5
+#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+ typename T##3, typename T##4, typename T##5, typename T##6
+#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+ typename T##3, typename T##4, typename T##5, typename T##6, typename T##7
+#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+ typename T##3, typename T##4, typename T##5, typename T##6, \
+ typename T##7, typename T##8
+#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+ typename T##3, typename T##4, typename T##5, typename T##6, \
+ typename T##7, typename T##8, typename T##9
+
+// In theory, defining stuff in the ::std namespace is undefined
+// behavior. We can do this as we are playing the role of a standard
+// library vendor.
+namespace std {
+namespace tr1 {
+
+template <typename T0 = void, typename T1 = void, typename T2 = void,
+ typename T3 = void, typename T4 = void, typename T5 = void,
+ typename T6 = void, typename T7 = void, typename T8 = void,
+ typename T9 = void>
+class tuple;
+
+// Anything in namespace gtest_internal is Google Test's INTERNAL
+// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
+namespace gtest_internal {
+
+// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
+template <typename T>
+struct ByRef { typedef const T& type; }; // NOLINT
+template <typename T>
+struct ByRef<T&> { typedef T& type; }; // NOLINT
+
+// A handy wrapper for ByRef.
+#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
+
+// AddRef<T>::type is T if T is a reference; otherwise it's T&. This
+// is the same as tr1::add_reference<T>::type.
+template <typename T>
+struct AddRef { typedef T& type; }; // NOLINT
+template <typename T>
+struct AddRef<T&> { typedef T& type; }; // NOLINT
+
+// A handy wrapper for AddRef.
+#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
+
+// A helper for implementing get<k>().
+template <int k> class Get;
+
+// A helper for implementing tuple_element<k, T>. kIndexValid is true
+// iff k < the number of fields in tuple type T.
+template <bool kIndexValid, int kIndex, class Tuple>
+struct TupleElement;
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; };
+
+} // namespace gtest_internal
+
+template <>
+class tuple<> {
+ public:
+ tuple() {}
+ tuple(const tuple& /* t */) {}
+ tuple& operator=(const tuple& /* t */) { return *this; }
+};
+
+template <GTEST_1_TYPENAMES_(T)>
+class GTEST_1_TUPLE_(T) {
+ public:
+ template <int k> friend class gtest_internal::Get;
+
+ tuple() : f0_() {}
+
+ explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}
+
+ tuple(const tuple& t) : f0_(t.f0_) {}
+
+ template <GTEST_1_TYPENAMES_(U)>
+ tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {}
+
+ tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+ template <GTEST_1_TYPENAMES_(U)>
+ tuple& operator=(const GTEST_1_TUPLE_(U)& t) {
+ return CopyFrom(t);
+ }
+
+ GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+ template <GTEST_1_TYPENAMES_(U)>
+ tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {
+ f0_ = t.f0_;
+ return *this;
+ }
+
+ T0 f0_;
+};
+
+template <GTEST_2_TYPENAMES_(T)>
+class GTEST_2_TUPLE_(T) {
+ public:
+ template <int k> friend class gtest_internal::Get;
+
+ tuple() : f0_(), f1_() {}
+
+ explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),
+ f1_(f1) {}
+
+ tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {}
+
+ template <GTEST_2_TYPENAMES_(U)>
+ tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {}
+ template <typename U0, typename U1>
+ tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
+
+ tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+ template <GTEST_2_TYPENAMES_(U)>
+ tuple& operator=(const GTEST_2_TUPLE_(U)& t) {
+ return CopyFrom(t);
+ }
+ template <typename U0, typename U1>
+ tuple& operator=(const ::std::pair<U0, U1>& p) {
+ f0_ = p.first;
+ f1_ = p.second;
+ return *this;
+ }
+
+ GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+ template <GTEST_2_TYPENAMES_(U)>
+ tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {
+ f0_ = t.f0_;
+ f1_ = t.f1_;
+ return *this;
+ }
+
+ T0 f0_;
+ T1 f1_;
+};
+
+template <GTEST_3_TYPENAMES_(T)>
+class GTEST_3_TUPLE_(T) {
+ public:
+ template <int k> friend class gtest_internal::Get;
+
+ tuple() : f0_(), f1_(), f2_() {}
+
+ explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+ GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}
+
+ tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
+
+ template <GTEST_3_TYPENAMES_(U)>
+ tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
+
+ tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+ template <GTEST_3_TYPENAMES_(U)>
+ tuple& operator=(const GTEST_3_TUPLE_(U)& t) {
+ return CopyFrom(t);
+ }
+
+ GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+ template <GTEST_3_TYPENAMES_(U)>
+ tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {
+ f0_ = t.f0_;
+ f1_ = t.f1_;
+ f2_ = t.f2_;
+ return *this;
+ }
+
+ T0 f0_;
+ T1 f1_;
+ T2 f2_;
+};
+
+template <GTEST_4_TYPENAMES_(T)>
+class GTEST_4_TUPLE_(T) {
+ public:
+ template <int k> friend class gtest_internal::Get;
+
+ tuple() : f0_(), f1_(), f2_(), f3_() {}
+
+ explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+ GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),
+ f3_(f3) {}
+
+ tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {}
+
+ template <GTEST_4_TYPENAMES_(U)>
+ tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+ f3_(t.f3_) {}
+
+ tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+ template <GTEST_4_TYPENAMES_(U)>
+ tuple& operator=(const GTEST_4_TUPLE_(U)& t) {
+ return CopyFrom(t);
+ }
+
+ GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+ template <GTEST_4_TYPENAMES_(U)>
+ tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {
+ f0_ = t.f0_;
+ f1_ = t.f1_;
+ f2_ = t.f2_;
+ f3_ = t.f3_;
+ return *this;
+ }
+
+ T0 f0_;
+ T1 f1_;
+ T2 f2_;
+ T3 f3_;
+};
+
+template <GTEST_5_TYPENAMES_(T)>
+class GTEST_5_TUPLE_(T) {
+ public:
+ template <int k> friend class gtest_internal::Get;
+
+ tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {}
+
+ explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+ GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,
+ GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {}
+
+ tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+ f4_(t.f4_) {}
+
+ template <GTEST_5_TYPENAMES_(U)>
+ tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+ f3_(t.f3_), f4_(t.f4_) {}
+
+ tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+ template <GTEST_5_TYPENAMES_(U)>
+ tuple& operator=(const GTEST_5_TUPLE_(U)& t) {
+ return CopyFrom(t);
+ }
+
+ GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+ template <GTEST_5_TYPENAMES_(U)>
+ tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {
+ f0_ = t.f0_;
+ f1_ = t.f1_;
+ f2_ = t.f2_;
+ f3_ = t.f3_;
+ f4_ = t.f4_;
+ return *this;
+ }
+
+ T0 f0_;
+ T1 f1_;
+ T2 f2_;
+ T3 f3_;
+ T4 f4_;
+};
+
+template <GTEST_6_TYPENAMES_(T)>
+class GTEST_6_TUPLE_(T) {
+ public:
+ template <int k> friend class gtest_internal::Get;
+
+ tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {}
+
+ explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+ GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+ GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+ f5_(f5) {}
+
+ tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+ f4_(t.f4_), f5_(t.f5_) {}
+
+ template <GTEST_6_TYPENAMES_(U)>
+ tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+ f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {}
+
+ tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+ template <GTEST_6_TYPENAMES_(U)>
+ tuple& operator=(const GTEST_6_TUPLE_(U)& t) {
+ return CopyFrom(t);
+ }
+
+ GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+ template <GTEST_6_TYPENAMES_(U)>
+ tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {
+ f0_ = t.f0_;
+ f1_ = t.f1_;
+ f2_ = t.f2_;
+ f3_ = t.f3_;
+ f4_ = t.f4_;
+ f5_ = t.f5_;
+ return *this;
+ }
+
+ T0 f0_;
+ T1 f1_;
+ T2 f2_;
+ T3 f3_;
+ T4 f4_;
+ T5 f5_;
+};
+
+template <GTEST_7_TYPENAMES_(T)>
+class GTEST_7_TUPLE_(T) {
+ public:
+ template <int k> friend class gtest_internal::Get;
+
+ tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {}
+
+ explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+ GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+ GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2),
+ f3_(f3), f4_(f4), f5_(f5), f6_(f6) {}
+
+ tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+ f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
+
+ template <GTEST_7_TYPENAMES_(U)>
+ tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+ f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
+
+ tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+ template <GTEST_7_TYPENAMES_(U)>
+ tuple& operator=(const GTEST_7_TUPLE_(U)& t) {
+ return CopyFrom(t);
+ }
+
+ GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+ template <GTEST_7_TYPENAMES_(U)>
+ tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {
+ f0_ = t.f0_;
+ f1_ = t.f1_;
+ f2_ = t.f2_;
+ f3_ = t.f3_;
+ f4_ = t.f4_;
+ f5_ = t.f5_;
+ f6_ = t.f6_;
+ return *this;
+ }
+
+ T0 f0_;
+ T1 f1_;
+ T2 f2_;
+ T3 f3_;
+ T4 f4_;
+ T5 f5_;
+ T6 f6_;
+};
+
+template <GTEST_8_TYPENAMES_(T)>
+class GTEST_8_TUPLE_(T) {
+ public:
+ template <int k> friend class gtest_internal::Get;
+
+ tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {}
+
+ explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+ GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+ GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6,
+ GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+ f5_(f5), f6_(f6), f7_(f7) {}
+
+ tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+ f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
+
+ template <GTEST_8_TYPENAMES_(U)>
+ tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+ f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
+
+ tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+ template <GTEST_8_TYPENAMES_(U)>
+ tuple& operator=(const GTEST_8_TUPLE_(U)& t) {
+ return CopyFrom(t);
+ }
+
+ GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+ template <GTEST_8_TYPENAMES_(U)>
+ tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {
+ f0_ = t.f0_;
+ f1_ = t.f1_;
+ f2_ = t.f2_;
+ f3_ = t.f3_;
+ f4_ = t.f4_;
+ f5_ = t.f5_;
+ f6_ = t.f6_;
+ f7_ = t.f7_;
+ return *this;
+ }
+
+ T0 f0_;
+ T1 f1_;
+ T2 f2_;
+ T3 f3_;
+ T4 f4_;
+ T5 f5_;
+ T6 f6_;
+ T7 f7_;
+};
+
+template <GTEST_9_TYPENAMES_(T)>
+class GTEST_9_TUPLE_(T) {
+ public:
+ template <int k> friend class gtest_internal::Get;
+
+ tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {}
+
+ explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+ GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+ GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
+ GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+ f5_(f5), f6_(f6), f7_(f7), f8_(f8) {}
+
+ tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+ f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
+
+ template <GTEST_9_TYPENAMES_(U)>
+ tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+ f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
+
+ tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+ template <GTEST_9_TYPENAMES_(U)>
+ tuple& operator=(const GTEST_9_TUPLE_(U)& t) {
+ return CopyFrom(t);
+ }
+
+ GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+ template <GTEST_9_TYPENAMES_(U)>
+ tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {
+ f0_ = t.f0_;
+ f1_ = t.f1_;
+ f2_ = t.f2_;
+ f3_ = t.f3_;
+ f4_ = t.f4_;
+ f5_ = t.f5_;
+ f6_ = t.f6_;
+ f7_ = t.f7_;
+ f8_ = t.f8_;
+ return *this;
+ }
+
+ T0 f0_;
+ T1 f1_;
+ T2 f2_;
+ T3 f3_;
+ T4 f4_;
+ T5 f5_;
+ T6 f6_;
+ T7 f7_;
+ T8 f8_;
+};
+
+template <GTEST_10_TYPENAMES_(T)>
+class tuple {
+ public:
+ template <int k> friend class gtest_internal::Get;
+
+ tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(),
+ f9_() {}
+
+ explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+ GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+ GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
+ GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2),
+ f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {}
+
+ tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+ f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {}
+
+ template <GTEST_10_TYPENAMES_(U)>
+ tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+ f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_),
+ f9_(t.f9_) {}
+
+ tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+ template <GTEST_10_TYPENAMES_(U)>
+ tuple& operator=(const GTEST_10_TUPLE_(U)& t) {
+ return CopyFrom(t);
+ }
+
+ GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+ template <GTEST_10_TYPENAMES_(U)>
+ tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {
+ f0_ = t.f0_;
+ f1_ = t.f1_;
+ f2_ = t.f2_;
+ f3_ = t.f3_;
+ f4_ = t.f4_;
+ f5_ = t.f5_;
+ f6_ = t.f6_;
+ f7_ = t.f7_;
+ f8_ = t.f8_;
+ f9_ = t.f9_;
+ return *this;
+ }
+
+ T0 f0_;
+ T1 f1_;
+ T2 f2_;
+ T3 f3_;
+ T4 f4_;
+ T5 f5_;
+ T6 f6_;
+ T7 f7_;
+ T8 f8_;
+ T9 f9_;
+};
+
+// 6.1.3.2 Tuple creation functions.
+
+// Known limitations: we don't support passing an
+// std::tr1::reference_wrapper<T> to make_tuple(). And we don't
+// implement tie().
+
+inline tuple<> make_tuple() { return tuple<>(); }
+
+template <GTEST_1_TYPENAMES_(T)>
+inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) {
+ return GTEST_1_TUPLE_(T)(f0);
+}
+
+template <GTEST_2_TYPENAMES_(T)>
+inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) {
+ return GTEST_2_TUPLE_(T)(f0, f1);
+}
+
+template <GTEST_3_TYPENAMES_(T)>
+inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) {
+ return GTEST_3_TUPLE_(T)(f0, f1, f2);
+}
+
+template <GTEST_4_TYPENAMES_(T)>
+inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+ const T3& f3) {
+ return GTEST_4_TUPLE_(T)(f0, f1, f2, f3);
+}
+
+template <GTEST_5_TYPENAMES_(T)>
+inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+ const T3& f3, const T4& f4) {
+ return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4);
+}
+
+template <GTEST_6_TYPENAMES_(T)>
+inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+ const T3& f3, const T4& f4, const T5& f5) {
+ return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5);
+}
+
+template <GTEST_7_TYPENAMES_(T)>
+inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+ const T3& f3, const T4& f4, const T5& f5, const T6& f6) {
+ return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6);
+}
+
+template <GTEST_8_TYPENAMES_(T)>
+inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+ const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) {
+ return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7);
+}
+
+template <GTEST_9_TYPENAMES_(T)>
+inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+ const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
+ const T8& f8) {
+ return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8);
+}
+
+template <GTEST_10_TYPENAMES_(T)>
+inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+ const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
+ const T8& f8, const T9& f9) {
+ return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9);
+}
+
+// 6.1.3.3 Tuple helper classes.
+
+template <typename Tuple> struct tuple_size;
+
+template <GTEST_0_TYPENAMES_(T)>
+struct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; };
+
+template <GTEST_1_TYPENAMES_(T)>
+struct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; };
+
+template <GTEST_2_TYPENAMES_(T)>
+struct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; };
+
+template <GTEST_3_TYPENAMES_(T)>
+struct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; };
+
+template <GTEST_4_TYPENAMES_(T)>
+struct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; };
+
+template <GTEST_5_TYPENAMES_(T)>
+struct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; };
+
+template <GTEST_6_TYPENAMES_(T)>
+struct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; };
+
+template <GTEST_7_TYPENAMES_(T)>
+struct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; };
+
+template <GTEST_8_TYPENAMES_(T)>
+struct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; };
+
+template <GTEST_9_TYPENAMES_(T)>
+struct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; };
+
+template <int k, class Tuple>
+struct tuple_element {
+ typedef typename gtest_internal::TupleElement<
+ k < (tuple_size<Tuple>::value), k, Tuple>::type type;
+};
+
+#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
+
+// 6.1.3.4 Element access.
+
+namespace gtest_internal {
+
+template <>
+class Get<0> {
+ public:
+ template <class Tuple>
+ static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
+ Field(Tuple& t) { return t.f0_; } // NOLINT
+
+ template <class Tuple>
+ static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
+ ConstField(const Tuple& t) { return t.f0_; }
+};
+
+template <>
+class Get<1> {
+ public:
+ template <class Tuple>
+ static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
+ Field(Tuple& t) { return t.f1_; } // NOLINT
+
+ template <class Tuple>
+ static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
+ ConstField(const Tuple& t) { return t.f1_; }
+};
+
+template <>
+class Get<2> {
+ public:
+ template <class Tuple>
+ static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
+ Field(Tuple& t) { return t.f2_; } // NOLINT
+
+ template <class Tuple>
+ static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
+ ConstField(const Tuple& t) { return t.f2_; }
+};
+
+template <>
+class Get<3> {
+ public:
+ template <class Tuple>
+ static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
+ Field(Tuple& t) { return t.f3_; } // NOLINT
+
+ template <class Tuple>
+ static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
+ ConstField(const Tuple& t) { return t.f3_; }
+};
+
+template <>
+class Get<4> {
+ public:
+ template <class Tuple>
+ static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
+ Field(Tuple& t) { return t.f4_; } // NOLINT
+
+ template <class Tuple>
+ static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
+ ConstField(const Tuple& t) { return t.f4_; }
+};
+
+template <>
+class Get<5> {
+ public:
+ template <class Tuple>
+ static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
+ Field(Tuple& t) { return t.f5_; } // NOLINT
+
+ template <class Tuple>
+ static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
+ ConstField(const Tuple& t) { return t.f5_; }
+};
+
+template <>
+class Get<6> {
+ public:
+ template <class Tuple>
+ static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
+ Field(Tuple& t) { return t.f6_; } // NOLINT
+
+ template <class Tuple>
+ static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
+ ConstField(const Tuple& t) { return t.f6_; }
+};
+
+template <>
+class Get<7> {
+ public:
+ template <class Tuple>
+ static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
+ Field(Tuple& t) { return t.f7_; } // NOLINT
+
+ template <class Tuple>
+ static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
+ ConstField(const Tuple& t) { return t.f7_; }
+};
+
+template <>
+class Get<8> {
+ public:
+ template <class Tuple>
+ static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
+ Field(Tuple& t) { return t.f8_; } // NOLINT
+
+ template <class Tuple>
+ static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
+ ConstField(const Tuple& t) { return t.f8_; }
+};
+
+template <>
+class Get<9> {
+ public:
+ template <class Tuple>
+ static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
+ Field(Tuple& t) { return t.f9_; } // NOLINT
+
+ template <class Tuple>
+ static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
+ ConstField(const Tuple& t) { return t.f9_; }
+};
+
+} // namespace gtest_internal
+
+template <int k, GTEST_10_TYPENAMES_(T)>
+GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
+get(GTEST_10_TUPLE_(T)& t) {
+ return gtest_internal::Get<k>::Field(t);
+}
+
+template <int k, GTEST_10_TYPENAMES_(T)>
+GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
+get(const GTEST_10_TUPLE_(T)& t) {
+ return gtest_internal::Get<k>::ConstField(t);
+}
+
+// 6.1.3.5 Relational operators
+
+// We only implement == and !=, as we don't have a need for the rest yet.
+
+namespace gtest_internal {
+
+// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
+// first k fields of t1 equals the first k fields of t2.
+// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
+// k1 != k2.
+template <int kSize1, int kSize2>
+struct SameSizeTuplePrefixComparator;
+
+template <>
+struct SameSizeTuplePrefixComparator<0, 0> {
+ template <class Tuple1, class Tuple2>
+ static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
+ return true;
+ }
+};
+
+template <int k>
+struct SameSizeTuplePrefixComparator<k, k> {
+ template <class Tuple1, class Tuple2>
+ static bool Eq(const Tuple1& t1, const Tuple2& t2) {
+ return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
+ ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
+ }
+};
+
+} // namespace gtest_internal
+
+template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
+inline bool operator==(const GTEST_10_TUPLE_(T)& t,
+ const GTEST_10_TUPLE_(U)& u) {
+ return gtest_internal::SameSizeTuplePrefixComparator<
+ tuple_size<GTEST_10_TUPLE_(T)>::value,
+ tuple_size<GTEST_10_TUPLE_(U)>::value>::Eq(t, u);
+}
+
+template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
+inline bool operator!=(const GTEST_10_TUPLE_(T)& t,
+ const GTEST_10_TUPLE_(U)& u) { return !(t == u); }
+
+// 6.1.4 Pairs.
+// Unimplemented.
+
+} // namespace tr1
+} // namespace std
+
+#undef GTEST_0_TUPLE_
+#undef GTEST_1_TUPLE_
+#undef GTEST_2_TUPLE_
+#undef GTEST_3_TUPLE_
+#undef GTEST_4_TUPLE_
+#undef GTEST_5_TUPLE_
+#undef GTEST_6_TUPLE_
+#undef GTEST_7_TUPLE_
+#undef GTEST_8_TUPLE_
+#undef GTEST_9_TUPLE_
+#undef GTEST_10_TUPLE_
+
+#undef GTEST_0_TYPENAMES_
+#undef GTEST_1_TYPENAMES_
+#undef GTEST_2_TYPENAMES_
+#undef GTEST_3_TYPENAMES_
+#undef GTEST_4_TYPENAMES_
+#undef GTEST_5_TYPENAMES_
+#undef GTEST_6_TYPENAMES_
+#undef GTEST_7_TYPENAMES_
+#undef GTEST_8_TYPENAMES_
+#undef GTEST_9_TYPENAMES_
+#undef GTEST_10_TYPENAMES_
+
+#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
+#undef GTEST_BY_REF_
+#undef GTEST_ADD_REF_
+#undef GTEST_TUPLE_ELEMENT_
+
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+#elif GTEST_OS_SYMBIAN
+
+// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to
+// use STLport's tuple implementation, which unfortunately doesn't
+// work as the copy of STLport distributed with Symbian is incomplete.
+// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to
+// use its own tuple implementation.
+#ifdef BOOST_HAS_TR1_TUPLE
+#undef BOOST_HAS_TR1_TUPLE
+#endif // BOOST_HAS_TR1_TUPLE
+
+// This prevents <boost/tr1/detail/config.hpp>, which defines
+// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>.
+#define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
+#include <tuple>
+
+#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
+// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does
+// not conform to the TR1 spec, which requires the header to be <tuple>.
+
+#if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
+// Until version 4.3.2, gcc has a bug that causes <tr1/functional>,
+// which is #included by <tr1/tuple>, to not compile when RTTI is
+// disabled. _TR1_FUNCTIONAL is the header guard for
+// <tr1/functional>. Hence the following #define is a hack to prevent
+// <tr1/functional> from being included.
+#define _TR1_FUNCTIONAL 1
+#include <tr1/tuple>
+#undef _TR1_FUNCTIONAL // Allows the user to #include
+ // <tr1/functional> if he chooses to.
+#else
+#include <tr1/tuple> // NOLINT
+#endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
+
+#else
+// If the compiler is not GCC 4.0+, we assume the user is using a
+// spec-conforming TR1 implementation.
+#include <tuple> // NOLINT
+#endif // GTEST_USE_OWN_TR1_TUPLE
+
+#endif // GTEST_HAS_TR1_TUPLE
+
+// Determines whether clone(2) is supported.
+// Usually it will only be available on Linux, excluding
+// Linux on the Itanium architecture.
+// Also see http://linux.die.net/man/2/clone.
+#ifndef GTEST_HAS_CLONE
+// The user didn't tell us, so we need to figure it out.
+
+#if GTEST_OS_LINUX && !defined(__ia64__)
+#define GTEST_HAS_CLONE 1
+#else
+#define GTEST_HAS_CLONE 0
+#endif // GTEST_OS_LINUX && !defined(__ia64__)
+
+#endif // GTEST_HAS_CLONE
+
+// Determines whether to support stream redirection. This is used to test
+// output correctness and to implement death tests.
+#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN
+#define GTEST_HAS_STREAM_REDIRECTION_ 1
+#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN
+
+// Determines whether to support death tests.
+// Google Test does not support death tests for VC 7.1 and earlier as
+// abort() in a VC 7.1 application compiled as GUI in debug config
+// pops up a dialog window that cannot be suppressed programmatically.
+#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
+ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
+ GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX)
+#define GTEST_HAS_DEATH_TEST 1
+#include <vector> // NOLINT
+#endif
+
+// We don't support MSVC 7.1 with exceptions disabled now. Therefore
+// all the compilers we care about are adequate for supporting
+// value-parameterized tests.
+#define GTEST_HAS_PARAM_TEST 1
+
+// Determines whether to support type-driven tests.
+
+// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
+// Sun Pro CC, and IBM Visual Age support.
+#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \
+ defined(__IBMCPP__)
+#define GTEST_HAS_TYPED_TEST 1
+#define GTEST_HAS_TYPED_TEST_P 1
+#endif
+
+// Determines whether to support Combine(). This only makes sense when
+// value-parameterized tests are enabled. The implementation doesn't
+// work on Sun Studio since it doesn't understand templated conversion
+// operators.
+#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC)
+#define GTEST_HAS_COMBINE 1
+#endif
+
+// Determines whether the system compiler uses UTF-16 for encoding wide strings.
+#define GTEST_WIDE_STRING_USES_UTF16_ \
+ (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX)
+
+// Defines some utility macros.
+
+// The GNU compiler emits a warning if nested "if" statements are followed by
+// an "else" statement and braces are not used to explicitly disambiguate the
+// "else" binding. This leads to problems with code like:
+//
+// if (gate)
+// ASSERT_*(condition) << "Some message";
+//
+// The "switch (0) case 0:" idiom is used to suppress this.
+#ifdef __INTEL_COMPILER
+#define GTEST_AMBIGUOUS_ELSE_BLOCKER_
+#else
+#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: // NOLINT
+#endif
+
+// Use this annotation at the end of a struct/class definition to
+// prevent the compiler from optimizing away instances that are never
+// used. This is useful when all interesting logic happens inside the
+// c'tor and / or d'tor. Example:
+//
+// struct Foo {
+// Foo() { ... }
+// } GTEST_ATTRIBUTE_UNUSED_;
+//
+// Also use it after a variable or parameter declaration to tell the
+// compiler the variable/parameter does not have to be used.
+#if defined(__GNUC__) && !defined(COMPILER_ICC)
+#define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused))
+#else
+#define GTEST_ATTRIBUTE_UNUSED_
+#endif
+
+// A macro to disallow operator=
+// This should be used in the private: declarations for a class.
+#define GTEST_DISALLOW_ASSIGN_(type)\
+ void operator=(type const &)
+
+// A macro to disallow copy constructor and operator=
+// This should be used in the private: declarations for a class.
+#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\
+ type(type const &);\
+ GTEST_DISALLOW_ASSIGN_(type)
+
+// Tell the compiler to warn about unused return values for functions declared
+// with this macro. The macro should be used on function declarations
+// following the argument list:
+//
+// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;
+#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC)
+#define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result))
+#else
+#define GTEST_MUST_USE_RESULT_
+#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC
+
+// Determine whether the compiler supports Microsoft's Structured Exception
+// Handling. This is supported by several Windows compilers but generally
+// does not exist on any other system.
+#ifndef GTEST_HAS_SEH
+// The user didn't tell us, so we need to figure it out.
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// These two compilers are known to support SEH.
+#define GTEST_HAS_SEH 1
+#else
+// Assume no SEH.
+#define GTEST_HAS_SEH 0
+#endif
+
+#endif // GTEST_HAS_SEH
+
+#ifdef _MSC_VER
+
+#if GTEST_LINKED_AS_SHARED_LIBRARY
+#define GTEST_API_ __declspec(dllimport)
+#elif GTEST_CREATE_SHARED_LIBRARY
+#define GTEST_API_ __declspec(dllexport)
+#endif
+
+#endif // _MSC_VER
+
+#ifndef GTEST_API_
+#define GTEST_API_
+#endif
+
+namespace testing {
+
+class Message;
+
+namespace internal {
+
+class String;
+
+typedef ::std::stringstream StrStream;
+
+// A helper for suppressing warnings on constant condition. It just
+// returns 'condition'.
+GTEST_API_ bool IsTrue(bool condition);
+
+// Defines scoped_ptr.
+
+// This implementation of scoped_ptr is PARTIAL - it only contains
+// enough stuff to satisfy Google Test's need.
+template <typename T>
+class scoped_ptr {
+ public:
+ typedef T element_type;
+
+ explicit scoped_ptr(T* p = NULL) : ptr_(p) {}
+ ~scoped_ptr() { reset(); }
+
+ T& operator*() const { return *ptr_; }
+ T* operator->() const { return ptr_; }
+ T* get() const { return ptr_; }
+
+ T* release() {
+ T* const ptr = ptr_;
+ ptr_ = NULL;
+ return ptr;
+ }
+
+ void reset(T* p = NULL) {
+ if (p != ptr_) {
+ if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type.
+ delete ptr_;
+ }
+ ptr_ = p;
+ }
+ }
+ private:
+ T* ptr_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr);
+};
+
+// Defines RE.
+
+// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended
+// Regular Expression syntax.
+class GTEST_API_ RE {
+ public:
+ // A copy constructor is required by the Standard to initialize object
+ // references from r-values.
+ RE(const RE& other) { Init(other.pattern()); }
+
+ // Constructs an RE from a string.
+ RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT
+
+#if GTEST_HAS_GLOBAL_STRING
+ RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT
+#endif // GTEST_HAS_GLOBAL_STRING
+
+ RE(const char* regex) { Init(regex); } // NOLINT
+ ~RE();
+
+ // Returns the string representation of the regex.
+ const char* pattern() const { return pattern_; }
+
+ // FullMatch(str, re) returns true iff regular expression re matches
+ // the entire str.
+ // PartialMatch(str, re) returns true iff regular expression re
+ // matches a substring of str (including str itself).
+ //
+ // TODO(wan@google.com): make FullMatch() and PartialMatch() work
+ // when str contains NUL characters.
+ static bool FullMatch(const ::std::string& str, const RE& re) {
+ return FullMatch(str.c_str(), re);
+ }
+ static bool PartialMatch(const ::std::string& str, const RE& re) {
+ return PartialMatch(str.c_str(), re);
+ }
+
+#if GTEST_HAS_GLOBAL_STRING
+ static bool FullMatch(const ::string& str, const RE& re) {
+ return FullMatch(str.c_str(), re);
+ }
+ static bool PartialMatch(const ::string& str, const RE& re) {
+ return PartialMatch(str.c_str(), re);
+ }
+#endif // GTEST_HAS_GLOBAL_STRING
+
+ static bool FullMatch(const char* str, const RE& re);
+ static bool PartialMatch(const char* str, const RE& re);
+
+ private:
+ void Init(const char* regex);
+
+ // We use a const char* instead of a string, as Google Test may be used
+ // where string is not available. We also do not use Google Test's own
+ // String type here, in order to simplify dependencies between the
+ // files.
+ const char* pattern_;
+ bool is_valid_;
+#if GTEST_USES_POSIX_RE
+ regex_t full_regex_; // For FullMatch().
+ regex_t partial_regex_; // For PartialMatch().
+#else // GTEST_USES_SIMPLE_RE
+ const char* full_pattern_; // For FullMatch();
+#endif
+
+ GTEST_DISALLOW_ASSIGN_(RE);
+};
+
+// Defines logging utilities:
+// GTEST_LOG_(severity) - logs messages at the specified severity level. The
+// message itself is streamed into the macro.
+// LogToStderr() - directs all log messages to stderr.
+// FlushInfoLog() - flushes informational log messages.
+
+enum GTestLogSeverity {
+ GTEST_INFO,
+ GTEST_WARNING,
+ GTEST_ERROR,
+ GTEST_FATAL
+};
+
+// Formats log entry severity, provides a stream object for streaming the
+// log message, and terminates the message with a newline when going out of
+// scope.
+class GTEST_API_ GTestLog {
+ public:
+ GTestLog(GTestLogSeverity severity, const char* file, int line);
+
+ // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
+ ~GTestLog();
+
+ ::std::ostream& GetStream() { return ::std::cerr; }
+
+ private:
+ const GTestLogSeverity severity_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog);
+};
+
+#define GTEST_LOG_(severity) \
+ ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \
+ __FILE__, __LINE__).GetStream()
+
+inline void LogToStderr() {}
+inline void FlushInfoLog() { fflush(NULL); }
+
+// INTERNAL IMPLEMENTATION - DO NOT USE.
+//
+// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
+// is not satisfied.
+// Synopsys:
+// GTEST_CHECK_(boolean_condition);
+// or
+// GTEST_CHECK_(boolean_condition) << "Additional message";
+//
+// This checks the condition and if the condition is not satisfied
+// it prints message about the condition violation, including the
+// condition itself, plus additional message streamed into it, if any,
+// and then it aborts the program. It aborts the program irrespective of
+// whether it is built in the debug mode or not.
+#define GTEST_CHECK_(condition) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (::testing::internal::IsTrue(condition)) \
+ ; \
+ else \
+ GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
+
+// An all-mode assert to verify that the given POSIX-style function
+// call returns 0 (indicating success). Known limitation: this
+// doesn't expand to a balanced 'if' statement, so enclose the macro
+// in {} if you need to use it as the only statement in an 'if'
+// branch.
+#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \
+ if (const int gtest_error = (posix_call)) \
+ GTEST_LOG_(FATAL) << #posix_call << "failed with error " \
+ << gtest_error
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Downcasts the pointer of type Base to Derived.
+// Derived must be a subclass of Base. The parameter MUST
+// point to a class of type Derived, not any subclass of it.
+// When RTTI is available, the function performs a runtime
+// check to enforce this.
+template <class Derived, class Base>
+Derived* CheckedDowncastToActualType(Base* base) {
+#if GTEST_HAS_RTTI
+ GTEST_CHECK_(typeid(*base) == typeid(Derived));
+ return dynamic_cast<Derived*>(base); // NOLINT
+#else
+ return static_cast<Derived*>(base); // Poor man's downcast.
+#endif
+}
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+
+// Defines the stderr capturer:
+// CaptureStdout - starts capturing stdout.
+// GetCapturedStdout - stops capturing stdout and returns the captured string.
+// CaptureStderr - starts capturing stderr.
+// GetCapturedStderr - stops capturing stderr and returns the captured string.
+//
+GTEST_API_ void CaptureStdout();
+GTEST_API_ String GetCapturedStdout();
+GTEST_API_ void CaptureStderr();
+GTEST_API_ String GetCapturedStderr();
+
+#endif // GTEST_HAS_STREAM_REDIRECTION_
+
+
+#if GTEST_HAS_DEATH_TEST
+
+// A copy of all command line arguments. Set by InitGoogleTest().
+extern ::std::vector<String> g_argvs;
+
+// GTEST_HAS_DEATH_TEST implies we have ::std::string.
+const ::std::vector<String>& GetArgvs();
+
+#endif // GTEST_HAS_DEATH_TEST
+
+// Defines synchronization primitives.
+
+#if GTEST_HAS_PTHREAD
+
+// Sleeps for (roughly) n milli-seconds. This function is only for
+// testing Google Test's own constructs. Don't use it in user tests,
+// either directly or indirectly.
+inline void SleepMilliseconds(int n) {
+ const timespec time = {
+ 0, // 0 seconds.
+ n * 1000L * 1000L, // And n ms.
+ };
+ nanosleep(&time, NULL);
+}
+
+// Allows a controller thread to pause execution of newly created
+// threads until notified. Instances of this class must be created
+// and destroyed in the controller thread.
+//
+// This class is only for testing Google Test's own constructs. Do not
+// use it in user tests, either directly or indirectly.
+class Notification {
+ public:
+ Notification() : notified_(false) {}
+
+ // Notifies all threads created with this notification to start. Must
+ // be called from the controller thread.
+ void Notify() { notified_ = true; }
+
+ // Blocks until the controller thread notifies. Must be called from a test
+ // thread.
+ void WaitForNotification() {
+ while(!notified_) {
+ SleepMilliseconds(10);
+ }
+ }
+
+ private:
+ volatile bool notified_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
+};
+
+// As a C-function, ThreadFuncWithCLinkage cannot be templated itself.
+// Consequently, it cannot select a correct instantiation of ThreadWithParam
+// in order to call its Run(). Introducing ThreadWithParamBase as a
+// non-templated base class for ThreadWithParam allows us to bypass this
+// problem.
+class ThreadWithParamBase {
+ public:
+ virtual ~ThreadWithParamBase() {}
+ virtual void Run() = 0;
+};
+
+// pthread_create() accepts a pointer to a function type with the C linkage.
+// According to the Standard (7.5/1), function types with different linkages
+// are different even if they are otherwise identical. Some compilers (for
+// example, SunStudio) treat them as different types. Since class methods
+// cannot be defined with C-linkage we need to define a free C-function to
+// pass into pthread_create().
+extern "C" inline void* ThreadFuncWithCLinkage(void* thread) {
+ static_cast<ThreadWithParamBase*>(thread)->Run();
+ return NULL;
+}
+
+// Helper class for testing Google Test's multi-threading constructs.
+// To use it, write:
+//
+// void ThreadFunc(int param) { /* Do things with param */ }
+// Notification thread_can_start;
+// ...
+// // The thread_can_start parameter is optional; you can supply NULL.
+// ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start);
+// thread_can_start.Notify();
+//
+// These classes are only for testing Google Test's own constructs. Do
+// not use them in user tests, either directly or indirectly.
+template <typename T>
+class ThreadWithParam : public ThreadWithParamBase {
+ public:
+ typedef void (*UserThreadFunc)(T);
+
+ ThreadWithParam(
+ UserThreadFunc func, T param, Notification* thread_can_start)
+ : func_(func),
+ param_(param),
+ thread_can_start_(thread_can_start),
+ finished_(false) {
+ ThreadWithParamBase* const base = this;
+ // The thread can be created only after all fields except thread_
+ // have been initialized.
+ GTEST_CHECK_POSIX_SUCCESS_(
+ pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base));
+ }
+ ~ThreadWithParam() { Join(); }
+
+ void Join() {
+ if (!finished_) {
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));
+ finished_ = true;
+ }
+ }
+
+ virtual void Run() {
+ if (thread_can_start_ != NULL)
+ thread_can_start_->WaitForNotification();
+ func_(param_);
+ }
+
+ private:
+ const UserThreadFunc func_; // User-supplied thread function.
+ const T param_; // User-supplied parameter to the thread function.
+ // When non-NULL, used to block execution until the controller thread
+ // notifies.
+ Notification* const thread_can_start_;
+ bool finished_; // true iff we know that the thread function has finished.
+ pthread_t thread_; // The native thread object.
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
+};
+
+// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is
+// true.
+#include <pthread.h>
+
+// MutexBase and Mutex implement mutex on pthreads-based platforms. They
+// are used in conjunction with class MutexLock:
+//
+// Mutex mutex;
+// ...
+// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end
+// // of the current scope.
+//
+// MutexBase implements behavior for both statically and dynamically
+// allocated mutexes. Do not use MutexBase directly. Instead, write
+// the following to define a static mutex:
+//
+// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);
+//
+// You can forward declare a static mutex like this:
+//
+// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
+//
+// To create a dynamic mutex, just define an object of type Mutex.
+class MutexBase {
+ public:
+ // Acquires this mutex.
+ void Lock() {
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
+ owner_ = pthread_self();
+ }
+
+ // Releases this mutex.
+ void Unlock() {
+ // We don't protect writing to owner_ here, as it's the caller's
+ // responsibility to ensure that the current thread holds the
+ // mutex when this is called.
+ owner_ = 0;
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
+ }
+
+ // Does nothing if the current thread holds the mutex. Otherwise, crashes
+ // with high probability.
+ void AssertHeld() const {
+ GTEST_CHECK_(owner_ == pthread_self())
+ << "The current thread is not holding the mutex @" << this;
+ }
+
+ // A static mutex may be used before main() is entered. It may even
+ // be used before the dynamic initialization stage. Therefore we
+ // must be able to initialize a static mutex object at link time.
+ // This means MutexBase has to be a POD and its member variables
+ // have to be public.
+ public:
+ pthread_mutex_t mutex_; // The underlying pthread mutex.
+ pthread_t owner_; // The thread holding the mutex; 0 means no one holds it.
+};
+
+// Forward-declares a static mutex.
+#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
+ extern ::testing::internal::MutexBase mutex
+
+// Defines and statically (i.e. at link time) initializes a static mutex.
+#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
+ ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 }
+
+// The Mutex class can only be used for mutexes created at runtime. It
+// shares its API with MutexBase otherwise.
+class Mutex : public MutexBase {
+ public:
+ Mutex() {
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
+ owner_ = 0;
+ }
+ ~Mutex() {
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_));
+ }
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex);
+};
+
+// We cannot name this class MutexLock as the ctor declaration would
+// conflict with a macro named MutexLock, which is defined on some
+// platforms. Hence the typedef trick below.
+class GTestMutexLock {
+ public:
+ explicit GTestMutexLock(MutexBase* mutex)
+ : mutex_(mutex) { mutex_->Lock(); }
+
+ ~GTestMutexLock() { mutex_->Unlock(); }
+
+ private:
+ MutexBase* const mutex_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock);
+};
+
+typedef GTestMutexLock MutexLock;
+
+// Helpers for ThreadLocal.
+
+// pthread_key_create() requires DeleteThreadLocalValue() to have
+// C-linkage. Therefore it cannot be templatized to access
+// ThreadLocal<T>. Hence the need for class
+// ThreadLocalValueHolderBase.
+class ThreadLocalValueHolderBase {
+ public:
+ virtual ~ThreadLocalValueHolderBase() {}
+};
+
+// Called by pthread to delete thread-local data stored by
+// pthread_setspecific().
+extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
+ delete static_cast<ThreadLocalValueHolderBase*>(value_holder);
+}
+
+// Implements thread-local storage on pthreads-based systems.
+//
+// // Thread 1
+// ThreadLocal<int> tl(100); // 100 is the default value for each thread.
+//
+// // Thread 2
+// tl.set(150); // Changes the value for thread 2 only.
+// EXPECT_EQ(150, tl.get());
+//
+// // Thread 1
+// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value.
+// tl.set(200);
+// EXPECT_EQ(200, tl.get());
+//
+// The template type argument T must have a public copy constructor.
+// In addition, the default ThreadLocal constructor requires T to have
+// a public default constructor.
+//
+// An object managed for a thread by a ThreadLocal instance is deleted
+// when the thread exits. Or, if the ThreadLocal instance dies in
+// that thread, when the ThreadLocal dies. It's the user's
+// responsibility to ensure that all other threads using a ThreadLocal
+// have exited when it dies, or the per-thread objects for those
+// threads will not be deleted.
+//
+// Google Test only uses global ThreadLocal objects. That means they
+// will die after main() has returned. Therefore, no per-thread
+// object managed by Google Test will be leaked as long as all threads
+// using Google Test have exited when main() returns.
+template <typename T>
+class ThreadLocal {
+ public:
+ ThreadLocal() : key_(CreateKey()),
+ default_() {}
+ explicit ThreadLocal(const T& value) : key_(CreateKey()),
+ default_(value) {}
+
+ ~ThreadLocal() {
+ // Destroys the managed object for the current thread, if any.
+ DeleteThreadLocalValue(pthread_getspecific(key_));
+
+ // Releases resources associated with the key. This will *not*
+ // delete managed objects for other threads.
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_));
+ }
+
+ T* pointer() { return GetOrCreateValue(); }
+ const T* pointer() const { return GetOrCreateValue(); }
+ const T& get() const { return *pointer(); }
+ void set(const T& value) { *pointer() = value; }
+
+ private:
+ // Holds a value of type T.
+ class ValueHolder : public ThreadLocalValueHolderBase {
+ public:
+ explicit ValueHolder(const T& value) : value_(value) {}
+
+ T* pointer() { return &value_; }
+
+ private:
+ T value_;
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder);
+ };
+
+ static pthread_key_t CreateKey() {
+ pthread_key_t key;
+ // When a thread exits, DeleteThreadLocalValue() will be called on
+ // the object managed for that thread.
+ GTEST_CHECK_POSIX_SUCCESS_(
+ pthread_key_create(&key, &DeleteThreadLocalValue));
+ return key;
+ }
+
+ T* GetOrCreateValue() const {
+ ThreadLocalValueHolderBase* const holder =
+ static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_));
+ if (holder != NULL) {
+ return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();
+ }
+
+ ValueHolder* const new_holder = new ValueHolder(default_);
+ ThreadLocalValueHolderBase* const holder_base = new_holder;
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));
+ return new_holder->pointer();
+ }
+
+ // A key pthreads uses for looking up per-thread values.
+ const pthread_key_t key_;
+ const T default_; // The default value for each thread.
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
+};
+
+#define GTEST_IS_THREADSAFE 1
+
+#else // GTEST_HAS_PTHREAD
+
+// A dummy implementation of synchronization primitives (mutex, lock,
+// and thread-local variable). Necessary for compiling Google Test where
+// mutex is not supported - using Google Test in multiple threads is not
+// supported on such platforms.
+
+class Mutex {
+ public:
+ Mutex() {}
+ void AssertHeld() const {}
+};
+
+#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
+ extern ::testing::internal::Mutex mutex
+
+#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex
+
+class GTestMutexLock {
+ public:
+ explicit GTestMutexLock(Mutex*) {} // NOLINT
+};
+
+typedef GTestMutexLock MutexLock;
+
+template <typename T>
+class ThreadLocal {
+ public:
+ ThreadLocal() : value_() {}
+ explicit ThreadLocal(const T& value) : value_(value) {}
+ T* pointer() { return &value_; }
+ const T* pointer() const { return &value_; }
+ const T& get() const { return value_; }
+ void set(const T& value) { value_ = value; }
+ private:
+ T value_;
+};
+
+// The above synchronization primitives have dummy implementations.
+// Therefore Google Test is not thread-safe.
+#define GTEST_IS_THREADSAFE 0
+
+#endif // GTEST_HAS_PTHREAD
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+GTEST_API_ size_t GetThreadCount();
+
+// Passing non-POD classes through ellipsis (...) crashes the ARM
+// compiler and generates a warning in Sun Studio. The Nokia Symbian
+// and the IBM XL C/C++ compiler try to instantiate a copy constructor
+// for objects passed through ellipsis (...), failing for uncopyable
+// objects. We define this to ensure that only POD is passed through
+// ellipsis on these systems.
+#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC)
+// We lose support for NULL detection where the compiler doesn't like
+// passing non-POD classes through ellipsis (...).
+#define GTEST_ELLIPSIS_NEEDS_POD_ 1
+#else
+#define GTEST_CAN_COMPARE_NULL 1
+#endif
+
+// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between
+// const T& and const T* in a function template. These compilers
+// _can_ decide between class template specializations for T and T*,
+// so a tr1::type_traits-like is_pointer works.
+#if defined(__SYMBIAN32__) || defined(__IBMCPP__)
+#define GTEST_NEEDS_IS_POINTER_ 1
+#endif
+
+template <bool bool_value>
+struct bool_constant {
+ typedef bool_constant<bool_value> type;
+ static const bool value = bool_value;
+};
+template <bool bool_value> const bool bool_constant<bool_value>::value;
+
+typedef bool_constant<false> false_type;
+typedef bool_constant<true> true_type;
+
+template <typename T>
+struct is_pointer : public false_type {};
+
+template <typename T>
+struct is_pointer<T*> : public true_type {};
+
+#if GTEST_OS_WINDOWS
+#define GTEST_PATH_SEP_ "\\"
+#define GTEST_HAS_ALT_PATH_SEP_ 1
+// The biggest signed integer type the compiler supports.
+typedef __int64 BiggestInt;
+#else
+#define GTEST_PATH_SEP_ "/"
+#define GTEST_HAS_ALT_PATH_SEP_ 0
+typedef long long BiggestInt; // NOLINT
+#endif // GTEST_OS_WINDOWS
+
+// The testing::internal::posix namespace holds wrappers for common
+// POSIX functions. These wrappers hide the differences between
+// Windows/MSVC and POSIX systems. Since some compilers define these
+// standard functions as macros, the wrapper cannot have the same name
+// as the wrapped function.
+
+namespace posix {
+
+// Functions with a different name on Windows.
+
+#if GTEST_OS_WINDOWS
+
+typedef struct _stat StatStruct;
+
+#ifdef __BORLANDC__
+inline int IsATTY(int fd) { return isatty(fd); }
+inline int StrCaseCmp(const char* s1, const char* s2) {
+ return stricmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return strdup(src); }
+#else // !__BORLANDC__
+#if GTEST_OS_WINDOWS_MOBILE
+inline int IsATTY(int /* fd */) { return 0; }
+#else
+inline int IsATTY(int fd) { return _isatty(fd); }
+#endif // GTEST_OS_WINDOWS_MOBILE
+inline int StrCaseCmp(const char* s1, const char* s2) {
+ return _stricmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return _strdup(src); }
+#endif // __BORLANDC__
+
+#if GTEST_OS_WINDOWS_MOBILE
+inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }
+// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this
+// time and thus not defined there.
+#else
+inline int FileNo(FILE* file) { return _fileno(file); }
+inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
+inline int RmDir(const char* dir) { return _rmdir(dir); }
+inline bool IsDir(const StatStruct& st) {
+ return (_S_IFDIR & st.st_mode) != 0;
+}
+#endif // GTEST_OS_WINDOWS_MOBILE
+
+#else
+
+typedef struct stat StatStruct;
+
+inline int FileNo(FILE* file) { return fileno(file); }
+inline int IsATTY(int fd) { return isatty(fd); }
+inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
+inline int StrCaseCmp(const char* s1, const char* s2) {
+ return strcasecmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return strdup(src); }
+inline int RmDir(const char* dir) { return rmdir(dir); }
+inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
+
+#endif // GTEST_OS_WINDOWS
+
+// Functions deprecated by MSVC 8.0.
+
+#ifdef _MSC_VER
+// Temporarily disable warning 4996 (deprecated function).
+#pragma warning(push)
+#pragma warning(disable:4996)
+#endif
+
+inline const char* StrNCpy(char* dest, const char* src, size_t n) {
+ return strncpy(dest, src, n);
+}
+
+// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and
+// StrError() aren't needed on Windows CE at this time and thus not
+// defined there.
+
+#if !GTEST_OS_WINDOWS_MOBILE
+inline int ChDir(const char* dir) { return chdir(dir); }
+#endif
+inline FILE* FOpen(const char* path, const char* mode) {
+ return fopen(path, mode);
+}
+#if !GTEST_OS_WINDOWS_MOBILE
+inline FILE *FReopen(const char* path, const char* mode, FILE* stream) {
+ return freopen(path, mode, stream);
+}
+inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }
+#endif
+inline int FClose(FILE* fp) { return fclose(fp); }
+#if !GTEST_OS_WINDOWS_MOBILE
+inline int Read(int fd, void* buf, unsigned int count) {
+ return static_cast<int>(read(fd, buf, count));
+}
+inline int Write(int fd, const void* buf, unsigned int count) {
+ return static_cast<int>(write(fd, buf, count));
+}
+inline int Close(int fd) { return close(fd); }
+inline const char* StrError(int errnum) { return strerror(errnum); }
+#endif
+inline const char* GetEnv(const char* name) {
+#if GTEST_OS_WINDOWS_MOBILE
+ // We are on Windows CE, which has no environment variables.
+ return NULL;
+#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
+ // Environment variables which we programmatically clear will be set to the
+ // empty string rather than unset (NULL). Handle that case.
+ const char* const env = getenv(name);
+ return (env != NULL && env[0] != '\0') ? env : NULL;
+#else
+ return getenv(name);
+#endif
+}
+
+#ifdef _MSC_VER
+#pragma warning(pop) // Restores the warning state.
+#endif
+
+#if GTEST_OS_WINDOWS_MOBILE
+// Windows CE has no C library. The abort() function is used in
+// several places in Google Test. This implementation provides a reasonable
+// imitation of standard behaviour.
+void Abort();
+#else
+inline void Abort() { abort(); }
+#endif // GTEST_OS_WINDOWS_MOBILE
+
+} // namespace posix
+
+// The maximum number a BiggestInt can represent. This definition
+// works no matter BiggestInt is represented in one's complement or
+// two's complement.
+//
+// We cannot rely on numeric_limits in STL, as __int64 and long long
+// are not part of standard C++ and numeric_limits doesn't need to be
+// defined for them.
+const BiggestInt kMaxBiggestInt =
+ ~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1));
+
+// This template class serves as a compile-time function from size to
+// type. It maps a size in bytes to a primitive type with that
+// size. e.g.
+//
+// TypeWithSize<4>::UInt
+//
+// is typedef-ed to be unsigned int (unsigned integer made up of 4
+// bytes).
+//
+// Such functionality should belong to STL, but I cannot find it
+// there.
+//
+// Google Test uses this class in the implementation of floating-point
+// comparison.
+//
+// For now it only handles UInt (unsigned int) as that's all Google Test
+// needs. Other types can be easily added in the future if need
+// arises.
+template <size_t size>
+class TypeWithSize {
+ public:
+ // This prevents the user from using TypeWithSize<N> with incorrect
+ // values of N.
+ typedef void UInt;
+};
+
+// The specialization for size 4.
+template <>
+class TypeWithSize<4> {
+ public:
+ // unsigned int has size 4 in both gcc and MSVC.
+ //
+ // As base/basictypes.h doesn't compile on Windows, we cannot use
+ // uint32, uint64, and etc here.
+ typedef int Int;
+ typedef unsigned int UInt;
+};
+
+// The specialization for size 8.
+template <>
+class TypeWithSize<8> {
+ public:
+#if GTEST_OS_WINDOWS
+ typedef __int64 Int;
+ typedef unsigned __int64 UInt;
+#else
+ typedef long long Int; // NOLINT
+ typedef unsigned long long UInt; // NOLINT
+#endif // GTEST_OS_WINDOWS
+};
+
+// Integer types of known sizes.
+typedef TypeWithSize<4>::Int Int32;
+typedef TypeWithSize<4>::UInt UInt32;
+typedef TypeWithSize<8>::Int Int64;
+typedef TypeWithSize<8>::UInt UInt64;
+typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
+
+// Utilities for command line flags and environment variables.
+
+// Macro for referencing flags.
+#define GTEST_FLAG(name) FLAGS_gtest_##name
+
+// Macros for declaring flags.
+#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
+#define GTEST_DECLARE_int32_(name) \
+ GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)
+#define GTEST_DECLARE_string_(name) \
+ GTEST_API_ extern ::testing::internal::String GTEST_FLAG(name)
+
+// Macros for defining flags.
+#define GTEST_DEFINE_bool_(name, default_val, doc) \
+ GTEST_API_ bool GTEST_FLAG(name) = (default_val)
+#define GTEST_DEFINE_int32_(name, default_val, doc) \
+ GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
+#define GTEST_DEFINE_string_(name, default_val, doc) \
+ GTEST_API_ ::testing::internal::String GTEST_FLAG(name) = (default_val)
+
+// Parses 'str' for a 32-bit signed integer. If successful, writes the result
+// to *value and returns true; otherwise leaves *value unchanged and returns
+// false.
+// TODO(chandlerc): Find a better way to refactor flag and environment parsing
+// out of both gtest-port.cc and gtest.cc to avoid exporting this utility
+// function.
+bool ParseInt32(const Message& src_text, const char* str, Int32* value);
+
+// Parses a bool/Int32/string from the environment variable
+// corresponding to the given Google Test flag.
+bool BoolFromGTestEnv(const char* flag, bool default_val);
+GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val);
+const char* StringFromGTestEnv(const char* flag, const char* default_val);
+
+} // namespace internal
+} // namespace testing
+
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
+
+#if GTEST_OS_LINUX
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#endif // GTEST_OS_LINUX
+
+#include <ctype.h>
+#include <string.h>
+#include <iomanip>
+#include <limits>
+#include <set>
+
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// 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.
+//
+// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file declares the String class and functions used internally by
+// Google Test. They are subject to change without notice. They should not used
+// by code external to Google Test.
+//
+// This header file is #included by <gtest/internal/gtest-internal.h>.
+// It should not be #included by other files.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
+
+#ifdef __BORLANDC__
+// string.h is not guaranteed to provide strcpy on C++ Builder.
+#include <mem.h>
+#endif
+
+#include <string.h>
+
+#include <string>
+
+namespace testing {
+namespace internal {
+
+// String - a UTF-8 string class.
+//
+// For historic reasons, we don't use std::string.
+//
+// TODO(wan@google.com): replace this class with std::string or
+// implement it in terms of the latter.
+//
+// Note that String can represent both NULL and the empty string,
+// while std::string cannot represent NULL.
+//
+// NULL and the empty string are considered different. NULL is less
+// than anything (including the empty string) except itself.
+//
+// This class only provides minimum functionality necessary for
+// implementing Google Test. We do not intend to implement a full-fledged
+// string class here.
+//
+// Since the purpose of this class is to provide a substitute for
+// std::string on platforms where it cannot be used, we define a copy
+// constructor and assignment operators such that we don't need
+// conditional compilation in a lot of places.
+//
+// In order to make the representation efficient, the d'tor of String
+// is not virtual. Therefore DO NOT INHERIT FROM String.
+class GTEST_API_ String {
+ public:
+ // Static utility methods
+
+ // Returns the input enclosed in double quotes if it's not NULL;
+ // otherwise returns "(null)". For example, "\"Hello\"" is returned
+ // for input "Hello".
+ //
+ // This is useful for printing a C string in the syntax of a literal.
+ //
+ // Known issue: escape sequences are not handled yet.
+ static String ShowCStringQuoted(const char* c_str);
+
+ // Clones a 0-terminated C string, allocating memory using new. The
+ // caller is responsible for deleting the return value using
+ // delete[]. Returns the cloned string, or NULL if the input is
+ // NULL.
+ //
+ // This is different from strdup() in string.h, which allocates
+ // memory using malloc().
+ static const char* CloneCString(const char* c_str);
+
+#if GTEST_OS_WINDOWS_MOBILE
+ // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
+ // able to pass strings to Win32 APIs on CE we need to convert them
+ // to 'Unicode', UTF-16.
+
+ // Creates a UTF-16 wide string from the given ANSI string, allocating
+ // memory using new. The caller is responsible for deleting the return
+ // value using delete[]. Returns the wide string, or NULL if the
+ // input is NULL.
+ //
+ // The wide string is created using the ANSI codepage (CP_ACP) to
+ // match the behaviour of the ANSI versions of Win32 calls and the
+ // C runtime.
+ static LPCWSTR AnsiToUtf16(const char* c_str);
+
+ // Creates an ANSI string from the given wide string, allocating
+ // memory using new. The caller is responsible for deleting the return
+ // value using delete[]. Returns the ANSI string, or NULL if the
+ // input is NULL.
+ //
+ // The returned string is created using the ANSI codepage (CP_ACP) to
+ // match the behaviour of the ANSI versions of Win32 calls and the
+ // C runtime.
+ static const char* Utf16ToAnsi(LPCWSTR utf16_str);
+#endif
+
+ // Compares two C strings. Returns true iff they have the same content.
+ //
+ // Unlike strcmp(), this function can handle NULL argument(s). A
+ // NULL C string is considered different to any non-NULL C string,
+ // including the empty string.
+ static bool CStringEquals(const char* lhs, const char* rhs);
+
+ // Converts a wide C string to a String using the UTF-8 encoding.
+ // NULL will be converted to "(null)". If an error occurred during
+ // the conversion, "(failed to convert from wide string)" is
+ // returned.
+ static String ShowWideCString(const wchar_t* wide_c_str);
+
+ // Similar to ShowWideCString(), except that this function encloses
+ // the converted string in double quotes.
+ static String ShowWideCStringQuoted(const wchar_t* wide_c_str);
+
+ // Compares two wide C strings. Returns true iff they have the same
+ // content.
+ //
+ // Unlike wcscmp(), this function can handle NULL argument(s). A
+ // NULL C string is considered different to any non-NULL C string,
+ // including the empty string.
+ static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
+
+ // Compares two C strings, ignoring case. Returns true iff they
+ // have the same content.
+ //
+ // Unlike strcasecmp(), this function can handle NULL argument(s).
+ // A NULL C string is considered different to any non-NULL C string,
+ // including the empty string.
+ static bool CaseInsensitiveCStringEquals(const char* lhs,
+ const char* rhs);
+
+ // Compares two wide C strings, ignoring case. Returns true iff they
+ // have the same content.
+ //
+ // Unlike wcscasecmp(), this function can handle NULL argument(s).
+ // A NULL C string is considered different to any non-NULL wide C string,
+ // including the empty string.
+ // NB: The implementations on different platforms slightly differ.
+ // On windows, this method uses _wcsicmp which compares according to LC_CTYPE
+ // environment variable. On GNU platform this method uses wcscasecmp
+ // which compares according to LC_CTYPE category of the current locale.
+ // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
+ // current locale.
+ static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
+ const wchar_t* rhs);
+
+ // Formats a list of arguments to a String, using the same format
+ // spec string as for printf.
+ //
+ // We do not use the StringPrintf class as it is not universally
+ // available.
+ //
+ // The result is limited to 4096 characters (including the tailing
+ // 0). If 4096 characters are not enough to format the input,
+ // "<buffer exceeded>" is returned.
+ static String Format(const char* format, ...);
+
+ // C'tors
+
+ // The default c'tor constructs a NULL string.
+ String() : c_str_(NULL), length_(0) {}
+
+ // Constructs a String by cloning a 0-terminated C string.
+ String(const char* a_c_str) { // NOLINT
+ if (a_c_str == NULL) {
+ c_str_ = NULL;
+ length_ = 0;
+ } else {
+ ConstructNonNull(a_c_str, strlen(a_c_str));
+ }
+ }
+
+ // Constructs a String by copying a given number of chars from a
+ // buffer. E.g. String("hello", 3) creates the string "hel",
+ // String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "",
+ // and String(NULL, 1) results in access violation.
+ String(const char* buffer, size_t a_length) {
+ ConstructNonNull(buffer, a_length);
+ }
+
+ // The copy c'tor creates a new copy of the string. The two
+ // String objects do not share content.
+ String(const String& str) : c_str_(NULL), length_(0) { *this = str; }
+
+ // D'tor. String is intended to be a final class, so the d'tor
+ // doesn't need to be virtual.
+ ~String() { delete[] c_str_; }
+
+ // Allows a String to be implicitly converted to an ::std::string or
+ // ::string, and vice versa. Converting a String containing a NULL
+ // pointer to ::std::string or ::string is undefined behavior.
+ // Converting a ::std::string or ::string containing an embedded NUL
+ // character to a String will result in the prefix up to the first
+ // NUL character.
+ String(const ::std::string& str) {
+ ConstructNonNull(str.c_str(), str.length());
+ }
+
+ operator ::std::string() const { return ::std::string(c_str(), length()); }
+
+#if GTEST_HAS_GLOBAL_STRING
+ String(const ::string& str) {
+ ConstructNonNull(str.c_str(), str.length());
+ }
+
+ operator ::string() const { return ::string(c_str(), length()); }
+#endif // GTEST_HAS_GLOBAL_STRING
+
+ // Returns true iff this is an empty string (i.e. "").
+ bool empty() const { return (c_str() != NULL) && (length() == 0); }
+
+ // Compares this with another String.
+ // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0
+ // if this is greater than rhs.
+ int Compare(const String& rhs) const;
+
+ // Returns true iff this String equals the given C string. A NULL
+ // string and a non-NULL string are considered not equal.
+ bool operator==(const char* a_c_str) const { return Compare(a_c_str) == 0; }
+
+ // Returns true iff this String is less than the given String. A
+ // NULL string is considered less than "".
+ bool operator<(const String& rhs) const { return Compare(rhs) < 0; }
+
+ // Returns true iff this String doesn't equal the given C string. A NULL
+ // string and a non-NULL string are considered not equal.
+ bool operator!=(const char* a_c_str) const { return !(*this == a_c_str); }
+
+ // Returns true iff this String ends with the given suffix. *Any*
+ // String is considered to end with a NULL or empty suffix.
+ bool EndsWith(const char* suffix) const;
+
+ // Returns true iff this String ends with the given suffix, not considering
+ // case. Any String is considered to end with a NULL or empty suffix.
+ bool EndsWithCaseInsensitive(const char* suffix) const;
+
+ // Returns the length of the encapsulated string, or 0 if the
+ // string is NULL.
+ size_t length() const { return length_; }
+
+ // Gets the 0-terminated C string this String object represents.
+ // The String object still owns the string. Therefore the caller
+ // should NOT delete the return value.
+ const char* c_str() const { return c_str_; }
+
+ // Assigns a C string to this object. Self-assignment works.
+ const String& operator=(const char* a_c_str) {
+ return *this = String(a_c_str);
+ }
+
+ // Assigns a String object to this object. Self-assignment works.
+ const String& operator=(const String& rhs) {
+ if (this != &rhs) {
+ delete[] c_str_;
+ if (rhs.c_str() == NULL) {
+ c_str_ = NULL;
+ length_ = 0;
+ } else {
+ ConstructNonNull(rhs.c_str(), rhs.length());
+ }
+ }
+
+ return *this;
+ }
+
+ private:
+ // Constructs a non-NULL String from the given content. This
+ // function can only be called when data_ has not been allocated.
+ // ConstructNonNull(NULL, 0) results in an empty string ("").
+ // ConstructNonNull(NULL, non_zero) is undefined behavior.
+ void ConstructNonNull(const char* buffer, size_t a_length) {
+ char* const str = new char[a_length + 1];
+ memcpy(str, buffer, a_length);
+ str[a_length] = '\0';
+ c_str_ = str;
+ length_ = a_length;
+ }
+
+ const char* c_str_;
+ size_t length_;
+}; // class String
+
+// Streams a String to an ostream. Each '\0' character in the String
+// is replaced with "\\0".
+inline ::std::ostream& operator<<(::std::ostream& os, const String& str) {
+ if (str.c_str() == NULL) {
+ os << "(null)";
+ } else {
+ const char* const c_str = str.c_str();
+ for (size_t i = 0; i != str.length(); i++) {
+ if (c_str[i] == '\0') {
+ os << "\\0";
+ } else {
+ os << c_str[i];
+ }
+ }
+ }
+ return os;
+}
+
+// Gets the content of the StrStream's buffer as a String. Each '\0'
+// character in the buffer is replaced with "\\0".
+GTEST_API_ String StrStreamToString(StrStream* stream);
+
+// Converts a streamable value to a String. A NULL pointer is
+// converted to "(null)". When the input value is a ::string,
+// ::std::string, ::wstring, or ::std::wstring object, each NUL
+// character in it is replaced with "\\0".
+
+// Declared here but defined in gtest.h, so that it has access
+// to the definition of the Message class, required by the ARM
+// compiler.
+template <typename T>
+String StreamableToString(const T& streamable);
+
+} // namespace internal
+} // namespace testing
+
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// 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: keith.ray@gmail.com (Keith Ray)
+//
+// Google Test filepath utilities
+//
+// This header file declares classes and functions used internally by
+// Google Test. They are subject to change without notice.
+//
+// This file is #included in <gtest/internal/gtest-internal.h>.
+// Do not include this header file separately!
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
+
+
+namespace testing {
+namespace internal {
+
+// FilePath - a class for file and directory pathname manipulation which
+// handles platform-specific conventions (like the pathname separator).
+// Used for helper functions for naming files in a directory for xml output.
+// Except for Set methods, all methods are const or static, which provides an
+// "immutable value object" -- useful for peace of mind.
+// A FilePath with a value ending in a path separator ("like/this/") represents
+// a directory, otherwise it is assumed to represent a file. In either case,
+// it may or may not represent an actual file or directory in the file system.
+// Names are NOT checked for syntax correctness -- no checking for illegal
+// characters, malformed paths, etc.
+
+class GTEST_API_ FilePath {
+ public:
+ FilePath() : pathname_("") { }
+ FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
+
+ explicit FilePath(const char* pathname) : pathname_(pathname) {
+ Normalize();
+ }
+
+ explicit FilePath(const String& pathname) : pathname_(pathname) {
+ Normalize();
+ }
+
+ FilePath& operator=(const FilePath& rhs) {
+ Set(rhs);
+ return *this;
+ }
+
+ void Set(const FilePath& rhs) {
+ pathname_ = rhs.pathname_;
+ }
+
+ String ToString() const { return pathname_; }
+ const char* c_str() const { return pathname_.c_str(); }
+
+ // Returns the current working directory, or "" if unsuccessful.
+ static FilePath GetCurrentDir();
+
+ // Given directory = "dir", base_name = "test", number = 0,
+ // extension = "xml", returns "dir/test.xml". If number is greater
+ // than zero (e.g., 12), returns "dir/test_12.xml".
+ // On Windows platform, uses \ as the separator rather than /.
+ static FilePath MakeFileName(const FilePath& directory,
+ const FilePath& base_name,
+ int number,
+ const char* extension);
+
+ // Given directory = "dir", relative_path = "test.xml",
+ // returns "dir/test.xml".
+ // On Windows, uses \ as the separator rather than /.
+ static FilePath ConcatPaths(const FilePath& directory,
+ const FilePath& relative_path);
+
+ // Returns a pathname for a file that does not currently exist. The pathname
+ // will be directory/base_name.extension or
+ // directory/base_name_<number>.extension if directory/base_name.extension
+ // already exists. The number will be incremented until a pathname is found
+ // that does not already exist.
+ // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
+ // There could be a race condition if two or more processes are calling this
+ // function at the same time -- they could both pick the same filename.
+ static FilePath GenerateUniqueFileName(const FilePath& directory,
+ const FilePath& base_name,
+ const char* extension);
+
+ // Returns true iff the path is NULL or "".
+ bool IsEmpty() const { return c_str() == NULL || *c_str() == '\0'; }
+
+ // If input name has a trailing separator character, removes it and returns
+ // the name, otherwise return the name string unmodified.
+ // On Windows platform, uses \ as the separator, other platforms use /.
+ FilePath RemoveTrailingPathSeparator() const;
+
+ // Returns a copy of the FilePath with the directory part removed.
+ // Example: FilePath("path/to/file").RemoveDirectoryName() returns
+ // FilePath("file"). If there is no directory part ("just_a_file"), it returns
+ // the FilePath unmodified. If there is no file part ("just_a_dir/") it
+ // returns an empty FilePath ("").
+ // On Windows platform, '\' is the path separator, otherwise it is '/'.
+ FilePath RemoveDirectoryName() const;
+
+ // RemoveFileName returns the directory path with the filename removed.
+ // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
+ // If the FilePath is "a_file" or "/a_file", RemoveFileName returns
+ // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
+ // not have a file, like "just/a/dir/", it returns the FilePath unmodified.
+ // On Windows platform, '\' is the path separator, otherwise it is '/'.
+ FilePath RemoveFileName() const;
+
+ // Returns a copy of the FilePath with the case-insensitive extension removed.
+ // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
+ // FilePath("dir/file"). If a case-insensitive extension is not
+ // found, returns a copy of the original FilePath.
+ FilePath RemoveExtension(const char* extension) const;
+
+ // Creates directories so that path exists. Returns true if successful or if
+ // the directories already exist; returns false if unable to create
+ // directories for any reason. Will also return false if the FilePath does
+ // not represent a directory (that is, it doesn't end with a path separator).
+ bool CreateDirectoriesRecursively() const;
+
+ // Create the directory so that path exists. Returns true if successful or
+ // if the directory already exists; returns false if unable to create the
+ // directory for any reason, including if the parent directory does not
+ // exist. Not named "CreateDirectory" because that's a macro on Windows.
+ bool CreateFolder() const;
+
+ // Returns true if FilePath describes something in the file-system,
+ // either a file, directory, or whatever, and that something exists.
+ bool FileOrDirectoryExists() const;
+
+ // Returns true if pathname describes a directory in the file-system
+ // that exists.
+ bool DirectoryExists() const;
+
+ // Returns true if FilePath ends with a path separator, which indicates that
+ // it is intended to represent a directory. Returns false otherwise.
+ // This does NOT check that a directory (or file) actually exists.
+ bool IsDirectory() const;
+
+ // Returns true if pathname describes a root directory. (Windows has one
+ // root directory per disk drive.)
+ bool IsRootDirectory() const;
+
+ // Returns true if pathname describes an absolute path.
+ bool IsAbsolutePath() const;
+
+ private:
+ // Replaces multiple consecutive separators with a single separator.
+ // For example, "bar///foo" becomes "bar/foo". Does not eliminate other
+ // redundancies that might be in a pathname involving "." or "..".
+ //
+ // A pathname with multiple consecutive separators may occur either through
+ // user error or as a result of some scripts or APIs that generate a pathname
+ // with a trailing separator. On other platforms the same API or script
+ // may NOT generate a pathname with a trailing "/". Then elsewhere that
+ // pathname may have another "/" and pathname components added to it,
+ // without checking for the separator already being there.
+ // The script language and operating system may allow paths like "foo//bar"
+ // but some of the functions in FilePath will not handle that correctly. In
+ // particular, RemoveTrailingPathSeparator() only removes one separator, and
+ // it is called in CreateDirectoriesRecursively() assuming that it will change
+ // a pathname from directory syntax (trailing separator) to filename syntax.
+ //
+ // On Windows this method also replaces the alternate path separator '/' with
+ // the primary path separator '\\', so that for example "bar\\/\\foo" becomes
+ // "bar\\foo".
+
+ void Normalize();
+
+ // Returns a pointer to the last occurence of a valid path separator in
+ // the FilePath. On Windows, for example, both '/' and '\' are valid path
+ // separators. Returns NULL if no path separator was found.
+ const char* FindLastPathSeparator() const;
+
+ String pathname_;
+}; // class FilePath
+
+} // namespace internal
+} // namespace testing
+
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
+// This file was GENERATED by command:
+// pump.py gtest-type-util.h.pump
+// DO NOT EDIT BY HAND!!!
+
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// 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: wan@google.com (Zhanyong Wan)
+
+// Type utilities needed for implementing typed and type-parameterized
+// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
+//
+// Currently we support at most 50 types in a list, and at most 50
+// type-parameterized tests in one type-parameterized test case.
+// Please contact googletestframework@googlegroups.com if you need
+// more.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+
+
+#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
+// libstdc++ (which is where cxxabi.h comes from).
+#ifdef __GLIBCXX__
+#include <cxxabi.h>
+#endif // __GLIBCXX__
+
+namespace testing {
+namespace internal {
+
+// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
+// type. This can be used as a compile-time assertion to ensure that
+// two types are equal.
+
+template <typename T1, typename T2>
+struct AssertTypeEq;
+
+template <typename T>
+struct AssertTypeEq<T, T> {
+ typedef bool type;
+};
+
+// GetTypeName<T>() returns a human-readable name of type T.
+template <typename T>
+String GetTypeName() {
+#if GTEST_HAS_RTTI
+
+ const char* const name = typeid(T).name();
+#ifdef __GLIBCXX__
+ int status = 0;
+ // gcc's implementation of typeid(T).name() mangles the type name,
+ // so we have to demangle it.
+ char* const readable_name = abi::__cxa_demangle(name, 0, 0, &status);
+ const String name_str(status == 0 ? readable_name : name);
+ free(readable_name);
+ return name_str;
+#else
+ return name;
+#endif // __GLIBCXX__
+
+#else
+ return "<type>";
+#endif // GTEST_HAS_RTTI
+}
+
+// A unique type used as the default value for the arguments of class
+// template Types. This allows us to simulate variadic templates
+// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
+// support directly.
+struct None {};
+
+// The following family of struct and struct templates are used to
+// represent type lists. In particular, TypesN<T1, T2, ..., TN>
+// represents a type list with N types (T1, T2, ..., and TN) in it.
+// Except for Types0, every struct in the family has two member types:
+// Head for the first type in the list, and Tail for the rest of the
+// list.
+
+// The empty type list.
+struct Types0 {};
+
+// Type lists of length 1, 2, 3, and so on.
+
+template <typename T1>
+struct Types1 {
+ typedef T1 Head;
+ typedef Types0 Tail;
+};
+template <typename T1, typename T2>
+struct Types2 {
+ typedef T1 Head;
+ typedef Types1<T2> Tail;
+};
+
+template <typename T1, typename T2, typename T3>
+struct Types3 {
+ typedef T1 Head;
+ typedef Types2<T2, T3> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4>
+struct Types4 {
+ typedef T1 Head;
+ typedef Types3<T2, T3, T4> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+struct Types5 {
+ typedef T1 Head;
+ typedef Types4<T2, T3, T4, T5> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+struct Types6 {
+ typedef T1 Head;
+ typedef Types5<T2, T3, T4, T5, T6> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7>
+struct Types7 {
+ typedef T1 Head;
+ typedef Types6<T2, T3, T4, T5, T6, T7> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8>
+struct Types8 {
+ typedef T1 Head;
+ typedef Types7<T2, T3, T4, T5, T6, T7, T8> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9>
+struct Types9 {
+ typedef T1 Head;
+ typedef Types8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+struct Types10 {
+ typedef T1 Head;
+ typedef Types9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11>
+struct Types11 {
+ typedef T1 Head;
+ typedef Types10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12>
+struct Types12 {
+ typedef T1 Head;
+ typedef Types11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13>
+struct Types13 {
+ typedef T1 Head;
+ typedef Types12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14>
+struct Types14 {
+ typedef T1 Head;
+ typedef Types13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15>
+struct Types15 {
+ typedef T1 Head;
+ typedef Types14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16>
+struct Types16 {
+ typedef T1 Head;
+ typedef Types15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17>
+struct Types17 {
+ typedef T1 Head;
+ typedef Types16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18>
+struct Types18 {
+ typedef T1 Head;
+ typedef Types17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19>
+struct Types19 {
+ typedef T1 Head;
+ typedef Types18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20>
+struct Types20 {
+ typedef T1 Head;
+ typedef Types19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21>
+struct Types21 {
+ typedef T1 Head;
+ typedef Types20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22>
+struct Types22 {
+ typedef T1 Head;
+ typedef Types21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23>
+struct Types23 {
+ typedef T1 Head;
+ typedef Types22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24>
+struct Types24 {
+ typedef T1 Head;
+ typedef Types23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25>
+struct Types25 {
+ typedef T1 Head;
+ typedef Types24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26>
+struct Types26 {
+ typedef T1 Head;
+ typedef Types25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27>
+struct Types27 {
+ typedef T1 Head;
+ typedef Types26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28>
+struct Types28 {
+ typedef T1 Head;
+ typedef Types27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29>
+struct Types29 {
+ typedef T1 Head;
+ typedef Types28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30>
+struct Types30 {
+ typedef T1 Head;
+ typedef Types29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31>
+struct Types31 {
+ typedef T1 Head;
+ typedef Types30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32>
+struct Types32 {
+ typedef T1 Head;
+ typedef Types31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33>
+struct Types33 {
+ typedef T1 Head;
+ typedef Types32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34>
+struct Types34 {
+ typedef T1 Head;
+ typedef Types33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35>
+struct Types35 {
+ typedef T1 Head;
+ typedef Types34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36>
+struct Types36 {
+ typedef T1 Head;
+ typedef Types35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37>
+struct Types37 {
+ typedef T1 Head;
+ typedef Types36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38>
+struct Types38 {
+ typedef T1 Head;
+ typedef Types37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39>
+struct Types39 {
+ typedef T1 Head;
+ typedef Types38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40>
+struct Types40 {
+ typedef T1 Head;
+ typedef Types39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41>
+struct Types41 {
+ typedef T1 Head;
+ typedef Types40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42>
+struct Types42 {
+ typedef T1 Head;
+ typedef Types41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43>
+struct Types43 {
+ typedef T1 Head;
+ typedef Types42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+ T43> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44>
+struct Types44 {
+ typedef T1 Head;
+ typedef Types43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45>
+struct Types45 {
+ typedef T1 Head;
+ typedef Types44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44, T45> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46>
+struct Types46 {
+ typedef T1 Head;
+ typedef Types45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44, T45, T46> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47>
+struct Types47 {
+ typedef T1 Head;
+ typedef Types46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44, T45, T46, T47> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47, typename T48>
+struct Types48 {
+ typedef T1 Head;
+ typedef Types47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44, T45, T46, T47, T48> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47, typename T48, typename T49>
+struct Types49 {
+ typedef T1 Head;
+ typedef Types48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44, T45, T46, T47, T48, T49> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47, typename T48, typename T49, typename T50>
+struct Types50 {
+ typedef T1 Head;
+ typedef Types49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44, T45, T46, T47, T48, T49, T50> Tail;
+};
+
+
+} // namespace internal
+
+// We don't want to require the users to write TypesN<...> directly,
+// as that would require them to count the length. Types<...> is much
+// easier to write, but generates horrible messages when there is a
+// compiler error, as gcc insists on printing out each template
+// argument, even if it has the default value (this means Types<int>
+// will appear as Types<int, None, None, ..., None> in the compiler
+// errors).
+//
+// Our solution is to combine the best part of the two approaches: a
+// user would write Types<T1, ..., TN>, and Google Test will translate
+// that to TypesN<T1, ..., TN> internally to make error messages
+// readable. The translation is done by the 'type' member of the
+// Types template.
+template <typename T1 = internal::None, typename T2 = internal::None,
+ typename T3 = internal::None, typename T4 = internal::None,
+ typename T5 = internal::None, typename T6 = internal::None,
+ typename T7 = internal::None, typename T8 = internal::None,
+ typename T9 = internal::None, typename T10 = internal::None,
+ typename T11 = internal::None, typename T12 = internal::None,
+ typename T13 = internal::None, typename T14 = internal::None,
+ typename T15 = internal::None, typename T16 = internal::None,
+ typename T17 = internal::None, typename T18 = internal::None,
+ typename T19 = internal::None, typename T20 = internal::None,
+ typename T21 = internal::None, typename T22 = internal::None,
+ typename T23 = internal::None, typename T24 = internal::None,
+ typename T25 = internal::None, typename T26 = internal::None,
+ typename T27 = internal::None, typename T28 = internal::None,
+ typename T29 = internal::None, typename T30 = internal::None,
+ typename T31 = internal::None, typename T32 = internal::None,
+ typename T33 = internal::None, typename T34 = internal::None,
+ typename T35 = internal::None, typename T36 = internal::None,
+ typename T37 = internal::None, typename T38 = internal::None,
+ typename T39 = internal::None, typename T40 = internal::None,
+ typename T41 = internal::None, typename T42 = internal::None,
+ typename T43 = internal::None, typename T44 = internal::None,
+ typename T45 = internal::None, typename T46 = internal::None,
+ typename T47 = internal::None, typename T48 = internal::None,
+ typename T49 = internal::None, typename T50 = internal::None>
+struct Types {
+ typedef internal::Types50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+ T41, T42, T43, T44, T45, T46, T47, T48, T49, T50> type;
+};
+
+template <>
+struct Types<internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None> {
+ typedef internal::Types0 type;
+};
+template <typename T1>
+struct Types<T1, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None> {
+ typedef internal::Types1<T1> type;
+};
+template <typename T1, typename T2>
+struct Types<T1, T2, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None> {
+ typedef internal::Types2<T1, T2> type;
+};
+template <typename T1, typename T2, typename T3>
+struct Types<T1, T2, T3, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None> {
+ typedef internal::Types3<T1, T2, T3> type;
+};
+template <typename T1, typename T2, typename T3, typename T4>
+struct Types<T1, T2, T3, T4, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None> {
+ typedef internal::Types4<T1, T2, T3, T4> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+struct Types<T1, T2, T3, T4, T5, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None> {
+ typedef internal::Types5<T1, T2, T3, T4, T5> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+struct Types<T1, T2, T3, T4, T5, T6, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None> {
+ typedef internal::Types6<T1, T2, T3, T4, T5, T6> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7>
+struct Types<T1, T2, T3, T4, T5, T6, T7, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None> {
+ typedef internal::Types7<T1, T2, T3, T4, T5, T6, T7> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None> {
+ typedef internal::Types8<T1, T2, T3, T4, T5, T6, T7, T8> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None> {
+ typedef internal::Types9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None> {
+ typedef internal::Types10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None> {
+ typedef internal::Types11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None> {
+ typedef internal::Types12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None> {
+ typedef internal::Types13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None> {
+ typedef internal::Types14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None> {
+ typedef internal::Types15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None> {
+ typedef internal::Types16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None> {
+ typedef internal::Types17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None> {
+ typedef internal::Types18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None> {
+ typedef internal::Types19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None> {
+ typedef internal::Types20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None> {
+ typedef internal::Types21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None> {
+ typedef internal::Types22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None> {
+ typedef internal::Types23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None> {
+ typedef internal::Types24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None> {
+ typedef internal::Types25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None> {
+ typedef internal::Types26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None> {
+ typedef internal::Types27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None> {
+ typedef internal::Types28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None> {
+ typedef internal::Types29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None> {
+ typedef internal::Types30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None> {
+ typedef internal::Types31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None> {
+ typedef internal::Types32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None> {
+ typedef internal::Types33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None> {
+ typedef internal::Types34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None> {
+ typedef internal::Types35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None> {
+ typedef internal::Types36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, T37, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None> {
+ typedef internal::Types37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, T37, T38, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None> {
+ typedef internal::Types38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, T37, T38, T39, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None> {
+ typedef internal::Types39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None> {
+ typedef internal::Types40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+ T40> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None, internal::None> {
+ typedef internal::Types41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+ T41> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, internal::None,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None> {
+ typedef internal::Types42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+ T41, T42> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None, internal::None> {
+ typedef internal::Types43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+ T41, T42, T43> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None, internal::None> {
+ typedef internal::Types44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+ T41, T42, T43, T44> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+ internal::None, internal::None, internal::None, internal::None,
+ internal::None> {
+ typedef internal::Types45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+ T41, T42, T43, T44, T45> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+ T46, internal::None, internal::None, internal::None, internal::None> {
+ typedef internal::Types46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+ T41, T42, T43, T44, T45, T46> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+ T46, T47, internal::None, internal::None, internal::None> {
+ typedef internal::Types47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+ T41, T42, T43, T44, T45, T46, T47> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47, typename T48>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+ T46, T47, T48, internal::None, internal::None> {
+ typedef internal::Types48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+ T41, T42, T43, T44, T45, T46, T47, T48> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47, typename T48, typename T49>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+ T46, T47, T48, T49, internal::None> {
+ typedef internal::Types49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+ T41, T42, T43, T44, T45, T46, T47, T48, T49> type;
+};
+
+namespace internal {
+
+#define GTEST_TEMPLATE_ template <typename T> class
+
+// The template "selector" struct TemplateSel<Tmpl> is used to
+// represent Tmpl, which must be a class template with one type
+// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined
+// as the type Tmpl<T>. This allows us to actually instantiate the
+// template "selected" by TemplateSel<Tmpl>.
+//
+// This trick is necessary for simulating typedef for class templates,
+// which C++ doesn't support directly.
+template <GTEST_TEMPLATE_ Tmpl>
+struct TemplateSel {
+ template <typename T>
+ struct Bind {
+ typedef Tmpl<T> type;
+ };
+};
+
+#define GTEST_BIND_(TmplSel, T) \
+ TmplSel::template Bind<T>::type
+
+// A unique struct template used as the default value for the
+// arguments of class template Templates. This allows us to simulate
+// variadic templates (e.g. Templates<int>, Templates<int, double>,
+// and etc), which C++ doesn't support directly.
+template <typename T>
+struct NoneT {};
+
+// The following family of struct and struct templates are used to
+// represent template lists. In particular, TemplatesN<T1, T2, ...,
+// TN> represents a list of N templates (T1, T2, ..., and TN). Except
+// for Templates0, every struct in the family has two member types:
+// Head for the selector of the first template in the list, and Tail
+// for the rest of the list.
+
+// The empty template list.
+struct Templates0 {};
+
+// Template lists of length 1, 2, 3, and so on.
+
+template <GTEST_TEMPLATE_ T1>
+struct Templates1 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates0 Tail;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>
+struct Templates2 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates1<T2> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>
+struct Templates3 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates2<T2, T3> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4>
+struct Templates4 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates3<T2, T3, T4> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>
+struct Templates5 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates4<T2, T3, T4, T5> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>
+struct Templates6 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates5<T2, T3, T4, T5, T6> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7>
+struct Templates7 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates6<T2, T3, T4, T5, T6, T7> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>
+struct Templates8 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates7<T2, T3, T4, T5, T6, T7, T8> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>
+struct Templates9 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10>
+struct Templates10 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>
+struct Templates11 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>
+struct Templates12 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13>
+struct Templates13 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>
+struct Templates14 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>
+struct Templates15 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16>
+struct Templates16 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>
+struct Templates17 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>
+struct Templates18 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19>
+struct Templates19 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>
+struct Templates20 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>
+struct Templates21 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22>
+struct Templates22 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>
+struct Templates23 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>
+struct Templates24 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25>
+struct Templates25 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>
+struct Templates26 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>
+struct Templates27 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28>
+struct Templates28 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>
+struct Templates29 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>
+struct Templates30 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31>
+struct Templates31 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>
+struct Templates32 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>
+struct Templates33 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34>
+struct Templates34 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>
+struct Templates35 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>
+struct Templates36 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37>
+struct Templates37 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>
+struct Templates38 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>
+struct Templates39 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40>
+struct Templates40 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>
+struct Templates41 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>
+struct Templates42 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+ T42> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43>
+struct Templates43 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+ T43> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>
+struct Templates44 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+ T43, T44> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>
+struct Templates45 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+ T43, T44, T45> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+ GTEST_TEMPLATE_ T46>
+struct Templates46 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+ T43, T44, T45, T46> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+ GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>
+struct Templates47 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+ T43, T44, T45, T46, T47> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+ GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>
+struct Templates48 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+ T43, T44, T45, T46, T47, T48> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+ GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+ GTEST_TEMPLATE_ T49>
+struct Templates49 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+ T43, T44, T45, T46, T47, T48, T49> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+ GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+ GTEST_TEMPLATE_ T49, GTEST_TEMPLATE_ T50>
+struct Templates50 {
+ typedef TemplateSel<T1> Head;
+ typedef Templates49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+ T43, T44, T45, T46, T47, T48, T49, T50> Tail;
+};
+
+
+// We don't want to require the users to write TemplatesN<...> directly,
+// as that would require them to count the length. Templates<...> is much
+// easier to write, but generates horrible messages when there is a
+// compiler error, as gcc insists on printing out each template
+// argument, even if it has the default value (this means Templates<list>
+// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler
+// errors).
+//
+// Our solution is to combine the best part of the two approaches: a
+// user would write Templates<T1, ..., TN>, and Google Test will translate
+// that to TemplatesN<T1, ..., TN> internally to make error messages
+// readable. The translation is done by the 'type' member of the
+// Templates template.
+template <GTEST_TEMPLATE_ T1 = NoneT, GTEST_TEMPLATE_ T2 = NoneT,
+ GTEST_TEMPLATE_ T3 = NoneT, GTEST_TEMPLATE_ T4 = NoneT,
+ GTEST_TEMPLATE_ T5 = NoneT, GTEST_TEMPLATE_ T6 = NoneT,
+ GTEST_TEMPLATE_ T7 = NoneT, GTEST_TEMPLATE_ T8 = NoneT,
+ GTEST_TEMPLATE_ T9 = NoneT, GTEST_TEMPLATE_ T10 = NoneT,
+ GTEST_TEMPLATE_ T11 = NoneT, GTEST_TEMPLATE_ T12 = NoneT,
+ GTEST_TEMPLATE_ T13 = NoneT, GTEST_TEMPLATE_ T14 = NoneT,
+ GTEST_TEMPLATE_ T15 = NoneT, GTEST_TEMPLATE_ T16 = NoneT,
+ GTEST_TEMPLATE_ T17 = NoneT, GTEST_TEMPLATE_ T18 = NoneT,
+ GTEST_TEMPLATE_ T19 = NoneT, GTEST_TEMPLATE_ T20 = NoneT,
+ GTEST_TEMPLATE_ T21 = NoneT, GTEST_TEMPLATE_ T22 = NoneT,
+ GTEST_TEMPLATE_ T23 = NoneT, GTEST_TEMPLATE_ T24 = NoneT,
+ GTEST_TEMPLATE_ T25 = NoneT, GTEST_TEMPLATE_ T26 = NoneT,
+ GTEST_TEMPLATE_ T27 = NoneT, GTEST_TEMPLATE_ T28 = NoneT,
+ GTEST_TEMPLATE_ T29 = NoneT, GTEST_TEMPLATE_ T30 = NoneT,
+ GTEST_TEMPLATE_ T31 = NoneT, GTEST_TEMPLATE_ T32 = NoneT,
+ GTEST_TEMPLATE_ T33 = NoneT, GTEST_TEMPLATE_ T34 = NoneT,
+ GTEST_TEMPLATE_ T35 = NoneT, GTEST_TEMPLATE_ T36 = NoneT,
+ GTEST_TEMPLATE_ T37 = NoneT, GTEST_TEMPLATE_ T38 = NoneT,
+ GTEST_TEMPLATE_ T39 = NoneT, GTEST_TEMPLATE_ T40 = NoneT,
+ GTEST_TEMPLATE_ T41 = NoneT, GTEST_TEMPLATE_ T42 = NoneT,
+ GTEST_TEMPLATE_ T43 = NoneT, GTEST_TEMPLATE_ T44 = NoneT,
+ GTEST_TEMPLATE_ T45 = NoneT, GTEST_TEMPLATE_ T46 = NoneT,
+ GTEST_TEMPLATE_ T47 = NoneT, GTEST_TEMPLATE_ T48 = NoneT,
+ GTEST_TEMPLATE_ T49 = NoneT, GTEST_TEMPLATE_ T50 = NoneT>
+struct Templates {
+ typedef Templates50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+ T42, T43, T44, T45, T46, T47, T48, T49, T50> type;
+};
+
+template <>
+struct Templates<NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT> {
+ typedef Templates0 type;
+};
+template <GTEST_TEMPLATE_ T1>
+struct Templates<T1, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT> {
+ typedef Templates1<T1> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>
+struct Templates<T1, T2, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT> {
+ typedef Templates2<T1, T2> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>
+struct Templates<T1, T2, T3, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates3<T1, T2, T3> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4>
+struct Templates<T1, T2, T3, T4, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates4<T1, T2, T3, T4> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>
+struct Templates<T1, T2, T3, T4, T5, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates5<T1, T2, T3, T4, T5> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>
+struct Templates<T1, T2, T3, T4, T5, T6, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates6<T1, T2, T3, T4, T5, T6> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates7<T1, T2, T3, T4, T5, T6, T7> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates8<T1, T2, T3, T4, T5, T6, T7, T8> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT> {
+ typedef Templates22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT> {
+ typedef Templates23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT> {
+ typedef Templates24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT> {
+ typedef Templates25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT> {
+ typedef Templates26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT> {
+ typedef Templates27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT> {
+ typedef Templates28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT> {
+ typedef Templates29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, NoneT, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, NoneT, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, NoneT, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, NoneT, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+ T41> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, NoneT,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+ T42> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+ T42, T43> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+ NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+ T42, T43, T44> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+ T45, NoneT, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+ T42, T43, T44, T45> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+ GTEST_TEMPLATE_ T46>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+ T45, T46, NoneT, NoneT, NoneT, NoneT> {
+ typedef Templates46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+ T42, T43, T44, T45, T46> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+ GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+ T45, T46, T47, NoneT, NoneT, NoneT> {
+ typedef Templates47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+ T42, T43, T44, T45, T46, T47> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+ GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+ T45, T46, T47, T48, NoneT, NoneT> {
+ typedef Templates48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+ T42, T43, T44, T45, T46, T47, T48> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+ GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+ GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+ GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+ GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+ GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+ GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+ GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+ GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+ GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+ GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+ GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+ GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+ GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+ GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+ GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+ GTEST_TEMPLATE_ T49>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+ T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+ T45, T46, T47, T48, T49, NoneT> {
+ typedef Templates49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+ T42, T43, T44, T45, T46, T47, T48, T49> type;
+};
+
+// The TypeList template makes it possible to use either a single type
+// or a Types<...> list in TYPED_TEST_CASE() and
+// INSTANTIATE_TYPED_TEST_CASE_P().
+
+template <typename T>
+struct TypeList { typedef Types1<T> type; };
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47, typename T48, typename T49, typename T50>
+struct TypeList<Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44, T45, T46, T47, T48, T49, T50> > {
+ typedef typename Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+ T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>::type type;
+};
+
+} // namespace internal
+} // namespace testing
+
+#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+
+// Due to C++ preprocessor weirdness, we need double indirection to
+// concatenate two tokens when one of them is __LINE__. Writing
+//
+// foo ## __LINE__
+//
+// will result in the token foo__LINE__, instead of foo followed by
+// the current line number. For more details, see
+// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
+#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
+#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar
+
+// Google Test defines the testing::Message class to allow construction of
+// test messages via the << operator. The idea is that anything
+// streamable to std::ostream can be streamed to a testing::Message.
+// This allows a user to use his own types in Google Test assertions by
+// overloading the << operator.
+//
+// util/gtl/stl_logging-inl.h overloads << for STL containers. These
+// overloads cannot be defined in the std namespace, as that will be
+// undefined behavior. Therefore, they are defined in the global
+// namespace instead.
+//
+// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
+// overloads are visible in either the std namespace or the global
+// namespace, but not other namespaces, including the testing
+// namespace which Google Test's Message class is in.
+//
+// To allow STL containers (and other types that has a << operator
+// defined in the global namespace) to be used in Google Test assertions,
+// testing::Message must access the custom << operator from the global
+// namespace. Hence this helper function.
+//
+// Note: Jeffrey Yasskin suggested an alternative fix by "using
+// ::operator<<;" in the definition of Message's operator<<. That fix
+// doesn't require a helper function, but unfortunately doesn't
+// compile with MSVC.
+template <typename T>
+inline void GTestStreamToHelper(std::ostream* os, const T& val) {
+ *os << val;
+}
+
+namespace testing {
+
+// Forward declaration of classes.
+
+class AssertionResult; // Result of an assertion.
+class Message; // Represents a failure message.
+class Test; // Represents a test.
+class TestInfo; // Information about a test.
+class TestPartResult; // Result of a test part.
+class UnitTest; // A collection of test cases.
+
+namespace internal {
+
+struct TraceInfo; // Information about a trace point.
+class ScopedTrace; // Implements scoped trace.
+class TestInfoImpl; // Opaque implementation of TestInfo
+class UnitTestImpl; // Opaque implementation of UnitTest
+
+// How many times InitGoogleTest() has been called.
+extern int g_init_gtest_count;
+
+// The text used in failure messages to indicate the start of the
+// stack trace.
+GTEST_API_ extern const char kStackTraceMarker[];
+
+// A secret type that Google Test users don't know about. It has no
+// definition on purpose. Therefore it's impossible to create a
+// Secret object, which is what we want.
+class Secret;
+
+// Two overloaded helpers for checking at compile time whether an
+// expression is a null pointer literal (i.e. NULL or any 0-valued
+// compile-time integral constant). Their return values have
+// different sizes, so we can use sizeof() to test which version is
+// picked by the compiler. These helpers have no implementations, as
+// we only need their signatures.
+//
+// Given IsNullLiteralHelper(x), the compiler will pick the first
+// version if x can be implicitly converted to Secret*, and pick the
+// second version otherwise. Since Secret is a secret and incomplete
+// type, the only expression a user can write that has type Secret* is
+// a null pointer literal. Therefore, we know that x is a null
+// pointer literal if and only if the first version is picked by the
+// compiler.
+char IsNullLiteralHelper(Secret* p);
+char (&IsNullLiteralHelper(...))[2]; // NOLINT
+
+// A compile-time bool constant that is true if and only if x is a
+// null pointer literal (i.e. NULL or any 0-valued compile-time
+// integral constant).
+#ifdef GTEST_ELLIPSIS_NEEDS_POD_
+// We lose support for NULL detection where the compiler doesn't like
+// passing non-POD classes through ellipsis (...).
+#define GTEST_IS_NULL_LITERAL_(x) false
+#else
+#define GTEST_IS_NULL_LITERAL_(x) \
+ (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1)
+#endif // GTEST_ELLIPSIS_NEEDS_POD_
+
+// Appends the user-supplied message to the Google-Test-generated message.
+GTEST_API_ String AppendUserMessage(const String& gtest_msg,
+ const Message& user_msg);
+
+// A helper class for creating scoped traces in user programs.
+class GTEST_API_ ScopedTrace {
+ public:
+ // The c'tor pushes the given source file location and message onto
+ // a trace stack maintained by Google Test.
+ ScopedTrace(const char* file, int line, const Message& message);
+
+ // The d'tor pops the info pushed by the c'tor.
+ //
+ // Note that the d'tor is not virtual in order to be efficient.
+ // Don't inherit from ScopedTrace!
+ ~ScopedTrace();
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace);
+} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its
+ // c'tor and d'tor. Therefore it doesn't
+ // need to be used otherwise.
+
+// Converts a streamable value to a String. A NULL pointer is
+// converted to "(null)". When the input value is a ::string,
+// ::std::string, ::wstring, or ::std::wstring object, each NUL
+// character in it is replaced with "\\0".
+// Declared here but defined in gtest.h, so that it has access
+// to the definition of the Message class, required by the ARM
+// compiler.
+template <typename T>
+String StreamableToString(const T& streamable);
+
+// Formats a value to be used in a failure message.
+
+#ifdef GTEST_NEEDS_IS_POINTER_
+
+// These are needed as the Nokia Symbian and IBM XL C/C++ compilers
+// cannot decide between const T& and const T* in a function template.
+// These compilers _can_ decide between class template specializations
+// for T and T*, so a tr1::type_traits-like is_pointer works, and we
+// can overload on that.
+
+// This overload makes sure that all pointers (including
+// those to char or wchar_t) are printed as raw pointers.
+template <typename T>
+inline String FormatValueForFailureMessage(internal::true_type /*dummy*/,
+ T* pointer) {
+ return StreamableToString(static_cast<const void*>(pointer));
+}
+
+template <typename T>
+inline String FormatValueForFailureMessage(internal::false_type /*dummy*/,
+ const T& value) {
+ return StreamableToString(value);
+}
+
+template <typename T>
+inline String FormatForFailureMessage(const T& value) {
+ return FormatValueForFailureMessage(
+ typename internal::is_pointer<T>::type(), value);
+}
+
+#else
+
+// These are needed as the above solution using is_pointer has the
+// limitation that T cannot be a type without external linkage, when
+// compiled using MSVC.
+
+template <typename T>
+inline String FormatForFailureMessage(const T& value) {
+ return StreamableToString(value);
+}
+
+// This overload makes sure that all pointers (including
+// those to char or wchar_t) are printed as raw pointers.
+template <typename T>
+inline String FormatForFailureMessage(T* pointer) {
+ return StreamableToString(static_cast<const void*>(pointer));
+}
+
+#endif // GTEST_NEEDS_IS_POINTER_
+
+// These overloaded versions handle narrow and wide characters.
+GTEST_API_ String FormatForFailureMessage(char ch);
+GTEST_API_ String FormatForFailureMessage(wchar_t wchar);
+
+// When this operand is a const char* or char*, and the other operand
+// is a ::std::string or ::string, we print this operand as a C string
+// rather than a pointer. We do the same for wide strings.
+
+// This internal macro is used to avoid duplicated code.
+#define GTEST_FORMAT_IMPL_(operand2_type, operand1_printer)\
+inline String FormatForComparisonFailureMessage(\
+ operand2_type::value_type* str, const operand2_type& /*operand2*/) {\
+ return operand1_printer(str);\
+}\
+inline String FormatForComparisonFailureMessage(\
+ const operand2_type::value_type* str, const operand2_type& /*operand2*/) {\
+ return operand1_printer(str);\
+}
+
+GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted)
+#if GTEST_HAS_STD_WSTRING
+GTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted)
+#endif // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_STRING
+GTEST_FORMAT_IMPL_(::string, String::ShowCStringQuoted)
+#endif // GTEST_HAS_GLOBAL_STRING
+#if GTEST_HAS_GLOBAL_WSTRING
+GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted)
+#endif // GTEST_HAS_GLOBAL_WSTRING
+
+#undef GTEST_FORMAT_IMPL_
+
+// Constructs and returns the message for an equality assertion
+// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
+//
+// The first four parameters are the expressions used in the assertion
+// and their values, as strings. For example, for ASSERT_EQ(foo, bar)
+// where foo is 5 and bar is 6, we have:
+//
+// expected_expression: "foo"
+// actual_expression: "bar"
+// expected_value: "5"
+// actual_value: "6"
+//
+// The ignoring_case parameter is true iff the assertion is a
+// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will
+// be inserted into the message.
+GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
+ const char* actual_expression,
+ const String& expected_value,
+ const String& actual_value,
+ bool ignoring_case);
+
+// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
+GTEST_API_ String GetBoolAssertionFailureMessage(
+ const AssertionResult& assertion_result,
+ const char* expression_text,
+ const char* actual_predicate_value,
+ const char* expected_predicate_value);
+
+// This template class represents an IEEE floating-point number
+// (either single-precision or double-precision, depending on the
+// template parameters).
+//
+// The purpose of this class is to do more sophisticated number
+// comparison. (Due to round-off error, etc, it's very unlikely that
+// two floating-points will be equal exactly. Hence a naive
+// comparison by the == operation often doesn't work.)
+//
+// Format of IEEE floating-point:
+//
+// The most-significant bit being the leftmost, an IEEE
+// floating-point looks like
+//
+// sign_bit exponent_bits fraction_bits
+//
+// Here, sign_bit is a single bit that designates the sign of the
+// number.
+//
+// For float, there are 8 exponent bits and 23 fraction bits.
+//
+// For double, there are 11 exponent bits and 52 fraction bits.
+//
+// More details can be found at
+// http://en.wikipedia.org/wiki/IEEE_floating-point_standard.
+//
+// Template parameter:
+//
+// RawType: the raw floating-point type (either float or double)
+template <typename RawType>
+class FloatingPoint {
+ public:
+ // Defines the unsigned integer type that has the same size as the
+ // floating point number.
+ typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits;
+
+ // Constants.
+
+ // # of bits in a number.
+ static const size_t kBitCount = 8*sizeof(RawType);
+
+ // # of fraction bits in a number.
+ static const size_t kFractionBitCount =
+ std::numeric_limits<RawType>::digits - 1;
+
+ // # of exponent bits in a number.
+ static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount;
+
+ // The mask for the sign bit.
+ static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);
+
+ // The mask for the fraction bits.
+ static const Bits kFractionBitMask =
+ ~static_cast<Bits>(0) >> (kExponentBitCount + 1);
+
+ // The mask for the exponent bits.
+ static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask);
+
+ // How many ULP's (Units in the Last Place) we want to tolerate when
+ // comparing two numbers. The larger the value, the more error we
+ // allow. A 0 value means that two numbers must be exactly the same
+ // to be considered equal.
+ //
+ // The maximum error of a single floating-point operation is 0.5
+ // units in the last place. On Intel CPU's, all floating-point
+ // calculations are done with 80-bit precision, while double has 64
+ // bits. Therefore, 4 should be enough for ordinary use.
+ //
+ // See the following article for more details on ULP:
+ // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm.
+ static const size_t kMaxUlps = 4;
+
+ // Constructs a FloatingPoint from a raw floating-point number.
+ //
+ // On an Intel CPU, passing a non-normalized NAN (Not a Number)
+ // around may change its bits, although the new value is guaranteed
+ // to be also a NAN. Therefore, don't expect this constructor to
+ // preserve the bits in x when x is a NAN.
+ explicit FloatingPoint(const RawType& x) { u_.value_ = x; }
+
+ // Static methods
+
+ // Reinterprets a bit pattern as a floating-point number.
+ //
+ // This function is needed to test the AlmostEquals() method.
+ static RawType ReinterpretBits(const Bits bits) {
+ FloatingPoint fp(0);
+ fp.u_.bits_ = bits;
+ return fp.u_.value_;
+ }
+
+ // Returns the floating-point number that represent positive infinity.
+ static RawType Infinity() {
+ return ReinterpretBits(kExponentBitMask);
+ }
+
+ // Non-static methods
+
+ // Returns the bits that represents this number.
+ const Bits &bits() const { return u_.bits_; }
+
+ // Returns the exponent bits of this number.
+ Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
+
+ // Returns the fraction bits of this number.
+ Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
+
+ // Returns the sign bit of this number.
+ Bits sign_bit() const { return kSignBitMask & u_.bits_; }
+
+ // Returns true iff this is NAN (not a number).
+ bool is_nan() const {
+ // It's a NAN if the exponent bits are all ones and the fraction
+ // bits are not entirely zeros.
+ return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);
+ }
+
+ // Returns true iff this number is at most kMaxUlps ULP's away from
+ // rhs. In particular, this function:
+ //
+ // - returns false if either number is (or both are) NAN.
+ // - treats really large numbers as almost equal to infinity.
+ // - thinks +0.0 and -0.0 are 0 DLP's apart.
+ bool AlmostEquals(const FloatingPoint& rhs) const {
+ // The IEEE standard says that any comparison operation involving
+ // a NAN must return false.
+ if (is_nan() || rhs.is_nan()) return false;
+
+ return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_)
+ <= kMaxUlps;
+ }
+
+ private:
+ // The data type used to store the actual floating-point number.
+ union FloatingPointUnion {
+ RawType value_; // The raw floating-point number.
+ Bits bits_; // The bits that represent the number.
+ };
+
+ // Converts an integer from the sign-and-magnitude representation to
+ // the biased representation. More precisely, let N be 2 to the
+ // power of (kBitCount - 1), an integer x is represented by the
+ // unsigned number x + N.
+ //
+ // For instance,
+ //
+ // -N + 1 (the most negative number representable using
+ // sign-and-magnitude) is represented by 1;
+ // 0 is represented by N; and
+ // N - 1 (the biggest number representable using
+ // sign-and-magnitude) is represented by 2N - 1.
+ //
+ // Read http://en.wikipedia.org/wiki/Signed_number_representations
+ // for more details on signed number representations.
+ static Bits SignAndMagnitudeToBiased(const Bits &sam) {
+ if (kSignBitMask & sam) {
+ // sam represents a negative number.
+ return ~sam + 1;
+ } else {
+ // sam represents a positive number.
+ return kSignBitMask | sam;
+ }
+ }
+
+ // Given two numbers in the sign-and-magnitude representation,
+ // returns the distance between them as an unsigned number.
+ static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1,
+ const Bits &sam2) {
+ const Bits biased1 = SignAndMagnitudeToBiased(sam1);
+ const Bits biased2 = SignAndMagnitudeToBiased(sam2);
+ return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
+ }
+
+ FloatingPointUnion u_;
+};
+
+// Typedefs the instances of the FloatingPoint template class that we
+// care to use.
+typedef FloatingPoint<float> Float;
+typedef FloatingPoint<double> Double;
+
+// In order to catch the mistake of putting tests that use different
+// test fixture classes in the same test case, we need to assign
+// unique IDs to fixture classes and compare them. The TypeId type is
+// used to hold such IDs. The user should treat TypeId as an opaque
+// type: the only operation allowed on TypeId values is to compare
+// them for equality using the == operator.
+typedef const void* TypeId;
+
+template <typename T>
+class TypeIdHelper {
+ public:
+ // dummy_ must not have a const type. Otherwise an overly eager
+ // compiler (e.g. MSVC 7.1 & 8.0) may try to merge
+ // TypeIdHelper<T>::dummy_ for different Ts as an "optimization".
+ static bool dummy_;
+};
+
+template <typename T>
+bool TypeIdHelper<T>::dummy_ = false;
+
+// GetTypeId<T>() returns the ID of type T. Different values will be
+// returned for different types. Calling the function twice with the
+// same type argument is guaranteed to return the same ID.
+template <typename T>
+TypeId GetTypeId() {
+ // The compiler is required to allocate a different
+ // TypeIdHelper<T>::dummy_ variable for each T used to instantiate
+ // the template. Therefore, the address of dummy_ is guaranteed to
+ // be unique.
+ return &(TypeIdHelper<T>::dummy_);
+}
+
+// Returns the type ID of ::testing::Test. Always call this instead
+// of GetTypeId< ::testing::Test>() to get the type ID of
+// ::testing::Test, as the latter may give the wrong result due to a
+// suspected linker bug when compiling Google Test as a Mac OS X
+// framework.
+GTEST_API_ TypeId GetTestTypeId();
+
+// Defines the abstract factory interface that creates instances
+// of a Test object.
+class TestFactoryBase {
+ public:
+ virtual ~TestFactoryBase() {}
+
+ // Creates a test instance to run. The instance is both created and destroyed
+ // within TestInfoImpl::Run()
+ virtual Test* CreateTest() = 0;
+
+ protected:
+ TestFactoryBase() {}
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase);
+};
+
+// This class provides implementation of TeastFactoryBase interface.
+// It is used in TEST and TEST_F macros.
+template <class TestClass>
+class TestFactoryImpl : public TestFactoryBase {
+ public:
+ virtual Test* CreateTest() { return new TestClass; }
+};
+
+#if GTEST_OS_WINDOWS
+
+// Predicate-formatters for implementing the HRESULT checking macros
+// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}
+// We pass a long instead of HRESULT to avoid causing an
+// include dependency for the HRESULT type.
+GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr,
+ long hr); // NOLINT
+GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,
+ long hr); // NOLINT
+
+#endif // GTEST_OS_WINDOWS
+
+// Formats a source file path and a line number as they would appear
+// in a compiler error message.
+inline String FormatFileLocation(const char* file, int line) {
+ const char* const file_name = file == NULL ? "unknown file" : file;
+ if (line < 0) {
+ return String::Format("%s:", file_name);
+ }
+#ifdef _MSC_VER
+ return String::Format("%s(%d):", file_name, line);
+#else
+ return String::Format("%s:%d:", file_name, line);
+#endif // _MSC_VER
+}
+
+// Types of SetUpTestCase() and TearDownTestCase() functions.
+typedef void (*SetUpTestCaseFunc)();
+typedef void (*TearDownTestCaseFunc)();
+
+// Creates a new TestInfo object and registers it with Google Test;
+// returns the created object.
+//
+// Arguments:
+//
+// test_case_name: name of the test case
+// name: name of the test
+// test_case_comment: a comment on the test case that will be included in
+// the test output
+// comment: a comment on the test that will be included in the
+// test output
+// fixture_class_id: ID of the test fixture class
+// set_up_tc: pointer to the function that sets up the test case
+// tear_down_tc: pointer to the function that tears down the test case
+// factory: pointer to the factory that creates a test object.
+// The newly created TestInfo instance will assume
+// ownership of the factory object.
+GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
+ const char* test_case_name, const char* name,
+ const char* test_case_comment, const char* comment,
+ TypeId fixture_class_id,
+ SetUpTestCaseFunc set_up_tc,
+ TearDownTestCaseFunc tear_down_tc,
+ TestFactoryBase* factory);
+
+// If *pstr starts with the given prefix, modifies *pstr to be right
+// past the prefix and returns true; otherwise leaves *pstr unchanged
+// and returns false. None of pstr, *pstr, and prefix can be NULL.
+bool SkipPrefix(const char* prefix, const char** pstr);
+
+#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// State of the definition of a type-parameterized test case.
+class GTEST_API_ TypedTestCasePState {
+ public:
+ TypedTestCasePState() : registered_(false) {}
+
+ // Adds the given test name to defined_test_names_ and return true
+ // if the test case hasn't been registered; otherwise aborts the
+ // program.
+ bool AddTestName(const char* file, int line, const char* case_name,
+ const char* test_name) {
+ if (registered_) {
+ fprintf(stderr, "%s Test %s must be defined before "
+ "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n",
+ FormatFileLocation(file, line).c_str(), test_name, case_name);
+ fflush(stderr);
+ posix::Abort();
+ }
+ defined_test_names_.insert(test_name);
+ return true;
+ }
+
+ // Verifies that registered_tests match the test names in
+ // defined_test_names_; returns registered_tests if successful, or
+ // aborts the program otherwise.
+ const char* VerifyRegisteredTestNames(
+ const char* file, int line, const char* registered_tests);
+
+ private:
+ bool registered_;
+ ::std::set<const char*> defined_test_names_;
+};
+
+// Skips to the first non-space char after the first comma in 'str';
+// returns NULL if no comma is found in 'str'.
+inline const char* SkipComma(const char* str) {
+ const char* comma = strchr(str, ',');
+ if (comma == NULL) {
+ return NULL;
+ }
+ while (isspace(*(++comma))) {}
+ return comma;
+}
+
+// Returns the prefix of 'str' before the first comma in it; returns
+// the entire string if it contains no comma.
+inline String GetPrefixUntilComma(const char* str) {
+ const char* comma = strchr(str, ',');
+ return comma == NULL ? String(str) : String(str, comma - str);
+}
+
+// TypeParameterizedTest<Fixture, TestSel, Types>::Register()
+// registers a list of type-parameterized tests with Google Test. The
+// return value is insignificant - we just need to return something
+// such that we can call this function in a namespace scope.
+//
+// Implementation note: The GTEST_TEMPLATE_ macro declares a template
+// template parameter. It's defined in gtest-type-util.h.
+template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
+class TypeParameterizedTest {
+ public:
+ // 'index' is the index of the test in the type list 'Types'
+ // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
+ // Types). Valid values for 'index' are [0, N - 1] where N is the
+ // length of Types.
+ static bool Register(const char* prefix, const char* case_name,
+ const char* test_names, int index) {
+ typedef typename Types::Head Type;
+ typedef Fixture<Type> FixtureClass;
+ typedef typename GTEST_BIND_(TestSel, Type) TestClass;
+
+ // First, registers the first type-parameterized test in the type
+ // list.
+ MakeAndRegisterTestInfo(
+ String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/",
+ case_name, index).c_str(),
+ GetPrefixUntilComma(test_names).c_str(),
+ String::Format("TypeParam = %s", GetTypeName<Type>().c_str()).c_str(),
+ "",
+ GetTypeId<FixtureClass>(),
+ TestClass::SetUpTestCase,
+ TestClass::TearDownTestCase,
+ new TestFactoryImpl<TestClass>);
+
+ // Next, recurses (at compile time) with the tail of the type list.
+ return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>
+ ::Register(prefix, case_name, test_names, index + 1);
+ }
+};
+
+// The base case for the compile time recursion.
+template <GTEST_TEMPLATE_ Fixture, class TestSel>
+class TypeParameterizedTest<Fixture, TestSel, Types0> {
+ public:
+ static bool Register(const char* /*prefix*/, const char* /*case_name*/,
+ const char* /*test_names*/, int /*index*/) {
+ return true;
+ }
+};
+
+// TypeParameterizedTestCase<Fixture, Tests, Types>::Register()
+// registers *all combinations* of 'Tests' and 'Types' with Google
+// Test. The return value is insignificant - we just need to return
+// something such that we can call this function in a namespace scope.
+template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
+class TypeParameterizedTestCase {
+ public:
+ static bool Register(const char* prefix, const char* case_name,
+ const char* test_names) {
+ typedef typename Tests::Head Head;
+
+ // First, register the first test in 'Test' for each type in 'Types'.
+ TypeParameterizedTest<Fixture, Head, Types>::Register(
+ prefix, case_name, test_names, 0);
+
+ // Next, recurses (at compile time) with the tail of the test list.
+ return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>
+ ::Register(prefix, case_name, SkipComma(test_names));
+ }
+};
+
+// The base case for the compile time recursion.
+template <GTEST_TEMPLATE_ Fixture, typename Types>
+class TypeParameterizedTestCase<Fixture, Templates0, Types> {
+ public:
+ static bool Register(const char* /*prefix*/, const char* /*case_name*/,
+ const char* /*test_names*/) {
+ return true;
+ }
+};
+
+#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// Returns the current OS stack trace as a String.
+//
+// The maximum number of stack frames to be included is specified by
+// the gtest_stack_trace_depth flag. The skip_count parameter
+// specifies the number of top frames to be skipped, which doesn't
+// count against the number of frames to be included.
+//
+// For example, if Foo() calls Bar(), which in turn calls
+// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
+// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
+GTEST_API_ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test,
+ int skip_count);
+
+// Helpers for suppressing warnings on unreachable code or constant
+// condition.
+
+// Always returns true.
+GTEST_API_ bool AlwaysTrue();
+
+// Always returns false.
+inline bool AlwaysFalse() { return !AlwaysTrue(); }
+
+// A simple Linear Congruential Generator for generating random
+// numbers with a uniform distribution. Unlike rand() and srand(), it
+// doesn't use global state (and therefore can't interfere with user
+// code). Unlike rand_r(), it's portable. An LCG isn't very random,
+// but it's good enough for our purposes.
+class GTEST_API_ Random {
+ public:
+ static const UInt32 kMaxRange = 1u << 31;
+
+ explicit Random(UInt32 seed) : state_(seed) {}
+
+ void Reseed(UInt32 seed) { state_ = seed; }
+
+ // Generates a random number from [0, range). Crashes if 'range' is
+ // 0 or greater than kMaxRange.
+ UInt32 Generate(UInt32 range);
+
+ private:
+ UInt32 state_;
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);
+};
+
+} // namespace internal
+} // namespace testing
+
+#define GTEST_MESSAGE_(message, result_type) \
+ ::testing::internal::AssertHelper(result_type, __FILE__, __LINE__, message) \
+ = ::testing::Message()
+
+#define GTEST_FATAL_FAILURE_(message) \
+ return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)
+
+#define GTEST_NONFATAL_FAILURE_(message) \
+ GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
+
+#define GTEST_SUCCESS_(message) \
+ GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)
+
+// Suppresses MSVC warnings 4072 (unreachable code) for the code following
+// statement if it returns or throws (or doesn't return or throw in some
+// situations).
+#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
+ if (::testing::internal::AlwaysTrue()) { statement; }
+
+#define GTEST_TEST_THROW_(statement, expected_exception, fail) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (const char* gtest_msg = "") { \
+ bool gtest_caught_expected = false; \
+ try { \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+ } \
+ catch (expected_exception const&) { \
+ gtest_caught_expected = true; \
+ } \
+ catch (...) { \
+ gtest_msg = "Expected: " #statement " throws an exception of type " \
+ #expected_exception ".\n Actual: it throws a different " \
+ "type."; \
+ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
+ } \
+ if (!gtest_caught_expected) { \
+ gtest_msg = "Expected: " #statement " throws an exception of type " \
+ #expected_exception ".\n Actual: it throws nothing."; \
+ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
+ } \
+ } else \
+ GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
+ fail(gtest_msg)
+
+#define GTEST_TEST_NO_THROW_(statement, fail) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (const char* gtest_msg = "") { \
+ try { \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+ } \
+ catch (...) { \
+ gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \
+ " Actual: it throws."; \
+ goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
+ } \
+ } else \
+ GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \
+ fail(gtest_msg)
+
+#define GTEST_TEST_ANY_THROW_(statement, fail) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (const char* gtest_msg = "") { \
+ bool gtest_caught_any = false; \
+ try { \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+ } \
+ catch (...) { \
+ gtest_caught_any = true; \
+ } \
+ if (!gtest_caught_any) { \
+ gtest_msg = "Expected: " #statement " throws an exception.\n" \
+ " Actual: it doesn't."; \
+ goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \
+ } \
+ } else \
+ GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \
+ fail(gtest_msg)
+
+
+// Implements Boolean test assertions such as EXPECT_TRUE. expression can be
+// either a boolean expression or an AssertionResult. text is a textual
+// represenation of expression as it was passed into the EXPECT_TRUE.
+#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (const ::testing::AssertionResult gtest_ar_ = \
+ ::testing::AssertionResult(expression)) \
+ ; \
+ else \
+ fail(::testing::internal::GetBoolAssertionFailureMessage(\
+ gtest_ar_, text, #actual, #expected).c_str())
+
+#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (const char* gtest_msg = "") { \
+ ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+ if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \
+ gtest_msg = "Expected: " #statement " doesn't generate new fatal " \
+ "failures in the current thread.\n" \
+ " Actual: it does."; \
+ goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \
+ } \
+ } else \
+ GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \
+ fail(gtest_msg)
+
+// Expands to the name of the class that implements the given test.
+#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
+ test_case_name##_##test_name##_Test
+
+// Helper macro for defining tests.
+#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
+class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
+ public:\
+ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
+ private:\
+ virtual void TestBody();\
+ static ::testing::TestInfo* const test_info_;\
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(\
+ GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
+};\
+\
+::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
+ ::test_info_ =\
+ ::testing::internal::MakeAndRegisterTestInfo(\
+ #test_case_name, #test_name, "", "", \
+ (parent_id), \
+ parent_class::SetUpTestCase, \
+ parent_class::TearDownTestCase, \
+ new ::testing::internal::TestFactoryImpl<\
+ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
+void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
+
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// 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: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines the public API for death tests. It is
+// #included by gtest.h so a user doesn't need to include this
+// directly.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
+
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// 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.
+//
+// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines internal utilities needed for implementing
+// death tests. They are subject to change without notice.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
+
+
+namespace testing {
+namespace internal {
+
+GTEST_DECLARE_string_(internal_run_death_test);
+
+// Names of the flags (needed for parsing Google Test flags).
+const char kDeathTestStyleFlag[] = "death_test_style";
+const char kDeathTestUseFork[] = "death_test_use_fork";
+const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
+
+#if GTEST_HAS_DEATH_TEST
+
+// DeathTest is a class that hides much of the complexity of the
+// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method
+// returns a concrete class that depends on the prevailing death test
+// style, as defined by the --gtest_death_test_style and/or
+// --gtest_internal_run_death_test flags.
+
+// In describing the results of death tests, these terms are used with
+// the corresponding definitions:
+//
+// exit status: The integer exit information in the format specified
+// by wait(2)
+// exit code: The integer code passed to exit(3), _exit(2), or
+// returned from main()
+class GTEST_API_ DeathTest {
+ public:
+ // Create returns false if there was an error determining the
+ // appropriate action to take for the current death test; for example,
+ // if the gtest_death_test_style flag is set to an invalid value.
+ // The LastMessage method will return a more detailed message in that
+ // case. Otherwise, the DeathTest pointer pointed to by the "test"
+ // argument is set. If the death test should be skipped, the pointer
+ // is set to NULL; otherwise, it is set to the address of a new concrete
+ // DeathTest object that controls the execution of the current test.
+ static bool Create(const char* statement, const RE* regex,
+ const char* file, int line, DeathTest** test);
+ DeathTest();
+ virtual ~DeathTest() { }
+
+ // A helper class that aborts a death test when it's deleted.
+ class ReturnSentinel {
+ public:
+ explicit ReturnSentinel(DeathTest* test) : test_(test) { }
+ ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
+ private:
+ DeathTest* const test_;
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
+ } GTEST_ATTRIBUTE_UNUSED_;
+
+ // An enumeration of possible roles that may be taken when a death
+ // test is encountered. EXECUTE means that the death test logic should
+ // be executed immediately. OVERSEE means that the program should prepare
+ // the appropriate environment for a child process to execute the death
+ // test, then wait for it to complete.
+ enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
+
+ // An enumeration of the two reasons that a test might be aborted.
+ enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_DID_NOT_DIE };
+
+ // Assumes one of the above roles.
+ virtual TestRole AssumeRole() = 0;
+
+ // Waits for the death test to finish and returns its status.
+ virtual int Wait() = 0;
+
+ // Returns true if the death test passed; that is, the test process
+ // exited during the test, its exit status matches a user-supplied
+ // predicate, and its stderr output matches a user-supplied regular
+ // expression.
+ // The user-supplied predicate may be a macro expression rather
+ // than a function pointer or functor, or else Wait and Passed could
+ // be combined.
+ virtual bool Passed(bool exit_status_ok) = 0;
+
+ // Signals that the death test did not die as expected.
+ virtual void Abort(AbortReason reason) = 0;
+
+ // Returns a human-readable outcome message regarding the outcome of
+ // the last death test.
+ static const char* LastMessage();
+
+ static void set_last_death_test_message(const String& message);
+
+ private:
+ // A string containing a description of the outcome of the last death test.
+ static String last_death_test_message_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
+};
+
+// Factory interface for death tests. May be mocked out for testing.
+class DeathTestFactory {
+ public:
+ virtual ~DeathTestFactory() { }
+ virtual bool Create(const char* statement, const RE* regex,
+ const char* file, int line, DeathTest** test) = 0;
+};
+
+// A concrete DeathTestFactory implementation for normal use.
+class DefaultDeathTestFactory : public DeathTestFactory {
+ public:
+ virtual bool Create(const char* statement, const RE* regex,
+ const char* file, int line, DeathTest** test);
+};
+
+// Returns true if exit_status describes a process that was terminated
+// by a signal, or exited normally with a nonzero exit code.
+GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
+
+// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
+// ASSERT_EXIT*, and EXPECT_EXIT*.
+#define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (::testing::internal::AlwaysTrue()) { \
+ const ::testing::internal::RE& gtest_regex = (regex); \
+ ::testing::internal::DeathTest* gtest_dt; \
+ if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \
+ __FILE__, __LINE__, &gtest_dt)) { \
+ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
+ } \
+ if (gtest_dt != NULL) { \
+ ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
+ gtest_dt_ptr(gtest_dt); \
+ switch (gtest_dt->AssumeRole()) { \
+ case ::testing::internal::DeathTest::OVERSEE_TEST: \
+ if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
+ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
+ } \
+ break; \
+ case ::testing::internal::DeathTest::EXECUTE_TEST: { \
+ ::testing::internal::DeathTest::ReturnSentinel \
+ gtest_sentinel(gtest_dt); \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+ gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
+ break; \
+ } \
+ } \
+ } \
+ } else \
+ GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
+ fail(::testing::internal::DeathTest::LastMessage())
+// The symbol "fail" here expands to something into which a message
+// can be streamed.
+
+// A class representing the parsed contents of the
+// --gtest_internal_run_death_test flag, as it existed when
+// RUN_ALL_TESTS was called.
+class InternalRunDeathTestFlag {
+ public:
+ InternalRunDeathTestFlag(const String& a_file,
+ int a_line,
+ int an_index,
+ int a_write_fd)
+ : file_(a_file), line_(a_line), index_(an_index),
+ write_fd_(a_write_fd) {}
+
+ ~InternalRunDeathTestFlag() {
+ if (write_fd_ >= 0)
+ posix::Close(write_fd_);
+ }
+
+ String file() const { return file_; }
+ int line() const { return line_; }
+ int index() const { return index_; }
+ int write_fd() const { return write_fd_; }
+
+ private:
+ String file_;
+ int line_;
+ int index_;
+ int write_fd_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
+};
+
+// Returns a newly created InternalRunDeathTestFlag object with fields
+// initialized from the GTEST_FLAG(internal_run_death_test) flag if
+// the flag is specified; otherwise returns NULL.
+InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
+
+#else // GTEST_HAS_DEATH_TEST
+
+// This macro is used for implementing macros such as
+// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
+// death tests are not supported. Those macros must compile on such systems
+// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
+// systems that support death tests. This allows one to write such a macro
+// on a system that does not support death tests and be sure that it will
+// compile on a death-test supporting system.
+//
+// Parameters:
+// statement - A statement that a macro such as EXPECT_DEATH would test
+// for program termination. This macro has to make sure this
+// statement is compiled but not executed, to ensure that
+// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
+// parameter iff EXPECT_DEATH compiles with it.
+// regex - A regex that a macro such as EXPECT_DEATH would use to test
+// the output of statement. This parameter has to be
+// compiled but not evaluated by this macro, to ensure that
+// this macro only accepts expressions that a macro such as
+// EXPECT_DEATH would accept.
+// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
+// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
+// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
+// compile inside functions where ASSERT_DEATH doesn't
+// compile.
+//
+// The branch that has an always false condition is used to ensure that
+// statement and regex are compiled (and thus syntactically correct) but
+// never executed. The unreachable code macro protects the terminator
+// statement from generating an 'unreachable code' warning in case
+// statement unconditionally returns or throws. The Message constructor at
+// the end allows the syntax of streaming additional messages into the
+// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
+#define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (::testing::internal::AlwaysTrue()) { \
+ GTEST_LOG_(WARNING) \
+ << "Death tests are not supported on this platform.\n" \
+ << "Statement '" #statement "' cannot be verified."; \
+ } else if (::testing::internal::AlwaysFalse()) { \
+ ::testing::internal::RE::PartialMatch(".*", (regex)); \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+ terminator; \
+ } else \
+ ::testing::Message()
+
+#endif // GTEST_HAS_DEATH_TEST
+
+} // namespace internal
+} // namespace testing
+
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
+
+namespace testing {
+
+// This flag controls the style of death tests. Valid values are "threadsafe",
+// meaning that the death test child process will re-execute the test binary
+// from the start, running only a single death test, or "fast",
+// meaning that the child process will execute the test logic immediately
+// after forking.
+GTEST_DECLARE_string_(death_test_style);
+
+#if GTEST_HAS_DEATH_TEST
+
+// The following macros are useful for writing death tests.
+
+// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
+// executed:
+//
+// 1. It generates a warning if there is more than one active
+// thread. This is because it's safe to fork() or clone() only
+// when there is a single thread.
+//
+// 2. The parent process clone()s a sub-process and runs the death
+// test in it; the sub-process exits with code 0 at the end of the
+// death test, if it hasn't exited already.
+//
+// 3. The parent process waits for the sub-process to terminate.
+//
+// 4. The parent process checks the exit code and error message of
+// the sub-process.
+//
+// Examples:
+//
+// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
+// for (int i = 0; i < 5; i++) {
+// EXPECT_DEATH(server.ProcessRequest(i),
+// "Invalid request .* in ProcessRequest()")
+// << "Failed to die on request " << i);
+// }
+//
+// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
+//
+// bool KilledBySIGHUP(int exit_code) {
+// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
+// }
+//
+// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
+//
+// On the regular expressions used in death tests:
+//
+// On POSIX-compliant systems (*nix), we use the <regex.h> library,
+// which uses the POSIX extended regex syntax.
+//
+// On other platforms (e.g. Windows), we only support a simple regex
+// syntax implemented as part of Google Test. This limited
+// implementation should be enough most of the time when writing
+// death tests; though it lacks many features you can find in PCRE
+// or POSIX extended regex syntax. For example, we don't support
+// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
+// repetition count ("x{5,7}"), among others.
+//
+// Below is the syntax that we do support. We chose it to be a
+// subset of both PCRE and POSIX extended regex, so it's easy to
+// learn wherever you come from. In the following: 'A' denotes a
+// literal character, period (.), or a single \\ escape sequence;
+// 'x' and 'y' denote regular expressions; 'm' and 'n' are for
+// natural numbers.
+//
+// c matches any literal character c
+// \\d matches any decimal digit
+// \\D matches any character that's not a decimal digit
+// \\f matches \f
+// \\n matches \n
+// \\r matches \r
+// \\s matches any ASCII whitespace, including \n
+// \\S matches any character that's not a whitespace
+// \\t matches \t
+// \\v matches \v
+// \\w matches any letter, _, or decimal digit
+// \\W matches any character that \\w doesn't match
+// \\c matches any literal character c, which must be a punctuation
+// . matches any single character except \n
+// A? matches 0 or 1 occurrences of A
+// A* matches 0 or many occurrences of A
+// A+ matches 1 or many occurrences of A
+// ^ matches the beginning of a string (not that of each line)
+// $ matches the end of a string (not that of each line)
+// xy matches x followed by y
+//
+// If you accidentally use PCRE or POSIX extended regex features
+// not implemented by us, you will get a run-time failure. In that
+// case, please try to rewrite your regular expression within the
+// above syntax.
+//
+// This implementation is *not* meant to be as highly tuned or robust
+// as a compiled regex library, but should perform well enough for a
+// death test, which already incurs significant overhead by launching
+// a child process.
+//
+// Known caveats:
+//
+// A "threadsafe" style death test obtains the path to the test
+// program from argv[0] and re-executes it in the sub-process. For
+// simplicity, the current implementation doesn't search the PATH
+// when launching the sub-process. This means that the user must
+// invoke the test program via a path that contains at least one
+// path separator (e.g. path/to/foo_test and
+// /absolute/path/to/bar_test are fine, but foo_test is not). This
+// is rarely a problem as people usually don't put the test binary
+// directory in PATH.
+//
+// TODO(wan@google.com): make thread-safe death tests search the PATH.
+
+// Asserts that a given statement causes the program to exit, with an
+// integer exit status that satisfies predicate, and emitting error output
+// that matches regex.
+#define ASSERT_EXIT(statement, predicate, regex) \
+ GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
+
+// Like ASSERT_EXIT, but continues on to successive tests in the
+// test case, if any:
+#define EXPECT_EXIT(statement, predicate, regex) \
+ GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
+
+// Asserts that a given statement causes the program to exit, either by
+// explicitly exiting with a nonzero exit code or being killed by a
+// signal, and emitting error output that matches regex.
+#define ASSERT_DEATH(statement, regex) \
+ ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
+
+// Like ASSERT_DEATH, but continues on to successive tests in the
+// test case, if any:
+#define EXPECT_DEATH(statement, regex) \
+ EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
+
+// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
+
+// Tests that an exit code describes a normal exit with a given exit code.
+class GTEST_API_ ExitedWithCode {
+ public:
+ explicit ExitedWithCode(int exit_code);
+ bool operator()(int exit_status) const;
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ExitedWithCode& other);
+
+ const int exit_code_;
+};
+
+#if !GTEST_OS_WINDOWS
+// Tests that an exit code describes an exit due to termination by a
+// given signal.
+class GTEST_API_ KilledBySignal {
+ public:
+ explicit KilledBySignal(int signum);
+ bool operator()(int exit_status) const;
+ private:
+ const int signum_;
+};
+#endif // !GTEST_OS_WINDOWS
+
+// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
+// The death testing framework causes this to have interesting semantics,
+// since the sideeffects of the call are only visible in opt mode, and not
+// in debug mode.
+//
+// In practice, this can be used to test functions that utilize the
+// LOG(DFATAL) macro using the following style:
+//
+// int DieInDebugOr12(int* sideeffect) {
+// if (sideeffect) {
+// *sideeffect = 12;
+// }
+// LOG(DFATAL) << "death";
+// return 12;
+// }
+//
+// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
+// int sideeffect = 0;
+// // Only asserts in dbg.
+// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
+//
+// #ifdef NDEBUG
+// // opt-mode has sideeffect visible.
+// EXPECT_EQ(12, sideeffect);
+// #else
+// // dbg-mode no visible sideeffect.
+// EXPECT_EQ(0, sideeffect);
+// #endif
+// }
+//
+// This will assert that DieInDebugReturn12InOpt() crashes in debug
+// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
+// appropriate fallback value (12 in this case) in opt mode. If you
+// need to test that a function has appropriate side-effects in opt
+// mode, include assertions against the side-effects. A general
+// pattern for this is:
+//
+// EXPECT_DEBUG_DEATH({
+// // Side-effects here will have an effect after this statement in
+// // opt mode, but none in debug mode.
+// EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
+// }, "death");
+//
+#ifdef NDEBUG
+
+#define EXPECT_DEBUG_DEATH(statement, regex) \
+ do { statement; } while (::testing::internal::AlwaysFalse())
+
+#define ASSERT_DEBUG_DEATH(statement, regex) \
+ do { statement; } while (::testing::internal::AlwaysFalse())
+
+#else
+
+#define EXPECT_DEBUG_DEATH(statement, regex) \
+ EXPECT_DEATH(statement, regex)
+
+#define ASSERT_DEBUG_DEATH(statement, regex) \
+ ASSERT_DEATH(statement, regex)
+
+#endif // NDEBUG for EXPECT_DEBUG_DEATH
+#endif // GTEST_HAS_DEATH_TEST
+
+// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
+// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
+// death tests are supported; otherwise they just issue a warning. This is
+// useful when you are combining death test assertions with normal test
+// assertions in one test.
+#if GTEST_HAS_DEATH_TEST
+#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
+ EXPECT_DEATH(statement, regex)
+#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
+ ASSERT_DEATH(statement, regex)
+#else
+#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
+ GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
+#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
+ GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
+#endif
+
+} // namespace testing
+
+#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// 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: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines the Message class.
+//
+// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
+// leave some internal implementation details in this header file.
+// They are clearly marked by comments like this:
+//
+// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+//
+// Such code is NOT meant to be used by a user directly, and is subject
+// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
+// program!
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
+#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
+
+#include <limits>
+
+
+namespace testing {
+
+// The Message class works like an ostream repeater.
+//
+// Typical usage:
+//
+// 1. You stream a bunch of values to a Message object.
+// It will remember the text in a StrStream.
+// 2. Then you stream the Message object to an ostream.
+// This causes the text in the Message to be streamed
+// to the ostream.
+//
+// For example;
+//
+// testing::Message foo;
+// foo << 1 << " != " << 2;
+// std::cout << foo;
+//
+// will print "1 != 2".
+//
+// Message is not intended to be inherited from. In particular, its
+// destructor is not virtual.
+//
+// Note that StrStream behaves differently in gcc and in MSVC. You
+// can stream a NULL char pointer to it in the former, but not in the
+// latter (it causes an access violation if you do). The Message
+// class hides this difference by treating a NULL char pointer as
+// "(null)".
+class GTEST_API_ Message {
+ private:
+ // The type of basic IO manipulators (endl, ends, and flush) for
+ // narrow streams.
+ typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
+
+ public:
+ // Constructs an empty Message.
+ // We allocate the StrStream separately because it otherwise each use of
+ // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's
+ // stack frame leading to huge stack frames in some cases; gcc does not reuse
+ // the stack space.
+ Message() : ss_(new internal::StrStream) {
+ // By default, we want there to be enough precision when printing
+ // a double to a Message.
+ *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);
+ }
+
+ // Copy constructor.
+ Message(const Message& msg) : ss_(new internal::StrStream) { // NOLINT
+ *ss_ << msg.GetString();
+ }
+
+ // Constructs a Message from a C-string.
+ explicit Message(const char* str) : ss_(new internal::StrStream) {
+ *ss_ << str;
+ }
+
+ ~Message() { delete ss_; }
+#if GTEST_OS_SYMBIAN
+ // Streams a value (either a pointer or not) to this object.
+ template <typename T>
+ inline Message& operator <<(const T& value) {
+ StreamHelper(typename internal::is_pointer<T>::type(), value);
+ return *this;
+ }
+#else
+ // Streams a non-pointer value to this object.
+ template <typename T>
+ inline Message& operator <<(const T& val) {
+ ::GTestStreamToHelper(ss_, val);
+ return *this;
+ }
+
+ // Streams a pointer value to this object.
+ //
+ // This function is an overload of the previous one. When you
+ // stream a pointer to a Message, this definition will be used as it
+ // is more specialized. (The C++ Standard, section
+ // [temp.func.order].) If you stream a non-pointer, then the
+ // previous definition will be used.
+ //
+ // The reason for this overload is that streaming a NULL pointer to
+ // ostream is undefined behavior. Depending on the compiler, you
+ // may get "0", "(nil)", "(null)", or an access violation. To
+ // ensure consistent result across compilers, we always treat NULL
+ // as "(null)".
+ template <typename T>
+ inline Message& operator <<(T* const& pointer) { // NOLINT
+ if (pointer == NULL) {
+ *ss_ << "(null)";
+ } else {
+ ::GTestStreamToHelper(ss_, pointer);
+ }
+ return *this;
+ }
+#endif // GTEST_OS_SYMBIAN
+
+ // Since the basic IO manipulators are overloaded for both narrow
+ // and wide streams, we have to provide this specialized definition
+ // of operator <<, even though its body is the same as the
+ // templatized version above. Without this definition, streaming
+ // endl or other basic IO manipulators to Message will confuse the
+ // compiler.
+ Message& operator <<(BasicNarrowIoManip val) {
+ *ss_ << val;
+ return *this;
+ }
+
+ // Instead of 1/0, we want to see true/false for bool values.
+ Message& operator <<(bool b) {
+ return *this << (b ? "true" : "false");
+ }
+
+ // These two overloads allow streaming a wide C string to a Message
+ // using the UTF-8 encoding.
+ Message& operator <<(const wchar_t* wide_c_str) {
+ return *this << internal::String::ShowWideCString(wide_c_str);
+ }
+ Message& operator <<(wchar_t* wide_c_str) {
+ return *this << internal::String::ShowWideCString(wide_c_str);
+ }
+
+#if GTEST_HAS_STD_WSTRING
+ // Converts the given wide string to a narrow string using the UTF-8
+ // encoding, and streams the result to this Message object.
+ Message& operator <<(const ::std::wstring& wstr);
+#endif // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+ // Converts the given wide string to a narrow string using the UTF-8
+ // encoding, and streams the result to this Message object.
+ Message& operator <<(const ::wstring& wstr);
+#endif // GTEST_HAS_GLOBAL_WSTRING
+
+ // Gets the text streamed to this object so far as a String.
+ // Each '\0' character in the buffer is replaced with "\\0".
+ //
+ // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+ internal::String GetString() const {
+ return internal::StrStreamToString(ss_);
+ }
+
+ private:
+#if GTEST_OS_SYMBIAN
+ // These are needed as the Nokia Symbian Compiler cannot decide between
+ // const T& and const T* in a function template. The Nokia compiler _can_
+ // decide between class template specializations for T and T*, so a
+ // tr1::type_traits-like is_pointer works, and we can overload on that.
+ template <typename T>
+ inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) {
+ if (pointer == NULL) {
+ *ss_ << "(null)";
+ } else {
+ ::GTestStreamToHelper(ss_, pointer);
+ }
+ }
+ template <typename T>
+ inline void StreamHelper(internal::false_type /*dummy*/, const T& value) {
+ ::GTestStreamToHelper(ss_, value);
+ }
+#endif // GTEST_OS_SYMBIAN
+
+ // We'll hold the text streamed to this object here.
+ internal::StrStream* const ss_;
+
+ // We declare (but don't implement) this to prevent the compiler
+ // from implementing the assignment operator.
+ void operator=(const Message&);
+};
+
+// Streams a Message to an ostream.
+inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
+ return os << sb.GetString();
+}
+
+} // namespace testing
+
+#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
+// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
+
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// 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.
+//
+// Authors: vladl@google.com (Vlad Losev)
+//
+// Macros and functions for implementing parameterized tests
+// in Google C++ Testing Framework (Google Test)
+//
+// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
+//
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+
+
+// Value-parameterized tests allow you to test your code with different
+// parameters without writing multiple copies of the same test.
+//
+// Here is how you use value-parameterized tests:
+
+#if 0
+
+// To write value-parameterized tests, first you should define a fixture
+// class. It must be derived from testing::TestWithParam<T>, where T is
+// the type of your parameter values. TestWithParam<T> is itself derived
+// from testing::Test. T can be any copyable type. If it's a raw pointer,
+// you are responsible for managing the lifespan of the pointed values.
+
+class FooTest : public ::testing::TestWithParam<const char*> {
+ // You can implement all the usual class fixture members here.
+};
+
+// Then, use the TEST_P macro to define as many parameterized tests
+// for this fixture as you want. The _P suffix is for "parameterized"
+// or "pattern", whichever you prefer to think.
+
+TEST_P(FooTest, DoesBlah) {
+ // Inside a test, access the test parameter with the GetParam() method
+ // of the TestWithParam<T> class:
+ EXPECT_TRUE(foo.Blah(GetParam()));
+ ...
+}
+
+TEST_P(FooTest, HasBlahBlah) {
+ ...
+}
+
+// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
+// case with any set of parameters you want. Google Test defines a number
+// of functions for generating test parameters. They return what we call
+// (surprise!) parameter generators. Here is a summary of them, which
+// are all in the testing namespace:
+//
+//
+// Range(begin, end [, step]) - Yields values {begin, begin+step,
+// begin+step+step, ...}. The values do not
+// include end. step defaults to 1.
+// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
+// ValuesIn(container) - Yields values from a C-style array, an STL
+// ValuesIn(begin,end) container, or an iterator range [begin, end).
+// Bool() - Yields sequence {false, true}.
+// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
+// for the math savvy) of the values generated
+// by the N generators.
+//
+// For more details, see comments at the definitions of these functions below
+// in this file.
+//
+// The following statement will instantiate tests from the FooTest test case
+// each with parameter values "meeny", "miny", and "moe".
+
+INSTANTIATE_TEST_CASE_P(InstantiationName,
+ FooTest,
+ Values("meeny", "miny", "moe"));
+
+// To distinguish different instances of the pattern, (yes, you
+// can instantiate it more then once) the first argument to the
+// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
+// actual test case name. Remember to pick unique prefixes for different
+// instantiations. The tests from the instantiation above will have
+// these names:
+//
+// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
+// * InstantiationName/FooTest.DoesBlah/1 for "miny"
+// * InstantiationName/FooTest.DoesBlah/2 for "moe"
+// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
+// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
+// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
+//
+// You can use these names in --gtest_filter.
+//
+// This statement will instantiate all tests from FooTest again, each
+// with parameter values "cat" and "dog":
+
+const char* pets[] = {"cat", "dog"};
+INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
+
+// The tests from the instantiation above will have these names:
+//
+// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
+// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
+// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
+// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
+//
+// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
+// in the given test case, whether their definitions come before or
+// AFTER the INSTANTIATE_TEST_CASE_P statement.
+//
+// Please also note that generator expressions (including parameters to the
+// generators) are evaluated in InitGoogleTest(), after main() has started.
+// This allows the user on one hand, to adjust generator parameters in order
+// to dynamically determine a set of tests to run and on the other hand,
+// give the user a chance to inspect the generated tests with Google Test
+// reflection API before RUN_ALL_TESTS() is executed.
+//
+// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
+// for more examples.
+//
+// In the future, we plan to publish the API for defining new parameter
+// generators. But for now this interface remains part of the internal
+// implementation and is subject to change.
+
+#endif // 0
+
+
+#if !GTEST_OS_SYMBIAN
+#include <utility>
+#endif
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*. Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// 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: vladl@google.com (Vlad Losev)
+
+// Type and function utilities for implementing parameterized tests.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+
+#include <iterator>
+#include <utility>
+#include <vector>
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*. Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+// Copyright 2003 Google Inc.
+// All rights reserved.
+//
+// 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.
+//
+// Authors: Dan Egnor (egnor@google.com)
+//
+// A "smart" pointer type with reference tracking. Every pointer to a
+// particular object is kept on a circular linked list. When the last pointer
+// to an object is destroyed or reassigned, the object is deleted.
+//
+// Used properly, this deletes the object when the last reference goes away.
+// There are several caveats:
+// - Like all reference counting schemes, cycles lead to leaks.
+// - Each smart pointer is actually two pointers (8 bytes instead of 4).
+// - Every time a pointer is assigned, the entire list of pointers to that
+// object is traversed. This class is therefore NOT SUITABLE when there
+// will often be more than two or three pointers to a particular object.
+// - References are only tracked as long as linked_ptr<> objects are copied.
+// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
+// will happen (double deletion).
+//
+// A good use of this class is storing object references in STL containers.
+// You can safely put linked_ptr<> in a vector<>.
+// Other uses may not be as good.
+//
+// Note: If you use an incomplete type with linked_ptr<>, the class
+// *containing* linked_ptr<> must have a constructor and destructor (even
+// if they do nothing!).
+//
+// Bill Gibbons suggested we use something like this.
+//
+// Thread Safety:
+// Unlike other linked_ptr implementations, in this implementation
+// a linked_ptr object is thread-safe in the sense that:
+// - it's safe to copy linked_ptr objects concurrently,
+// - it's safe to copy *from* a linked_ptr and read its underlying
+// raw pointer (e.g. via get()) concurrently, and
+// - it's safe to write to two linked_ptrs that point to the same
+// shared object concurrently.
+// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
+// confusion with normal linked_ptr.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
+
+#include <stdlib.h>
+#include <assert.h>
+
+
+namespace testing {
+namespace internal {
+
+// Protects copying of all linked_ptr objects.
+GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
+
+// This is used internally by all instances of linked_ptr<>. It needs to be
+// a non-template class because different types of linked_ptr<> can refer to
+// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
+// So, it needs to be possible for different types of linked_ptr to participate
+// in the same circular linked list, so we need a single class type here.
+//
+// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
+class linked_ptr_internal {
+ public:
+ // Create a new circle that includes only this instance.
+ void join_new() {
+ next_ = this;
+ }
+
+ // Many linked_ptr operations may change p.link_ for some linked_ptr
+ // variable p in the same circle as this object. Therefore we need
+ // to prevent two such operations from occurring concurrently.
+ //
+ // Note that different types of linked_ptr objects can coexist in a
+ // circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
+ // linked_ptr<Derived2>). Therefore we must use a single mutex to
+ // protect all linked_ptr objects. This can create serious
+ // contention in production code, but is acceptable in a testing
+ // framework.
+
+ // Join an existing circle.
+ // L < g_linked_ptr_mutex
+ void join(linked_ptr_internal const* ptr) {
+ MutexLock lock(&g_linked_ptr_mutex);
+
+ linked_ptr_internal const* p = ptr;
+ while (p->next_ != ptr) p = p->next_;
+ p->next_ = this;
+ next_ = ptr;
+ }
+
+ // Leave whatever circle we're part of. Returns true if we were the
+ // last member of the circle. Once this is done, you can join() another.
+ // L < g_linked_ptr_mutex
+ bool depart() {
+ MutexLock lock(&g_linked_ptr_mutex);
+
+ if (next_ == this) return true;
+ linked_ptr_internal const* p = next_;
+ while (p->next_ != this) p = p->next_;
+ p->next_ = next_;
+ return false;
+ }
+
+ private:
+ mutable linked_ptr_internal const* next_;
+};
+
+template <typename T>
+class linked_ptr {
+ public:
+ typedef T element_type;
+
+ // Take over ownership of a raw pointer. This should happen as soon as
+ // possible after the object is created.
+ explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
+ ~linked_ptr() { depart(); }
+
+ // Copy an existing linked_ptr<>, adding ourselves to the list of references.
+ template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
+ linked_ptr(linked_ptr const& ptr) { // NOLINT
+ assert(&ptr != this);
+ copy(&ptr);
+ }
+
+ // Assignment releases the old value and acquires the new.
+ template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
+ depart();
+ copy(&ptr);
+ return *this;
+ }
+
+ linked_ptr& operator=(linked_ptr const& ptr) {
+ if (&ptr != this) {
+ depart();
+ copy(&ptr);
+ }
+ return *this;
+ }
+
+ // Smart pointer members.
+ void reset(T* ptr = NULL) {
+ depart();
+ capture(ptr);
+ }
+ T* get() const { return value_; }
+ T* operator->() const { return value_; }
+ T& operator*() const { return *value_; }
+ // Release ownership of the pointed object and returns it.
+ // Sole ownership by this linked_ptr object is required.
+ T* release() {
+ bool last = link_.depart();
+ assert(last);
+ T* v = value_;
+ value_ = NULL;
+ return v;
+ }
+
+ bool operator==(T* p) const { return value_ == p; }
+ bool operator!=(T* p) const { return value_ != p; }
+ template <typename U>
+ bool operator==(linked_ptr<U> const& ptr) const {
+ return value_ == ptr.get();
+ }
+ template <typename U>
+ bool operator!=(linked_ptr<U> const& ptr) const {
+ return value_ != ptr.get();
+ }
+
+ private:
+ template <typename U>
+ friend class linked_ptr;
+
+ T* value_;
+ linked_ptr_internal link_;
+
+ void depart() {
+ if (link_.depart()) delete value_;
+ }
+
+ void capture(T* ptr) {
+ value_ = ptr;
+ link_.join_new();
+ }
+
+ template <typename U> void copy(linked_ptr<U> const* ptr) {
+ value_ = ptr->get();
+ if (value_)
+ link_.join(&ptr->link_);
+ else
+ link_.join_new();
+ }
+};
+
+template<typename T> inline
+bool operator==(T* ptr, const linked_ptr<T>& x) {
+ return ptr == x.get();
+}
+
+template<typename T> inline
+bool operator!=(T* ptr, const linked_ptr<T>& x) {
+ return ptr != x.get();
+}
+
+// A function to convert T* into linked_ptr<T>
+// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
+// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
+template <typename T>
+linked_ptr<T> make_linked_ptr(T* ptr) {
+ return linked_ptr<T>(ptr);
+}
+
+} // namespace internal
+} // namespace testing
+
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+namespace internal {
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Outputs a message explaining invalid registration of different
+// fixture class for the same test case. This may happen when
+// TEST_P macro is used to define two tests with the same name
+// but in different namespaces.
+GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
+ const char* file, int line);
+
+template <typename> class ParamGeneratorInterface;
+template <typename> class ParamGenerator;
+
+// Interface for iterating over elements provided by an implementation
+// of ParamGeneratorInterface<T>.
+template <typename T>
+class ParamIteratorInterface {
+ public:
+ virtual ~ParamIteratorInterface() {}
+ // A pointer to the base generator instance.
+ // Used only for the purposes of iterator comparison
+ // to make sure that two iterators belong to the same generator.
+ virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
+ // Advances iterator to point to the next element
+ // provided by the generator. The caller is responsible
+ // for not calling Advance() on an iterator equal to
+ // BaseGenerator()->End().
+ virtual void Advance() = 0;
+ // Clones the iterator object. Used for implementing copy semantics
+ // of ParamIterator<T>.
+ virtual ParamIteratorInterface* Clone() const = 0;
+ // Dereferences the current iterator and provides (read-only) access
+ // to the pointed value. It is the caller's responsibility not to call
+ // Current() on an iterator equal to BaseGenerator()->End().
+ // Used for implementing ParamGenerator<T>::operator*().
+ virtual const T* Current() const = 0;
+ // Determines whether the given iterator and other point to the same
+ // element in the sequence generated by the generator.
+ // Used for implementing ParamGenerator<T>::operator==().
+ virtual bool Equals(const ParamIteratorInterface& other) const = 0;
+};
+
+// Class iterating over elements provided by an implementation of
+// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
+// and implements the const forward iterator concept.
+template <typename T>
+class ParamIterator {
+ public:
+ typedef T value_type;
+ typedef const T& reference;
+ typedef ptrdiff_t difference_type;
+
+ // ParamIterator assumes ownership of the impl_ pointer.
+ ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
+ ParamIterator& operator=(const ParamIterator& other) {
+ if (this != &other)
+ impl_.reset(other.impl_->Clone());
+ return *this;
+ }
+
+ const T& operator*() const { return *impl_->Current(); }
+ const T* operator->() const { return impl_->Current(); }
+ // Prefix version of operator++.
+ ParamIterator& operator++() {
+ impl_->Advance();
+ return *this;
+ }
+ // Postfix version of operator++.
+ ParamIterator operator++(int /*unused*/) {
+ ParamIteratorInterface<T>* clone = impl_->Clone();
+ impl_->Advance();
+ return ParamIterator(clone);
+ }
+ bool operator==(const ParamIterator& other) const {
+ return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
+ }
+ bool operator!=(const ParamIterator& other) const {
+ return !(*this == other);
+ }
+
+ private:
+ friend class ParamGenerator<T>;
+ explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
+ scoped_ptr<ParamIteratorInterface<T> > impl_;
+};
+
+// ParamGeneratorInterface<T> is the binary interface to access generators
+// defined in other translation units.
+template <typename T>
+class ParamGeneratorInterface {
+ public:
+ typedef T ParamType;
+
+ virtual ~ParamGeneratorInterface() {}
+
+ // Generator interface definition
+ virtual ParamIteratorInterface<T>* Begin() const = 0;
+ virtual ParamIteratorInterface<T>* End() const = 0;
+};
+
+// Wraps ParamGeneratorInterface<T> and provides general generator syntax
+// compatible with the STL Container concept.
+// This class implements copy initialization semantics and the contained
+// ParamGeneratorInterface<T> instance is shared among all copies
+// of the original object. This is possible because that instance is immutable.
+template<typename T>
+class ParamGenerator {
+ public:
+ typedef ParamIterator<T> iterator;
+
+ explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
+ ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
+
+ ParamGenerator& operator=(const ParamGenerator& other) {
+ impl_ = other.impl_;
+ return *this;
+ }
+
+ iterator begin() const { return iterator(impl_->Begin()); }
+ iterator end() const { return iterator(impl_->End()); }
+
+ private:
+ ::testing::internal::linked_ptr<const ParamGeneratorInterface<T> > impl_;
+};
+
+// Generates values from a range of two comparable values. Can be used to
+// generate sequences of user-defined types that implement operator+() and
+// operator<().
+// This class is used in the Range() function.
+template <typename T, typename IncrementT>
+class RangeGenerator : public ParamGeneratorInterface<T> {
+ public:
+ RangeGenerator(T begin, T end, IncrementT step)
+ : begin_(begin), end_(end),
+ step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
+ virtual ~RangeGenerator() {}
+
+ virtual ParamIteratorInterface<T>* Begin() const {
+ return new Iterator(this, begin_, 0, step_);
+ }
+ virtual ParamIteratorInterface<T>* End() const {
+ return new Iterator(this, end_, end_index_, step_);
+ }
+
+ private:
+ class Iterator : public ParamIteratorInterface<T> {
+ public:
+ Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
+ IncrementT step)
+ : base_(base), value_(value), index_(index), step_(step) {}
+ virtual ~Iterator() {}
+
+ virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+ return base_;
+ }
+ virtual void Advance() {
+ value_ = value_ + step_;
+ index_++;
+ }
+ virtual ParamIteratorInterface<T>* Clone() const {
+ return new Iterator(*this);
+ }
+ virtual const T* Current() const { return &value_; }
+ virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+ // Having the same base generator guarantees that the other
+ // iterator is of the same type and we can downcast.
+ GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+ << "The program attempted to compare iterators "
+ << "from different generators." << std::endl;
+ const int other_index =
+ CheckedDowncastToActualType<const Iterator>(&other)->index_;
+ return index_ == other_index;
+ }
+
+ private:
+ Iterator(const Iterator& other)
+ : ParamIteratorInterface<T>(),
+ base_(other.base_), value_(other.value_), index_(other.index_),
+ step_(other.step_) {}
+
+ // No implementation - assignment is unsupported.
+ void operator=(const Iterator& other);
+
+ const ParamGeneratorInterface<T>* const base_;
+ T value_;
+ int index_;
+ const IncrementT step_;
+ }; // class RangeGenerator::Iterator
+
+ static int CalculateEndIndex(const T& begin,
+ const T& end,
+ const IncrementT& step) {
+ int end_index = 0;
+ for (T i = begin; i < end; i = i + step)
+ end_index++;
+ return end_index;
+ }
+
+ // No implementation - assignment is unsupported.
+ void operator=(const RangeGenerator& other);
+
+ const T begin_;
+ const T end_;
+ const IncrementT step_;
+ // The index for the end() iterator. All the elements in the generated
+ // sequence are indexed (0-based) to aid iterator comparison.
+ const int end_index_;
+}; // class RangeGenerator
+
+
+// Generates values from a pair of STL-style iterators. Used in the
+// ValuesIn() function. The elements are copied from the source range
+// since the source can be located on the stack, and the generator
+// is likely to persist beyond that stack frame.
+template <typename T>
+class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
+ public:
+ template <typename ForwardIterator>
+ ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
+ : container_(begin, end) {}
+ virtual ~ValuesInIteratorRangeGenerator() {}
+
+ virtual ParamIteratorInterface<T>* Begin() const {
+ return new Iterator(this, container_.begin());
+ }
+ virtual ParamIteratorInterface<T>* End() const {
+ return new Iterator(this, container_.end());
+ }
+
+ private:
+ typedef typename ::std::vector<T> ContainerType;
+
+ class Iterator : public ParamIteratorInterface<T> {
+ public:
+ Iterator(const ParamGeneratorInterface<T>* base,
+ typename ContainerType::const_iterator iterator)
+ : base_(base), iterator_(iterator) {}
+ virtual ~Iterator() {}
+
+ virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+ return base_;
+ }
+ virtual void Advance() {
+ ++iterator_;
+ value_.reset();
+ }
+ virtual ParamIteratorInterface<T>* Clone() const {
+ return new Iterator(*this);
+ }
+ // We need to use cached value referenced by iterator_ because *iterator_
+ // can return a temporary object (and of type other then T), so just
+ // having "return &*iterator_;" doesn't work.
+ // value_ is updated here and not in Advance() because Advance()
+ // can advance iterator_ beyond the end of the range, and we cannot
+ // detect that fact. The client code, on the other hand, is
+ // responsible for not calling Current() on an out-of-range iterator.
+ virtual const T* Current() const {
+ if (value_.get() == NULL)
+ value_.reset(new T(*iterator_));
+ return value_.get();
+ }
+ virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+ // Having the same base generator guarantees that the other
+ // iterator is of the same type and we can downcast.
+ GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+ << "The program attempted to compare iterators "
+ << "from different generators." << std::endl;
+ return iterator_ ==
+ CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
+ }
+
+ private:
+ Iterator(const Iterator& other)
+ // The explicit constructor call suppresses a false warning
+ // emitted by gcc when supplied with the -Wextra option.
+ : ParamIteratorInterface<T>(),
+ base_(other.base_),
+ iterator_(other.iterator_) {}
+
+ const ParamGeneratorInterface<T>* const base_;
+ typename ContainerType::const_iterator iterator_;
+ // A cached value of *iterator_. We keep it here to allow access by
+ // pointer in the wrapping iterator's operator->().
+ // value_ needs to be mutable to be accessed in Current().
+ // Use of scoped_ptr helps manage cached value's lifetime,
+ // which is bound by the lifespan of the iterator itself.
+ mutable scoped_ptr<const T> value_;
+ }; // class ValuesInIteratorRangeGenerator::Iterator
+
+ // No implementation - assignment is unsupported.
+ void operator=(const ValuesInIteratorRangeGenerator& other);
+
+ const ContainerType container_;
+}; // class ValuesInIteratorRangeGenerator
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Stores a parameter value and later creates tests parameterized with that
+// value.
+template <class TestClass>
+class ParameterizedTestFactory : public TestFactoryBase {
+ public:
+ typedef typename TestClass::ParamType ParamType;
+ explicit ParameterizedTestFactory(ParamType parameter) :
+ parameter_(parameter) {}
+ virtual Test* CreateTest() {
+ TestClass::SetParam(&parameter_);
+ return new TestClass();
+ }
+
+ private:
+ const ParamType parameter_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// TestMetaFactoryBase is a base class for meta-factories that create
+// test factories for passing into MakeAndRegisterTestInfo function.
+template <class ParamType>
+class TestMetaFactoryBase {
+ public:
+ virtual ~TestMetaFactoryBase() {}
+
+ virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// TestMetaFactory creates test factories for passing into
+// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
+// ownership of test factory pointer, same factory object cannot be passed
+// into that method twice. But ParameterizedTestCaseInfo is going to call
+// it for each Test/Parameter value combination. Thus it needs meta factory
+// creator class.
+template <class TestCase>
+class TestMetaFactory
+ : public TestMetaFactoryBase<typename TestCase::ParamType> {
+ public:
+ typedef typename TestCase::ParamType ParamType;
+
+ TestMetaFactory() {}
+
+ virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
+ return new ParameterizedTestFactory<TestCase>(parameter);
+ }
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseInfoBase is a generic interface
+// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
+// accumulates test information provided by TEST_P macro invocations
+// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
+// and uses that information to register all resulting test instances
+// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
+// a collection of pointers to the ParameterizedTestCaseInfo objects
+// and calls RegisterTests() on each of them when asked.
+class ParameterizedTestCaseInfoBase {
+ public:
+ virtual ~ParameterizedTestCaseInfoBase() {}
+
+ // Base part of test case name for display purposes.
+ virtual const String& GetTestCaseName() const = 0;
+ // Test case id to verify identity.
+ virtual TypeId GetTestCaseTypeId() const = 0;
+ // UnitTest class invokes this method to register tests in this
+ // test case right before running them in RUN_ALL_TESTS macro.
+ // This method should not be called more then once on any single
+ // instance of a ParameterizedTestCaseInfoBase derived class.
+ virtual void RegisterTests() = 0;
+
+ protected:
+ ParameterizedTestCaseInfoBase() {}
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
+// macro invocations for a particular test case and generators
+// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
+// test case. It registers tests with all values generated by all
+// generators when asked.
+template <class TestCase>
+class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
+ public:
+ // ParamType and GeneratorCreationFunc are private types but are required
+ // for declarations of public methods AddTestPattern() and
+ // AddTestCaseInstantiation().
+ typedef typename TestCase::ParamType ParamType;
+ // A function that returns an instance of appropriate generator type.
+ typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
+
+ explicit ParameterizedTestCaseInfo(const char* name)
+ : test_case_name_(name) {}
+
+ // Test case base name for display purposes.
+ virtual const String& GetTestCaseName() const { return test_case_name_; }
+ // Test case id to verify identity.
+ virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
+ // TEST_P macro uses AddTestPattern() to record information
+ // about a single test in a LocalTestInfo structure.
+ // test_case_name is the base name of the test case (without invocation
+ // prefix). test_base_name is the name of an individual test without
+ // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
+ // test case base name and DoBar is test base name.
+ void AddTestPattern(const char* test_case_name,
+ const char* test_base_name,
+ TestMetaFactoryBase<ParamType>* meta_factory) {
+ tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
+ test_base_name,
+ meta_factory)));
+ }
+ // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
+ // about a generator.
+ int AddTestCaseInstantiation(const char* instantiation_name,
+ GeneratorCreationFunc* func,
+ const char* /* file */,
+ int /* line */) {
+ instantiations_.push_back(::std::make_pair(instantiation_name, func));
+ return 0; // Return value used only to run this method in namespace scope.
+ }
+ // UnitTest class invokes this method to register tests in this test case
+ // test cases right before running tests in RUN_ALL_TESTS macro.
+ // This method should not be called more then once on any single
+ // instance of a ParameterizedTestCaseInfoBase derived class.
+ // UnitTest has a guard to prevent from calling this method more then once.
+ virtual void RegisterTests() {
+ for (typename TestInfoContainer::iterator test_it = tests_.begin();
+ test_it != tests_.end(); ++test_it) {
+ linked_ptr<TestInfo> test_info = *test_it;
+ for (typename InstantiationContainer::iterator gen_it =
+ instantiations_.begin(); gen_it != instantiations_.end();
+ ++gen_it) {
+ const String& instantiation_name = gen_it->first;
+ ParamGenerator<ParamType> generator((*gen_it->second)());
+
+ Message test_case_name_stream;
+ if ( !instantiation_name.empty() )
+ test_case_name_stream << instantiation_name.c_str() << "/";
+ test_case_name_stream << test_info->test_case_base_name.c_str();
+
+ int i = 0;
+ for (typename ParamGenerator<ParamType>::iterator param_it =
+ generator.begin();
+ param_it != generator.end(); ++param_it, ++i) {
+ Message test_name_stream;
+ test_name_stream << test_info->test_base_name.c_str() << "/" << i;
+ ::testing::internal::MakeAndRegisterTestInfo(
+ test_case_name_stream.GetString().c_str(),
+ test_name_stream.GetString().c_str(),
+ "", // test_case_comment
+ "", // comment; TODO(vladl@google.com): provide parameter value
+ // representation.
+ GetTestCaseTypeId(),
+ TestCase::SetUpTestCase,
+ TestCase::TearDownTestCase,
+ test_info->test_meta_factory->CreateTestFactory(*param_it));
+ } // for param_it
+ } // for gen_it
+ } // for test_it
+ } // RegisterTests
+
+ private:
+ // LocalTestInfo structure keeps information about a single test registered
+ // with TEST_P macro.
+ struct TestInfo {
+ TestInfo(const char* a_test_case_base_name,
+ const char* a_test_base_name,
+ TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
+ test_case_base_name(a_test_case_base_name),
+ test_base_name(a_test_base_name),
+ test_meta_factory(a_test_meta_factory) {}
+
+ const String test_case_base_name;
+ const String test_base_name;
+ const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
+ };
+ typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
+ // Keeps pairs of <Instantiation name, Sequence generator creation function>
+ // received from INSTANTIATE_TEST_CASE_P macros.
+ typedef ::std::vector<std::pair<String, GeneratorCreationFunc*> >
+ InstantiationContainer;
+
+ const String test_case_name_;
+ TestInfoContainer tests_;
+ InstantiationContainer instantiations_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
+}; // class ParameterizedTestCaseInfo
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
+// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
+// macros use it to locate their corresponding ParameterizedTestCaseInfo
+// descriptors.
+class ParameterizedTestCaseRegistry {
+ public:
+ ParameterizedTestCaseRegistry() {}
+ ~ParameterizedTestCaseRegistry() {
+ for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+ it != test_case_infos_.end(); ++it) {
+ delete *it;
+ }
+ }
+
+ // Looks up or creates and returns a structure containing information about
+ // tests and instantiations of a particular test case.
+ template <class TestCase>
+ ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
+ const char* test_case_name,
+ const char* file,
+ int line) {
+ ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
+ for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+ it != test_case_infos_.end(); ++it) {
+ if ((*it)->GetTestCaseName() == test_case_name) {
+ if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
+ // Complain about incorrect usage of Google Test facilities
+ // and terminate the program since we cannot guaranty correct
+ // test case setup and tear-down in this case.
+ ReportInvalidTestCaseType(test_case_name, file, line);
+ abort();
+ } else {
+ // At this point we are sure that the object we found is of the same
+ // type we are looking for, so we downcast it to that type
+ // without further checks.
+ typed_test_info = CheckedDowncastToActualType<
+ ParameterizedTestCaseInfo<TestCase> >(*it);
+ }
+ break;
+ }
+ }
+ if (typed_test_info == NULL) {
+ typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);
+ test_case_infos_.push_back(typed_test_info);
+ }
+ return typed_test_info;
+ }
+ void RegisterTests() {
+ for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+ it != test_case_infos_.end(); ++it) {
+ (*it)->RegisterTests();
+ }
+ }
+
+ private:
+ typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
+
+ TestCaseInfoContainer test_case_infos_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
+};
+
+} // namespace internal
+} // namespace testing
+
+#endif // GTEST_HAS_PARAM_TEST
+
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
+
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// 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: vladl@google.com (Vlad Losev)
+
+// Type and function utilities for implementing parameterized tests.
+// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
+//
+// Currently Google Test supports at most 50 arguments in Values,
+// and at most 10 arguments in Combine. Please contact
+// googletestframework@googlegroups.com if you need more.
+// Please note that the number of arguments to Combine is limited
+// by the maximum arity of the implementation of tr1::tuple which is
+// currently set at 10.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*. Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+
+// Forward declarations of ValuesIn(), which is implemented in
+// include/gtest/gtest-param-test.h.
+template <typename ForwardIterator>
+internal::ParamGenerator<
+ typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
+ ForwardIterator begin, ForwardIterator end);
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+ const Container& container);
+
+namespace internal {
+
+// Used in the Values() function to provide polymorphic capabilities.
+template <typename T1>
+class ValueArray1 {
+ public:
+ explicit ValueArray1(T1 v1) : v1_(v1) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray1& other);
+
+ const T1 v1_;
+};
+
+template <typename T1, typename T2>
+class ValueArray2 {
+ public:
+ ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray2& other);
+
+ const T1 v1_;
+ const T2 v2_;
+};
+
+template <typename T1, typename T2, typename T3>
+class ValueArray3 {
+ public:
+ ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray3& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4>
+class ValueArray4 {
+ public:
+ ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3),
+ v4_(v4) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray4& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+class ValueArray5 {
+ public:
+ ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3),
+ v4_(v4), v5_(v5) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray5& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+class ValueArray6 {
+ public:
+ ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2),
+ v3_(v3), v4_(v4), v5_(v5), v6_(v6) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray6& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7>
+class ValueArray7 {
+ public:
+ ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1),
+ v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray7& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8>
+class ValueArray8 {
+ public:
+ ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+ T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+ v8_(v8) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray8& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9>
+class ValueArray9 {
+ public:
+ ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+ T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+ v8_(v8), v9_(v9) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray9& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+class ValueArray10 {
+ public:
+ ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+ v8_(v8), v9_(v9), v10_(v10) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray10& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11>
+class ValueArray11 {
+ public:
+ ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+ v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray11& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12>
+class ValueArray12 {
+ public:
+ ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+ v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray12& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13>
+class ValueArray13 {
+ public:
+ ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+ v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+ v12_(v12), v13_(v13) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray13& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14>
+class ValueArray14 {
+ public:
+ ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3),
+ v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+ v11_(v11), v12_(v12), v13_(v13), v14_(v14) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray14& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15>
+class ValueArray15 {
+ public:
+ ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2),
+ v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+ v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray15& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16>
+class ValueArray16 {
+ public:
+ ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1),
+ v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+ v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+ v16_(v16) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray16& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17>
+class ValueArray17 {
+ public:
+ ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+ T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+ v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+ v15_(v15), v16_(v16), v17_(v17) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray17& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18>
+class ValueArray18 {
+ public:
+ ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+ v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+ v15_(v15), v16_(v16), v17_(v17), v18_(v18) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray18& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19>
+class ValueArray19 {
+ public:
+ ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+ v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+ v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray19& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20>
+class ValueArray20 {
+ public:
+ ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+ v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+ v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+ v19_(v19), v20_(v20) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray20& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21>
+class ValueArray21 {
+ public:
+ ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+ v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+ v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+ v18_(v18), v19_(v19), v20_(v20), v21_(v21) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray21& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22>
+class ValueArray22 {
+ public:
+ ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3),
+ v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+ v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+ v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray22& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23>
+class ValueArray23 {
+ public:
+ ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2),
+ v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+ v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+ v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+ v23_(v23) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_,
+ v23_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray23& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24>
+class ValueArray24 {
+ public:
+ ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1),
+ v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+ v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+ v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+ v22_(v22), v23_(v23), v24_(v24) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray24& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25>
+class ValueArray25 {
+ public:
+ ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+ T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+ v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+ v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+ v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray25& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26>
+class ValueArray26 {
+ public:
+ ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+ v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+ v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+ v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray26& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27>
+class ValueArray27 {
+ public:
+ ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+ v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+ v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+ v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+ v26_(v26), v27_(v27) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray27& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28>
+class ValueArray28 {
+ public:
+ ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+ v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+ v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+ v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+ v25_(v25), v26_(v26), v27_(v27), v28_(v28) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray28& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29>
+class ValueArray29 {
+ public:
+ ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+ v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+ v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+ v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+ v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray29& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30>
+class ValueArray30 {
+ public:
+ ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3),
+ v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+ v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+ v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+ v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+ v29_(v29), v30_(v30) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray30& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31>
+class ValueArray31 {
+ public:
+ ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2),
+ v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+ v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+ v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+ v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+ v29_(v29), v30_(v30), v31_(v31) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray31& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32>
+class ValueArray32 {
+ public:
+ ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1),
+ v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+ v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+ v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+ v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+ v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray32& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33>
+class ValueArray33 {
+ public:
+ ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
+ T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+ v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+ v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+ v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+ v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+ v33_(v33) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray33& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34>
+class ValueArray34 {
+ public:
+ ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+ v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+ v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+ v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+ v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+ v33_(v33), v34_(v34) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray34& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35>
+class ValueArray35 {
+ public:
+ ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+ v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+ v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+ v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+ v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
+ v32_(v32), v33_(v33), v34_(v34), v35_(v35) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_,
+ v35_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray35& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36>
+class ValueArray36 {
+ public:
+ ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+ v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+ v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+ v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+ v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
+ v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray36& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37>
+class ValueArray37 {
+ public:
+ ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+ v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+ v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+ v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+ v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
+ v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
+ v36_(v36), v37_(v37) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray37& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38>
+class ValueArray38 {
+ public:
+ ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3),
+ v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+ v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+ v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+ v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+ v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+ v35_(v35), v36_(v36), v37_(v37), v38_(v38) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_, v38_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray38& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+ const T38 v38_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39>
+class ValueArray39 {
+ public:
+ ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2),
+ v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+ v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+ v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+ v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+ v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+ v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_, v38_, v39_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray39& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+ const T38 v38_;
+ const T39 v39_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40>
+class ValueArray40 {
+ public:
+ ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1),
+ v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+ v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+ v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+ v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+ v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
+ v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
+ v40_(v40) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_, v38_, v39_, v40_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray40& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+ const T38 v38_;
+ const T39 v39_;
+ const T40 v40_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41>
+class ValueArray41 {
+ public:
+ ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
+ T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+ v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+ v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+ v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+ v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+ v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+ v39_(v39), v40_(v40), v41_(v41) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_, v38_, v39_, v40_, v41_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray41& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+ const T38 v38_;
+ const T39 v39_;
+ const T40 v40_;
+ const T41 v41_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42>
+class ValueArray42 {
+ public:
+ ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+ T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+ v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+ v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+ v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+ v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+ v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+ v39_(v39), v40_(v40), v41_(v41), v42_(v42) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_, v38_, v39_, v40_, v41_, v42_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray42& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+ const T38 v38_;
+ const T39 v39_;
+ const T40 v40_;
+ const T41 v41_;
+ const T42 v42_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43>
+class ValueArray43 {
+ public:
+ ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+ T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+ v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+ v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+ v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+ v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
+ v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37),
+ v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray43& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+ const T38 v38_;
+ const T39 v39_;
+ const T40 v40_;
+ const T41 v41_;
+ const T42 v42_;
+ const T43 v43_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44>
+class ValueArray44 {
+ public:
+ ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+ T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+ v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+ v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+ v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+ v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
+ v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36),
+ v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42),
+ v43_(v43), v44_(v44) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray44& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+ const T38 v38_;
+ const T39 v39_;
+ const T40 v40_;
+ const T41 v41_;
+ const T42 v42_;
+ const T43 v43_;
+ const T44 v44_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45>
+class ValueArray45 {
+ public:
+ ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+ T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+ v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+ v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+ v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+ v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
+ v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
+ v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41),
+ v42_(v42), v43_(v43), v44_(v44), v45_(v45) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray45& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+ const T38 v38_;
+ const T39 v39_;
+ const T40 v40_;
+ const T41 v41_;
+ const T42 v42_;
+ const T43 v43_;
+ const T44 v44_;
+ const T45 v45_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46>
+class ValueArray46 {
+ public:
+ ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+ T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3),
+ v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+ v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+ v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+ v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+ v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+ v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
+ v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray46& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+ const T38 v38_;
+ const T39 v39_;
+ const T40 v40_;
+ const T41 v41_;
+ const T42 v42_;
+ const T43 v43_;
+ const T44 v44_;
+ const T45 v45_;
+ const T46 v46_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47>
+class ValueArray47 {
+ public:
+ ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+ T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2),
+ v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+ v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+ v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+ v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+ v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+ v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
+ v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46),
+ v47_(v47) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_,
+ v47_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray47& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+ const T38 v38_;
+ const T39 v39_;
+ const T40 v40_;
+ const T41 v41_;
+ const T42 v42_;
+ const T43 v43_;
+ const T44 v44_;
+ const T45 v45_;
+ const T46 v46_;
+ const T47 v47_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47, typename T48>
+class ValueArray48 {
+ public:
+ ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+ T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1),
+ v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+ v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+ v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+ v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+ v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
+ v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
+ v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45),
+ v46_(v46), v47_(v47), v48_(v48) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+ v48_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray48& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+ const T38 v38_;
+ const T39 v39_;
+ const T40 v40_;
+ const T41 v41_;
+ const T42 v42_;
+ const T43 v43_;
+ const T44 v44_;
+ const T45 v45_;
+ const T46 v46_;
+ const T47 v47_;
+ const T48 v48_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47, typename T48, typename T49>
+class ValueArray49 {
+ public:
+ ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+ T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48,
+ T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+ v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+ v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+ v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+ v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+ v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+ v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
+ v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+ v48_, v49_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray49& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+ const T38 v38_;
+ const T39 v39_;
+ const T40 v40_;
+ const T41 v41_;
+ const T42 v42_;
+ const T43 v43_;
+ const T44 v44_;
+ const T45 v45_;
+ const T46 v46_;
+ const T47 v47_;
+ const T48 v48_;
+ const T49 v49_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47, typename T48, typename T49, typename T50>
+class ValueArray50 {
+ public:
+ ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+ T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49,
+ T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+ v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+ v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+ v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+ v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+ v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+ v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
+ v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const {
+ const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+ v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+ v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+ v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+ v48_, v49_, v50_};
+ return ValuesIn(array);
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray50& other);
+
+ const T1 v1_;
+ const T2 v2_;
+ const T3 v3_;
+ const T4 v4_;
+ const T5 v5_;
+ const T6 v6_;
+ const T7 v7_;
+ const T8 v8_;
+ const T9 v9_;
+ const T10 v10_;
+ const T11 v11_;
+ const T12 v12_;
+ const T13 v13_;
+ const T14 v14_;
+ const T15 v15_;
+ const T16 v16_;
+ const T17 v17_;
+ const T18 v18_;
+ const T19 v19_;
+ const T20 v20_;
+ const T21 v21_;
+ const T22 v22_;
+ const T23 v23_;
+ const T24 v24_;
+ const T25 v25_;
+ const T26 v26_;
+ const T27 v27_;
+ const T28 v28_;
+ const T29 v29_;
+ const T30 v30_;
+ const T31 v31_;
+ const T32 v32_;
+ const T33 v33_;
+ const T34 v34_;
+ const T35 v35_;
+ const T36 v36_;
+ const T37 v37_;
+ const T38 v38_;
+ const T39 v39_;
+ const T40 v40_;
+ const T41 v41_;
+ const T42 v42_;
+ const T43 v43_;
+ const T44 v44_;
+ const T45 v45_;
+ const T46 v46_;
+ const T47 v47_;
+ const T48 v48_;
+ const T49 v49_;
+ const T50 v50_;
+};
+
+#if GTEST_HAS_COMBINE
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Generates values from the Cartesian product of values produced
+// by the argument generators.
+//
+template <typename T1, typename T2>
+class CartesianProductGenerator2
+ : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > {
+ public:
+ typedef ::std::tr1::tuple<T1, T2> ParamType;
+
+ CartesianProductGenerator2(const ParamGenerator<T1>& g1,
+ const ParamGenerator<T2>& g2)
+ : g1_(g1), g2_(g2) {}
+ virtual ~CartesianProductGenerator2() {}
+
+ virtual ParamIteratorInterface<ParamType>* Begin() const {
+ return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin());
+ }
+ virtual ParamIteratorInterface<ParamType>* End() const {
+ return new Iterator(this, g1_, g1_.end(), g2_, g2_.end());
+ }
+
+ private:
+ class Iterator : public ParamIteratorInterface<ParamType> {
+ public:
+ Iterator(const ParamGeneratorInterface<ParamType>* base,
+ const ParamGenerator<T1>& g1,
+ const typename ParamGenerator<T1>::iterator& current1,
+ const ParamGenerator<T2>& g2,
+ const typename ParamGenerator<T2>::iterator& current2)
+ : base_(base),
+ begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+ begin2_(g2.begin()), end2_(g2.end()), current2_(current2) {
+ ComputeCurrentValue();
+ }
+ virtual ~Iterator() {}
+
+ virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+ return base_;
+ }
+ // Advance should not be called on beyond-of-range iterators
+ // so no component iterators must be beyond end of range, either.
+ virtual void Advance() {
+ assert(!AtEnd());
+ ++current2_;
+ if (current2_ == end2_) {
+ current2_ = begin2_;
+ ++current1_;
+ }
+ ComputeCurrentValue();
+ }
+ virtual ParamIteratorInterface<ParamType>* Clone() const {
+ return new Iterator(*this);
+ }
+ virtual const ParamType* Current() const { return &current_value_; }
+ virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+ // Having the same base generator guarantees that the other
+ // iterator is of the same type and we can downcast.
+ GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+ << "The program attempted to compare iterators "
+ << "from different generators." << std::endl;
+ const Iterator* typed_other =
+ CheckedDowncastToActualType<const Iterator>(&other);
+ // We must report iterators equal if they both point beyond their
+ // respective ranges. That can happen in a variety of fashions,
+ // so we have to consult AtEnd().
+ return (AtEnd() && typed_other->AtEnd()) ||
+ (
+ current1_ == typed_other->current1_ &&
+ current2_ == typed_other->current2_);
+ }
+
+ private:
+ Iterator(const Iterator& other)
+ : base_(other.base_),
+ begin1_(other.begin1_),
+ end1_(other.end1_),
+ current1_(other.current1_),
+ begin2_(other.begin2_),
+ end2_(other.end2_),
+ current2_(other.current2_) {
+ ComputeCurrentValue();
+ }
+
+ void ComputeCurrentValue() {
+ if (!AtEnd())
+ current_value_ = ParamType(*current1_, *current2_);
+ }
+ bool AtEnd() const {
+ // We must report iterator past the end of the range when either of the
+ // component iterators has reached the end of its range.
+ return
+ current1_ == end1_ ||
+ current2_ == end2_;
+ }
+
+ // No implementation - assignment is unsupported.
+ void operator=(const Iterator& other);
+
+ const ParamGeneratorInterface<ParamType>* const base_;
+ // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+ // current[i]_ is the actual traversing iterator.
+ const typename ParamGenerator<T1>::iterator begin1_;
+ const typename ParamGenerator<T1>::iterator end1_;
+ typename ParamGenerator<T1>::iterator current1_;
+ const typename ParamGenerator<T2>::iterator begin2_;
+ const typename ParamGenerator<T2>::iterator end2_;
+ typename ParamGenerator<T2>::iterator current2_;
+ ParamType current_value_;
+ }; // class CartesianProductGenerator2::Iterator
+
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductGenerator2& other);
+
+ const ParamGenerator<T1> g1_;
+ const ParamGenerator<T2> g2_;
+}; // class CartesianProductGenerator2
+
+
+template <typename T1, typename T2, typename T3>
+class CartesianProductGenerator3
+ : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > {
+ public:
+ typedef ::std::tr1::tuple<T1, T2, T3> ParamType;
+
+ CartesianProductGenerator3(const ParamGenerator<T1>& g1,
+ const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3)
+ : g1_(g1), g2_(g2), g3_(g3) {}
+ virtual ~CartesianProductGenerator3() {}
+
+ virtual ParamIteratorInterface<ParamType>* Begin() const {
+ return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+ g3_.begin());
+ }
+ virtual ParamIteratorInterface<ParamType>* End() const {
+ return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end());
+ }
+
+ private:
+ class Iterator : public ParamIteratorInterface<ParamType> {
+ public:
+ Iterator(const ParamGeneratorInterface<ParamType>* base,
+ const ParamGenerator<T1>& g1,
+ const typename ParamGenerator<T1>::iterator& current1,
+ const ParamGenerator<T2>& g2,
+ const typename ParamGenerator<T2>::iterator& current2,
+ const ParamGenerator<T3>& g3,
+ const typename ParamGenerator<T3>::iterator& current3)
+ : base_(base),
+ begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+ begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+ begin3_(g3.begin()), end3_(g3.end()), current3_(current3) {
+ ComputeCurrentValue();
+ }
+ virtual ~Iterator() {}
+
+ virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+ return base_;
+ }
+ // Advance should not be called on beyond-of-range iterators
+ // so no component iterators must be beyond end of range, either.
+ virtual void Advance() {
+ assert(!AtEnd());
+ ++current3_;
+ if (current3_ == end3_) {
+ current3_ = begin3_;
+ ++current2_;
+ }
+ if (current2_ == end2_) {
+ current2_ = begin2_;
+ ++current1_;
+ }
+ ComputeCurrentValue();
+ }
+ virtual ParamIteratorInterface<ParamType>* Clone() const {
+ return new Iterator(*this);
+ }
+ virtual const ParamType* Current() const { return &current_value_; }
+ virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+ // Having the same base generator guarantees that the other
+ // iterator is of the same type and we can downcast.
+ GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+ << "The program attempted to compare iterators "
+ << "from different generators." << std::endl;
+ const Iterator* typed_other =
+ CheckedDowncastToActualType<const Iterator>(&other);
+ // We must report iterators equal if they both point beyond their
+ // respective ranges. That can happen in a variety of fashions,
+ // so we have to consult AtEnd().
+ return (AtEnd() && typed_other->AtEnd()) ||
+ (
+ current1_ == typed_other->current1_ &&
+ current2_ == typed_other->current2_ &&
+ current3_ == typed_other->current3_);
+ }
+
+ private:
+ Iterator(const Iterator& other)
+ : base_(other.base_),
+ begin1_(other.begin1_),
+ end1_(other.end1_),
+ current1_(other.current1_),
+ begin2_(other.begin2_),
+ end2_(other.end2_),
+ current2_(other.current2_),
+ begin3_(other.begin3_),
+ end3_(other.end3_),
+ current3_(other.current3_) {
+ ComputeCurrentValue();
+ }
+
+ void ComputeCurrentValue() {
+ if (!AtEnd())
+ current_value_ = ParamType(*current1_, *current2_, *current3_);
+ }
+ bool AtEnd() const {
+ // We must report iterator past the end of the range when either of the
+ // component iterators has reached the end of its range.
+ return
+ current1_ == end1_ ||
+ current2_ == end2_ ||
+ current3_ == end3_;
+ }
+
+ // No implementation - assignment is unsupported.
+ void operator=(const Iterator& other);
+
+ const ParamGeneratorInterface<ParamType>* const base_;
+ // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+ // current[i]_ is the actual traversing iterator.
+ const typename ParamGenerator<T1>::iterator begin1_;
+ const typename ParamGenerator<T1>::iterator end1_;
+ typename ParamGenerator<T1>::iterator current1_;
+ const typename ParamGenerator<T2>::iterator begin2_;
+ const typename ParamGenerator<T2>::iterator end2_;
+ typename ParamGenerator<T2>::iterator current2_;
+ const typename ParamGenerator<T3>::iterator begin3_;
+ const typename ParamGenerator<T3>::iterator end3_;
+ typename ParamGenerator<T3>::iterator current3_;
+ ParamType current_value_;
+ }; // class CartesianProductGenerator3::Iterator
+
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductGenerator3& other);
+
+ const ParamGenerator<T1> g1_;
+ const ParamGenerator<T2> g2_;
+ const ParamGenerator<T3> g3_;
+}; // class CartesianProductGenerator3
+
+
+template <typename T1, typename T2, typename T3, typename T4>
+class CartesianProductGenerator4
+ : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > {
+ public:
+ typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType;
+
+ CartesianProductGenerator4(const ParamGenerator<T1>& g1,
+ const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+ const ParamGenerator<T4>& g4)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
+ virtual ~CartesianProductGenerator4() {}
+
+ virtual ParamIteratorInterface<ParamType>* Begin() const {
+ return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+ g3_.begin(), g4_, g4_.begin());
+ }
+ virtual ParamIteratorInterface<ParamType>* End() const {
+ return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+ g4_, g4_.end());
+ }
+
+ private:
+ class Iterator : public ParamIteratorInterface<ParamType> {
+ public:
+ Iterator(const ParamGeneratorInterface<ParamType>* base,
+ const ParamGenerator<T1>& g1,
+ const typename ParamGenerator<T1>::iterator& current1,
+ const ParamGenerator<T2>& g2,
+ const typename ParamGenerator<T2>::iterator& current2,
+ const ParamGenerator<T3>& g3,
+ const typename ParamGenerator<T3>::iterator& current3,
+ const ParamGenerator<T4>& g4,
+ const typename ParamGenerator<T4>::iterator& current4)
+ : base_(base),
+ begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+ begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+ begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+ begin4_(g4.begin()), end4_(g4.end()), current4_(current4) {
+ ComputeCurrentValue();
+ }
+ virtual ~Iterator() {}
+
+ virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+ return base_;
+ }
+ // Advance should not be called on beyond-of-range iterators
+ // so no component iterators must be beyond end of range, either.
+ virtual void Advance() {
+ assert(!AtEnd());
+ ++current4_;
+ if (current4_ == end4_) {
+ current4_ = begin4_;
+ ++current3_;
+ }
+ if (current3_ == end3_) {
+ current3_ = begin3_;
+ ++current2_;
+ }
+ if (current2_ == end2_) {
+ current2_ = begin2_;
+ ++current1_;
+ }
+ ComputeCurrentValue();
+ }
+ virtual ParamIteratorInterface<ParamType>* Clone() const {
+ return new Iterator(*this);
+ }
+ virtual const ParamType* Current() const { return &current_value_; }
+ virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+ // Having the same base generator guarantees that the other
+ // iterator is of the same type and we can downcast.
+ GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+ << "The program attempted to compare iterators "
+ << "from different generators." << std::endl;
+ const Iterator* typed_other =
+ CheckedDowncastToActualType<const Iterator>(&other);
+ // We must report iterators equal if they both point beyond their
+ // respective ranges. That can happen in a variety of fashions,
+ // so we have to consult AtEnd().
+ return (AtEnd() && typed_other->AtEnd()) ||
+ (
+ current1_ == typed_other->current1_ &&
+ current2_ == typed_other->current2_ &&
+ current3_ == typed_other->current3_ &&
+ current4_ == typed_other->current4_);
+ }
+
+ private:
+ Iterator(const Iterator& other)
+ : base_(other.base_),
+ begin1_(other.begin1_),
+ end1_(other.end1_),
+ current1_(other.current1_),
+ begin2_(other.begin2_),
+ end2_(other.end2_),
+ current2_(other.current2_),
+ begin3_(other.begin3_),
+ end3_(other.end3_),
+ current3_(other.current3_),
+ begin4_(other.begin4_),
+ end4_(other.end4_),
+ current4_(other.current4_) {
+ ComputeCurrentValue();
+ }
+
+ void ComputeCurrentValue() {
+ if (!AtEnd())
+ current_value_ = ParamType(*current1_, *current2_, *current3_,
+ *current4_);
+ }
+ bool AtEnd() const {
+ // We must report iterator past the end of the range when either of the
+ // component iterators has reached the end of its range.
+ return
+ current1_ == end1_ ||
+ current2_ == end2_ ||
+ current3_ == end3_ ||
+ current4_ == end4_;
+ }
+
+ // No implementation - assignment is unsupported.
+ void operator=(const Iterator& other);
+
+ const ParamGeneratorInterface<ParamType>* const base_;
+ // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+ // current[i]_ is the actual traversing iterator.
+ const typename ParamGenerator<T1>::iterator begin1_;
+ const typename ParamGenerator<T1>::iterator end1_;
+ typename ParamGenerator<T1>::iterator current1_;
+ const typename ParamGenerator<T2>::iterator begin2_;
+ const typename ParamGenerator<T2>::iterator end2_;
+ typename ParamGenerator<T2>::iterator current2_;
+ const typename ParamGenerator<T3>::iterator begin3_;
+ const typename ParamGenerator<T3>::iterator end3_;
+ typename ParamGenerator<T3>::iterator current3_;
+ const typename ParamGenerator<T4>::iterator begin4_;
+ const typename ParamGenerator<T4>::iterator end4_;
+ typename ParamGenerator<T4>::iterator current4_;
+ ParamType current_value_;
+ }; // class CartesianProductGenerator4::Iterator
+
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductGenerator4& other);
+
+ const ParamGenerator<T1> g1_;
+ const ParamGenerator<T2> g2_;
+ const ParamGenerator<T3> g3_;
+ const ParamGenerator<T4> g4_;
+}; // class CartesianProductGenerator4
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+class CartesianProductGenerator5
+ : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > {
+ public:
+ typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType;
+
+ CartesianProductGenerator5(const ParamGenerator<T1>& g1,
+ const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+ const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
+ virtual ~CartesianProductGenerator5() {}
+
+ virtual ParamIteratorInterface<ParamType>* Begin() const {
+ return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+ g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin());
+ }
+ virtual ParamIteratorInterface<ParamType>* End() const {
+ return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+ g4_, g4_.end(), g5_, g5_.end());
+ }
+
+ private:
+ class Iterator : public ParamIteratorInterface<ParamType> {
+ public:
+ Iterator(const ParamGeneratorInterface<ParamType>* base,
+ const ParamGenerator<T1>& g1,
+ const typename ParamGenerator<T1>::iterator& current1,
+ const ParamGenerator<T2>& g2,
+ const typename ParamGenerator<T2>::iterator& current2,
+ const ParamGenerator<T3>& g3,
+ const typename ParamGenerator<T3>::iterator& current3,
+ const ParamGenerator<T4>& g4,
+ const typename ParamGenerator<T4>::iterator& current4,
+ const ParamGenerator<T5>& g5,
+ const typename ParamGenerator<T5>::iterator& current5)
+ : base_(base),
+ begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+ begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+ begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+ begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+ begin5_(g5.begin()), end5_(g5.end()), current5_(current5) {
+ ComputeCurrentValue();
+ }
+ virtual ~Iterator() {}
+
+ virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+ return base_;
+ }
+ // Advance should not be called on beyond-of-range iterators
+ // so no component iterators must be beyond end of range, either.
+ virtual void Advance() {
+ assert(!AtEnd());
+ ++current5_;
+ if (current5_ == end5_) {
+ current5_ = begin5_;
+ ++current4_;
+ }
+ if (current4_ == end4_) {
+ current4_ = begin4_;
+ ++current3_;
+ }
+ if (current3_ == end3_) {
+ current3_ = begin3_;
+ ++current2_;
+ }
+ if (current2_ == end2_) {
+ current2_ = begin2_;
+ ++current1_;
+ }
+ ComputeCurrentValue();
+ }
+ virtual ParamIteratorInterface<ParamType>* Clone() const {
+ return new Iterator(*this);
+ }
+ virtual const ParamType* Current() const { return &current_value_; }
+ virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+ // Having the same base generator guarantees that the other
+ // iterator is of the same type and we can downcast.
+ GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+ << "The program attempted to compare iterators "
+ << "from different generators." << std::endl;
+ const Iterator* typed_other =
+ CheckedDowncastToActualType<const Iterator>(&other);
+ // We must report iterators equal if they both point beyond their
+ // respective ranges. That can happen in a variety of fashions,
+ // so we have to consult AtEnd().
+ return (AtEnd() && typed_other->AtEnd()) ||
+ (
+ current1_ == typed_other->current1_ &&
+ current2_ == typed_other->current2_ &&
+ current3_ == typed_other->current3_ &&
+ current4_ == typed_other->current4_ &&
+ current5_ == typed_other->current5_);
+ }
+
+ private:
+ Iterator(const Iterator& other)
+ : base_(other.base_),
+ begin1_(other.begin1_),
+ end1_(other.end1_),
+ current1_(other.current1_),
+ begin2_(other.begin2_),
+ end2_(other.end2_),
+ current2_(other.current2_),
+ begin3_(other.begin3_),
+ end3_(other.end3_),
+ current3_(other.current3_),
+ begin4_(other.begin4_),
+ end4_(other.end4_),
+ current4_(other.current4_),
+ begin5_(other.begin5_),
+ end5_(other.end5_),
+ current5_(other.current5_) {
+ ComputeCurrentValue();
+ }
+
+ void ComputeCurrentValue() {
+ if (!AtEnd())
+ current_value_ = ParamType(*current1_, *current2_, *current3_,
+ *current4_, *current5_);
+ }
+ bool AtEnd() const {
+ // We must report iterator past the end of the range when either of the
+ // component iterators has reached the end of its range.
+ return
+ current1_ == end1_ ||
+ current2_ == end2_ ||
+ current3_ == end3_ ||
+ current4_ == end4_ ||
+ current5_ == end5_;
+ }
+
+ // No implementation - assignment is unsupported.
+ void operator=(const Iterator& other);
+
+ const ParamGeneratorInterface<ParamType>* const base_;
+ // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+ // current[i]_ is the actual traversing iterator.
+ const typename ParamGenerator<T1>::iterator begin1_;
+ const typename ParamGenerator<T1>::iterator end1_;
+ typename ParamGenerator<T1>::iterator current1_;
+ const typename ParamGenerator<T2>::iterator begin2_;
+ const typename ParamGenerator<T2>::iterator end2_;
+ typename ParamGenerator<T2>::iterator current2_;
+ const typename ParamGenerator<T3>::iterator begin3_;
+ const typename ParamGenerator<T3>::iterator end3_;
+ typename ParamGenerator<T3>::iterator current3_;
+ const typename ParamGenerator<T4>::iterator begin4_;
+ const typename ParamGenerator<T4>::iterator end4_;
+ typename ParamGenerator<T4>::iterator current4_;
+ const typename ParamGenerator<T5>::iterator begin5_;
+ const typename ParamGenerator<T5>::iterator end5_;
+ typename ParamGenerator<T5>::iterator current5_;
+ ParamType current_value_;
+ }; // class CartesianProductGenerator5::Iterator
+
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductGenerator5& other);
+
+ const ParamGenerator<T1> g1_;
+ const ParamGenerator<T2> g2_;
+ const ParamGenerator<T3> g3_;
+ const ParamGenerator<T4> g4_;
+ const ParamGenerator<T5> g5_;
+}; // class CartesianProductGenerator5
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+class CartesianProductGenerator6
+ : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5,
+ T6> > {
+ public:
+ typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType;
+
+ CartesianProductGenerator6(const ParamGenerator<T1>& g1,
+ const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+ const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+ const ParamGenerator<T6>& g6)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
+ virtual ~CartesianProductGenerator6() {}
+
+ virtual ParamIteratorInterface<ParamType>* Begin() const {
+ return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+ g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin());
+ }
+ virtual ParamIteratorInterface<ParamType>* End() const {
+ return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+ g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end());
+ }
+
+ private:
+ class Iterator : public ParamIteratorInterface<ParamType> {
+ public:
+ Iterator(const ParamGeneratorInterface<ParamType>* base,
+ const ParamGenerator<T1>& g1,
+ const typename ParamGenerator<T1>::iterator& current1,
+ const ParamGenerator<T2>& g2,
+ const typename ParamGenerator<T2>::iterator& current2,
+ const ParamGenerator<T3>& g3,
+ const typename ParamGenerator<T3>::iterator& current3,
+ const ParamGenerator<T4>& g4,
+ const typename ParamGenerator<T4>::iterator& current4,
+ const ParamGenerator<T5>& g5,
+ const typename ParamGenerator<T5>::iterator& current5,
+ const ParamGenerator<T6>& g6,
+ const typename ParamGenerator<T6>::iterator& current6)
+ : base_(base),
+ begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+ begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+ begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+ begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+ begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+ begin6_(g6.begin()), end6_(g6.end()), current6_(current6) {
+ ComputeCurrentValue();
+ }
+ virtual ~Iterator() {}
+
+ virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+ return base_;
+ }
+ // Advance should not be called on beyond-of-range iterators
+ // so no component iterators must be beyond end of range, either.
+ virtual void Advance() {
+ assert(!AtEnd());
+ ++current6_;
+ if (current6_ == end6_) {
+ current6_ = begin6_;
+ ++current5_;
+ }
+ if (current5_ == end5_) {
+ current5_ = begin5_;
+ ++current4_;
+ }
+ if (current4_ == end4_) {
+ current4_ = begin4_;
+ ++current3_;
+ }
+ if (current3_ == end3_) {
+ current3_ = begin3_;
+ ++current2_;
+ }
+ if (current2_ == end2_) {
+ current2_ = begin2_;
+ ++current1_;
+ }
+ ComputeCurrentValue();
+ }
+ virtual ParamIteratorInterface<ParamType>* Clone() const {
+ return new Iterator(*this);
+ }
+ virtual const ParamType* Current() const { return &current_value_; }
+ virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+ // Having the same base generator guarantees that the other
+ // iterator is of the same type and we can downcast.
+ GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+ << "The program attempted to compare iterators "
+ << "from different generators." << std::endl;
+ const Iterator* typed_other =
+ CheckedDowncastToActualType<const Iterator>(&other);
+ // We must report iterators equal if they both point beyond their
+ // respective ranges. That can happen in a variety of fashions,
+ // so we have to consult AtEnd().
+ return (AtEnd() && typed_other->AtEnd()) ||
+ (
+ current1_ == typed_other->current1_ &&
+ current2_ == typed_other->current2_ &&
+ current3_ == typed_other->current3_ &&
+ current4_ == typed_other->current4_ &&
+ current5_ == typed_other->current5_ &&
+ current6_ == typed_other->current6_);
+ }
+
+ private:
+ Iterator(const Iterator& other)
+ : base_(other.base_),
+ begin1_(other.begin1_),
+ end1_(other.end1_),
+ current1_(other.current1_),
+ begin2_(other.begin2_),
+ end2_(other.end2_),
+ current2_(other.current2_),
+ begin3_(other.begin3_),
+ end3_(other.end3_),
+ current3_(other.current3_),
+ begin4_(other.begin4_),
+ end4_(other.end4_),
+ current4_(other.current4_),
+ begin5_(other.begin5_),
+ end5_(other.end5_),
+ current5_(other.current5_),
+ begin6_(other.begin6_),
+ end6_(other.end6_),
+ current6_(other.current6_) {
+ ComputeCurrentValue();
+ }
+
+ void ComputeCurrentValue() {
+ if (!AtEnd())
+ current_value_ = ParamType(*current1_, *current2_, *current3_,
+ *current4_, *current5_, *current6_);
+ }
+ bool AtEnd() const {
+ // We must report iterator past the end of the range when either of the
+ // component iterators has reached the end of its range.
+ return
+ current1_ == end1_ ||
+ current2_ == end2_ ||
+ current3_ == end3_ ||
+ current4_ == end4_ ||
+ current5_ == end5_ ||
+ current6_ == end6_;
+ }
+
+ // No implementation - assignment is unsupported.
+ void operator=(const Iterator& other);
+
+ const ParamGeneratorInterface<ParamType>* const base_;
+ // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+ // current[i]_ is the actual traversing iterator.
+ const typename ParamGenerator<T1>::iterator begin1_;
+ const typename ParamGenerator<T1>::iterator end1_;
+ typename ParamGenerator<T1>::iterator current1_;
+ const typename ParamGenerator<T2>::iterator begin2_;
+ const typename ParamGenerator<T2>::iterator end2_;
+ typename ParamGenerator<T2>::iterator current2_;
+ const typename ParamGenerator<T3>::iterator begin3_;
+ const typename ParamGenerator<T3>::iterator end3_;
+ typename ParamGenerator<T3>::iterator current3_;
+ const typename ParamGenerator<T4>::iterator begin4_;
+ const typename ParamGenerator<T4>::iterator end4_;
+ typename ParamGenerator<T4>::iterator current4_;
+ const typename ParamGenerator<T5>::iterator begin5_;
+ const typename ParamGenerator<T5>::iterator end5_;
+ typename ParamGenerator<T5>::iterator current5_;
+ const typename ParamGenerator<T6>::iterator begin6_;
+ const typename ParamGenerator<T6>::iterator end6_;
+ typename ParamGenerator<T6>::iterator current6_;
+ ParamType current_value_;
+ }; // class CartesianProductGenerator6::Iterator
+
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductGenerator6& other);
+
+ const ParamGenerator<T1> g1_;
+ const ParamGenerator<T2> g2_;
+ const ParamGenerator<T3> g3_;
+ const ParamGenerator<T4> g4_;
+ const ParamGenerator<T5> g5_;
+ const ParamGenerator<T6> g6_;
+}; // class CartesianProductGenerator6
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7>
+class CartesianProductGenerator7
+ : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+ T7> > {
+ public:
+ typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType;
+
+ CartesianProductGenerator7(const ParamGenerator<T1>& g1,
+ const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+ const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+ const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
+ virtual ~CartesianProductGenerator7() {}
+
+ virtual ParamIteratorInterface<ParamType>* Begin() const {
+ return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+ g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+ g7_.begin());
+ }
+ virtual ParamIteratorInterface<ParamType>* End() const {
+ return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+ g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end());
+ }
+
+ private:
+ class Iterator : public ParamIteratorInterface<ParamType> {
+ public:
+ Iterator(const ParamGeneratorInterface<ParamType>* base,
+ const ParamGenerator<T1>& g1,
+ const typename ParamGenerator<T1>::iterator& current1,
+ const ParamGenerator<T2>& g2,
+ const typename ParamGenerator<T2>::iterator& current2,
+ const ParamGenerator<T3>& g3,
+ const typename ParamGenerator<T3>::iterator& current3,
+ const ParamGenerator<T4>& g4,
+ const typename ParamGenerator<T4>::iterator& current4,
+ const ParamGenerator<T5>& g5,
+ const typename ParamGenerator<T5>::iterator& current5,
+ const ParamGenerator<T6>& g6,
+ const typename ParamGenerator<T6>::iterator& current6,
+ const ParamGenerator<T7>& g7,
+ const typename ParamGenerator<T7>::iterator& current7)
+ : base_(base),
+ begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+ begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+ begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+ begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+ begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+ begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+ begin7_(g7.begin()), end7_(g7.end()), current7_(current7) {
+ ComputeCurrentValue();
+ }
+ virtual ~Iterator() {}
+
+ virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+ return base_;
+ }
+ // Advance should not be called on beyond-of-range iterators
+ // so no component iterators must be beyond end of range, either.
+ virtual void Advance() {
+ assert(!AtEnd());
+ ++current7_;
+ if (current7_ == end7_) {
+ current7_ = begin7_;
+ ++current6_;
+ }
+ if (current6_ == end6_) {
+ current6_ = begin6_;
+ ++current5_;
+ }
+ if (current5_ == end5_) {
+ current5_ = begin5_;
+ ++current4_;
+ }
+ if (current4_ == end4_) {
+ current4_ = begin4_;
+ ++current3_;
+ }
+ if (current3_ == end3_) {
+ current3_ = begin3_;
+ ++current2_;
+ }
+ if (current2_ == end2_) {
+ current2_ = begin2_;
+ ++current1_;
+ }
+ ComputeCurrentValue();
+ }
+ virtual ParamIteratorInterface<ParamType>* Clone() const {
+ return new Iterator(*this);
+ }
+ virtual const ParamType* Current() const { return &current_value_; }
+ virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+ // Having the same base generator guarantees that the other
+ // iterator is of the same type and we can downcast.
+ GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+ << "The program attempted to compare iterators "
+ << "from different generators." << std::endl;
+ const Iterator* typed_other =
+ CheckedDowncastToActualType<const Iterator>(&other);
+ // We must report iterators equal if they both point beyond their
+ // respective ranges. That can happen in a variety of fashions,
+ // so we have to consult AtEnd().
+ return (AtEnd() && typed_other->AtEnd()) ||
+ (
+ current1_ == typed_other->current1_ &&
+ current2_ == typed_other->current2_ &&
+ current3_ == typed_other->current3_ &&
+ current4_ == typed_other->current4_ &&
+ current5_ == typed_other->current5_ &&
+ current6_ == typed_other->current6_ &&
+ current7_ == typed_other->current7_);
+ }
+
+ private:
+ Iterator(const Iterator& other)
+ : base_(other.base_),
+ begin1_(other.begin1_),
+ end1_(other.end1_),
+ current1_(other.current1_),
+ begin2_(other.begin2_),
+ end2_(other.end2_),
+ current2_(other.current2_),
+ begin3_(other.begin3_),
+ end3_(other.end3_),
+ current3_(other.current3_),
+ begin4_(other.begin4_),
+ end4_(other.end4_),
+ current4_(other.current4_),
+ begin5_(other.begin5_),
+ end5_(other.end5_),
+ current5_(other.current5_),
+ begin6_(other.begin6_),
+ end6_(other.end6_),
+ current6_(other.current6_),
+ begin7_(other.begin7_),
+ end7_(other.end7_),
+ current7_(other.current7_) {
+ ComputeCurrentValue();
+ }
+
+ void ComputeCurrentValue() {
+ if (!AtEnd())
+ current_value_ = ParamType(*current1_, *current2_, *current3_,
+ *current4_, *current5_, *current6_, *current7_);
+ }
+ bool AtEnd() const {
+ // We must report iterator past the end of the range when either of the
+ // component iterators has reached the end of its range.
+ return
+ current1_ == end1_ ||
+ current2_ == end2_ ||
+ current3_ == end3_ ||
+ current4_ == end4_ ||
+ current5_ == end5_ ||
+ current6_ == end6_ ||
+ current7_ == end7_;
+ }
+
+ // No implementation - assignment is unsupported.
+ void operator=(const Iterator& other);
+
+ const ParamGeneratorInterface<ParamType>* const base_;
+ // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+ // current[i]_ is the actual traversing iterator.
+ const typename ParamGenerator<T1>::iterator begin1_;
+ const typename ParamGenerator<T1>::iterator end1_;
+ typename ParamGenerator<T1>::iterator current1_;
+ const typename ParamGenerator<T2>::iterator begin2_;
+ const typename ParamGenerator<T2>::iterator end2_;
+ typename ParamGenerator<T2>::iterator current2_;
+ const typename ParamGenerator<T3>::iterator begin3_;
+ const typename ParamGenerator<T3>::iterator end3_;
+ typename ParamGenerator<T3>::iterator current3_;
+ const typename ParamGenerator<T4>::iterator begin4_;
+ const typename ParamGenerator<T4>::iterator end4_;
+ typename ParamGenerator<T4>::iterator current4_;
+ const typename ParamGenerator<T5>::iterator begin5_;
+ const typename ParamGenerator<T5>::iterator end5_;
+ typename ParamGenerator<T5>::iterator current5_;
+ const typename ParamGenerator<T6>::iterator begin6_;
+ const typename ParamGenerator<T6>::iterator end6_;
+ typename ParamGenerator<T6>::iterator current6_;
+ const typename ParamGenerator<T7>::iterator begin7_;
+ const typename ParamGenerator<T7>::iterator end7_;
+ typename ParamGenerator<T7>::iterator current7_;
+ ParamType current_value_;
+ }; // class CartesianProductGenerator7::Iterator
+
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductGenerator7& other);
+
+ const ParamGenerator<T1> g1_;
+ const ParamGenerator<T2> g2_;
+ const ParamGenerator<T3> g3_;
+ const ParamGenerator<T4> g4_;
+ const ParamGenerator<T5> g5_;
+ const ParamGenerator<T6> g6_;
+ const ParamGenerator<T7> g7_;
+}; // class CartesianProductGenerator7
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8>
+class CartesianProductGenerator8
+ : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+ T7, T8> > {
+ public:
+ typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType;
+
+ CartesianProductGenerator8(const ParamGenerator<T1>& g1,
+ const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+ const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+ const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+ const ParamGenerator<T8>& g8)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
+ g8_(g8) {}
+ virtual ~CartesianProductGenerator8() {}
+
+ virtual ParamIteratorInterface<ParamType>* Begin() const {
+ return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+ g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+ g7_.begin(), g8_, g8_.begin());
+ }
+ virtual ParamIteratorInterface<ParamType>* End() const {
+ return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+ g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+ g8_.end());
+ }
+
+ private:
+ class Iterator : public ParamIteratorInterface<ParamType> {
+ public:
+ Iterator(const ParamGeneratorInterface<ParamType>* base,
+ const ParamGenerator<T1>& g1,
+ const typename ParamGenerator<T1>::iterator& current1,
+ const ParamGenerator<T2>& g2,
+ const typename ParamGenerator<T2>::iterator& current2,
+ const ParamGenerator<T3>& g3,
+ const typename ParamGenerator<T3>::iterator& current3,
+ const ParamGenerator<T4>& g4,
+ const typename ParamGenerator<T4>::iterator& current4,
+ const ParamGenerator<T5>& g5,
+ const typename ParamGenerator<T5>::iterator& current5,
+ const ParamGenerator<T6>& g6,
+ const typename ParamGenerator<T6>::iterator& current6,
+ const ParamGenerator<T7>& g7,
+ const typename ParamGenerator<T7>::iterator& current7,
+ const ParamGenerator<T8>& g8,
+ const typename ParamGenerator<T8>::iterator& current8)
+ : base_(base),
+ begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+ begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+ begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+ begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+ begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+ begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+ begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+ begin8_(g8.begin()), end8_(g8.end()), current8_(current8) {
+ ComputeCurrentValue();
+ }
+ virtual ~Iterator() {}
+
+ virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+ return base_;
+ }
+ // Advance should not be called on beyond-of-range iterators
+ // so no component iterators must be beyond end of range, either.
+ virtual void Advance() {
+ assert(!AtEnd());
+ ++current8_;
+ if (current8_ == end8_) {
+ current8_ = begin8_;
+ ++current7_;
+ }
+ if (current7_ == end7_) {
+ current7_ = begin7_;
+ ++current6_;
+ }
+ if (current6_ == end6_) {
+ current6_ = begin6_;
+ ++current5_;
+ }
+ if (current5_ == end5_) {
+ current5_ = begin5_;
+ ++current4_;
+ }
+ if (current4_ == end4_) {
+ current4_ = begin4_;
+ ++current3_;
+ }
+ if (current3_ == end3_) {
+ current3_ = begin3_;
+ ++current2_;
+ }
+ if (current2_ == end2_) {
+ current2_ = begin2_;
+ ++current1_;
+ }
+ ComputeCurrentValue();
+ }
+ virtual ParamIteratorInterface<ParamType>* Clone() const {
+ return new Iterator(*this);
+ }
+ virtual const ParamType* Current() const { return &current_value_; }
+ virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+ // Having the same base generator guarantees that the other
+ // iterator is of the same type and we can downcast.
+ GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+ << "The program attempted to compare iterators "
+ << "from different generators." << std::endl;
+ const Iterator* typed_other =
+ CheckedDowncastToActualType<const Iterator>(&other);
+ // We must report iterators equal if they both point beyond their
+ // respective ranges. That can happen in a variety of fashions,
+ // so we have to consult AtEnd().
+ return (AtEnd() && typed_other->AtEnd()) ||
+ (
+ current1_ == typed_other->current1_ &&
+ current2_ == typed_other->current2_ &&
+ current3_ == typed_other->current3_ &&
+ current4_ == typed_other->current4_ &&
+ current5_ == typed_other->current5_ &&
+ current6_ == typed_other->current6_ &&
+ current7_ == typed_other->current7_ &&
+ current8_ == typed_other->current8_);
+ }
+
+ private:
+ Iterator(const Iterator& other)
+ : base_(other.base_),
+ begin1_(other.begin1_),
+ end1_(other.end1_),
+ current1_(other.current1_),
+ begin2_(other.begin2_),
+ end2_(other.end2_),
+ current2_(other.current2_),
+ begin3_(other.begin3_),
+ end3_(other.end3_),
+ current3_(other.current3_),
+ begin4_(other.begin4_),
+ end4_(other.end4_),
+ current4_(other.current4_),
+ begin5_(other.begin5_),
+ end5_(other.end5_),
+ current5_(other.current5_),
+ begin6_(other.begin6_),
+ end6_(other.end6_),
+ current6_(other.current6_),
+ begin7_(other.begin7_),
+ end7_(other.end7_),
+ current7_(other.current7_),
+ begin8_(other.begin8_),
+ end8_(other.end8_),
+ current8_(other.current8_) {
+ ComputeCurrentValue();
+ }
+
+ void ComputeCurrentValue() {
+ if (!AtEnd())
+ current_value_ = ParamType(*current1_, *current2_, *current3_,
+ *current4_, *current5_, *current6_, *current7_, *current8_);
+ }
+ bool AtEnd() const {
+ // We must report iterator past the end of the range when either of the
+ // component iterators has reached the end of its range.
+ return
+ current1_ == end1_ ||
+ current2_ == end2_ ||
+ current3_ == end3_ ||
+ current4_ == end4_ ||
+ current5_ == end5_ ||
+ current6_ == end6_ ||
+ current7_ == end7_ ||
+ current8_ == end8_;
+ }
+
+ // No implementation - assignment is unsupported.
+ void operator=(const Iterator& other);
+
+ const ParamGeneratorInterface<ParamType>* const base_;
+ // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+ // current[i]_ is the actual traversing iterator.
+ const typename ParamGenerator<T1>::iterator begin1_;
+ const typename ParamGenerator<T1>::iterator end1_;
+ typename ParamGenerator<T1>::iterator current1_;
+ const typename ParamGenerator<T2>::iterator begin2_;
+ const typename ParamGenerator<T2>::iterator end2_;
+ typename ParamGenerator<T2>::iterator current2_;
+ const typename ParamGenerator<T3>::iterator begin3_;
+ const typename ParamGenerator<T3>::iterator end3_;
+ typename ParamGenerator<T3>::iterator current3_;
+ const typename ParamGenerator<T4>::iterator begin4_;
+ const typename ParamGenerator<T4>::iterator end4_;
+ typename ParamGenerator<T4>::iterator current4_;
+ const typename ParamGenerator<T5>::iterator begin5_;
+ const typename ParamGenerator<T5>::iterator end5_;
+ typename ParamGenerator<T5>::iterator current5_;
+ const typename ParamGenerator<T6>::iterator begin6_;
+ const typename ParamGenerator<T6>::iterator end6_;
+ typename ParamGenerator<T6>::iterator current6_;
+ const typename ParamGenerator<T7>::iterator begin7_;
+ const typename ParamGenerator<T7>::iterator end7_;
+ typename ParamGenerator<T7>::iterator current7_;
+ const typename ParamGenerator<T8>::iterator begin8_;
+ const typename ParamGenerator<T8>::iterator end8_;
+ typename ParamGenerator<T8>::iterator current8_;
+ ParamType current_value_;
+ }; // class CartesianProductGenerator8::Iterator
+
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductGenerator8& other);
+
+ const ParamGenerator<T1> g1_;
+ const ParamGenerator<T2> g2_;
+ const ParamGenerator<T3> g3_;
+ const ParamGenerator<T4> g4_;
+ const ParamGenerator<T5> g5_;
+ const ParamGenerator<T6> g6_;
+ const ParamGenerator<T7> g7_;
+ const ParamGenerator<T8> g8_;
+}; // class CartesianProductGenerator8
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9>
+class CartesianProductGenerator9
+ : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+ T7, T8, T9> > {
+ public:
+ typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType;
+
+ CartesianProductGenerator9(const ParamGenerator<T1>& g1,
+ const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+ const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+ const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+ const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+ g9_(g9) {}
+ virtual ~CartesianProductGenerator9() {}
+
+ virtual ParamIteratorInterface<ParamType>* Begin() const {
+ return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+ g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+ g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin());
+ }
+ virtual ParamIteratorInterface<ParamType>* End() const {
+ return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+ g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+ g8_.end(), g9_, g9_.end());
+ }
+
+ private:
+ class Iterator : public ParamIteratorInterface<ParamType> {
+ public:
+ Iterator(const ParamGeneratorInterface<ParamType>* base,
+ const ParamGenerator<T1>& g1,
+ const typename ParamGenerator<T1>::iterator& current1,
+ const ParamGenerator<T2>& g2,
+ const typename ParamGenerator<T2>::iterator& current2,
+ const ParamGenerator<T3>& g3,
+ const typename ParamGenerator<T3>::iterator& current3,
+ const ParamGenerator<T4>& g4,
+ const typename ParamGenerator<T4>::iterator& current4,
+ const ParamGenerator<T5>& g5,
+ const typename ParamGenerator<T5>::iterator& current5,
+ const ParamGenerator<T6>& g6,
+ const typename ParamGenerator<T6>::iterator& current6,
+ const ParamGenerator<T7>& g7,
+ const typename ParamGenerator<T7>::iterator& current7,
+ const ParamGenerator<T8>& g8,
+ const typename ParamGenerator<T8>::iterator& current8,
+ const ParamGenerator<T9>& g9,
+ const typename ParamGenerator<T9>::iterator& current9)
+ : base_(base),
+ begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+ begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+ begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+ begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+ begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+ begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+ begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+ begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
+ begin9_(g9.begin()), end9_(g9.end()), current9_(current9) {
+ ComputeCurrentValue();
+ }
+ virtual ~Iterator() {}
+
+ virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+ return base_;
+ }
+ // Advance should not be called on beyond-of-range iterators
+ // so no component iterators must be beyond end of range, either.
+ virtual void Advance() {
+ assert(!AtEnd());
+ ++current9_;
+ if (current9_ == end9_) {
+ current9_ = begin9_;
+ ++current8_;
+ }
+ if (current8_ == end8_) {
+ current8_ = begin8_;
+ ++current7_;
+ }
+ if (current7_ == end7_) {
+ current7_ = begin7_;
+ ++current6_;
+ }
+ if (current6_ == end6_) {
+ current6_ = begin6_;
+ ++current5_;
+ }
+ if (current5_ == end5_) {
+ current5_ = begin5_;
+ ++current4_;
+ }
+ if (current4_ == end4_) {
+ current4_ = begin4_;
+ ++current3_;
+ }
+ if (current3_ == end3_) {
+ current3_ = begin3_;
+ ++current2_;
+ }
+ if (current2_ == end2_) {
+ current2_ = begin2_;
+ ++current1_;
+ }
+ ComputeCurrentValue();
+ }
+ virtual ParamIteratorInterface<ParamType>* Clone() const {
+ return new Iterator(*this);
+ }
+ virtual const ParamType* Current() const { return &current_value_; }
+ virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+ // Having the same base generator guarantees that the other
+ // iterator is of the same type and we can downcast.
+ GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+ << "The program attempted to compare iterators "
+ << "from different generators." << std::endl;
+ const Iterator* typed_other =
+ CheckedDowncastToActualType<const Iterator>(&other);
+ // We must report iterators equal if they both point beyond their
+ // respective ranges. That can happen in a variety of fashions,
+ // so we have to consult AtEnd().
+ return (AtEnd() && typed_other->AtEnd()) ||
+ (
+ current1_ == typed_other->current1_ &&
+ current2_ == typed_other->current2_ &&
+ current3_ == typed_other->current3_ &&
+ current4_ == typed_other->current4_ &&
+ current5_ == typed_other->current5_ &&
+ current6_ == typed_other->current6_ &&
+ current7_ == typed_other->current7_ &&
+ current8_ == typed_other->current8_ &&
+ current9_ == typed_other->current9_);
+ }
+
+ private:
+ Iterator(const Iterator& other)
+ : base_(other.base_),
+ begin1_(other.begin1_),
+ end1_(other.end1_),
+ current1_(other.current1_),
+ begin2_(other.begin2_),
+ end2_(other.end2_),
+ current2_(other.current2_),
+ begin3_(other.begin3_),
+ end3_(other.end3_),
+ current3_(other.current3_),
+ begin4_(other.begin4_),
+ end4_(other.end4_),
+ current4_(other.current4_),
+ begin5_(other.begin5_),
+ end5_(other.end5_),
+ current5_(other.current5_),
+ begin6_(other.begin6_),
+ end6_(other.end6_),
+ current6_(other.current6_),
+ begin7_(other.begin7_),
+ end7_(other.end7_),
+ current7_(other.current7_),
+ begin8_(other.begin8_),
+ end8_(other.end8_),
+ current8_(other.current8_),
+ begin9_(other.begin9_),
+ end9_(other.end9_),
+ current9_(other.current9_) {
+ ComputeCurrentValue();
+ }
+
+ void ComputeCurrentValue() {
+ if (!AtEnd())
+ current_value_ = ParamType(*current1_, *current2_, *current3_,
+ *current4_, *current5_, *current6_, *current7_, *current8_,
+ *current9_);
+ }
+ bool AtEnd() const {
+ // We must report iterator past the end of the range when either of the
+ // component iterators has reached the end of its range.
+ return
+ current1_ == end1_ ||
+ current2_ == end2_ ||
+ current3_ == end3_ ||
+ current4_ == end4_ ||
+ current5_ == end5_ ||
+ current6_ == end6_ ||
+ current7_ == end7_ ||
+ current8_ == end8_ ||
+ current9_ == end9_;
+ }
+
+ // No implementation - assignment is unsupported.
+ void operator=(const Iterator& other);
+
+ const ParamGeneratorInterface<ParamType>* const base_;
+ // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+ // current[i]_ is the actual traversing iterator.
+ const typename ParamGenerator<T1>::iterator begin1_;
+ const typename ParamGenerator<T1>::iterator end1_;
+ typename ParamGenerator<T1>::iterator current1_;
+ const typename ParamGenerator<T2>::iterator begin2_;
+ const typename ParamGenerator<T2>::iterator end2_;
+ typename ParamGenerator<T2>::iterator current2_;
+ const typename ParamGenerator<T3>::iterator begin3_;
+ const typename ParamGenerator<T3>::iterator end3_;
+ typename ParamGenerator<T3>::iterator current3_;
+ const typename ParamGenerator<T4>::iterator begin4_;
+ const typename ParamGenerator<T4>::iterator end4_;
+ typename ParamGenerator<T4>::iterator current4_;
+ const typename ParamGenerator<T5>::iterator begin5_;
+ const typename ParamGenerator<T5>::iterator end5_;
+ typename ParamGenerator<T5>::iterator current5_;
+ const typename ParamGenerator<T6>::iterator begin6_;
+ const typename ParamGenerator<T6>::iterator end6_;
+ typename ParamGenerator<T6>::iterator current6_;
+ const typename ParamGenerator<T7>::iterator begin7_;
+ const typename ParamGenerator<T7>::iterator end7_;
+ typename ParamGenerator<T7>::iterator current7_;
+ const typename ParamGenerator<T8>::iterator begin8_;
+ const typename ParamGenerator<T8>::iterator end8_;
+ typename ParamGenerator<T8>::iterator current8_;
+ const typename ParamGenerator<T9>::iterator begin9_;
+ const typename ParamGenerator<T9>::iterator end9_;
+ typename ParamGenerator<T9>::iterator current9_;
+ ParamType current_value_;
+ }; // class CartesianProductGenerator9::Iterator
+
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductGenerator9& other);
+
+ const ParamGenerator<T1> g1_;
+ const ParamGenerator<T2> g2_;
+ const ParamGenerator<T3> g3_;
+ const ParamGenerator<T4> g4_;
+ const ParamGenerator<T5> g5_;
+ const ParamGenerator<T6> g6_;
+ const ParamGenerator<T7> g7_;
+ const ParamGenerator<T8> g8_;
+ const ParamGenerator<T9> g9_;
+}; // class CartesianProductGenerator9
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+class CartesianProductGenerator10
+ : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+ T7, T8, T9, T10> > {
+ public:
+ typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType;
+
+ CartesianProductGenerator10(const ParamGenerator<T1>& g1,
+ const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+ const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+ const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+ const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9,
+ const ParamGenerator<T10>& g10)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+ g9_(g9), g10_(g10) {}
+ virtual ~CartesianProductGenerator10() {}
+
+ virtual ParamIteratorInterface<ParamType>* Begin() const {
+ return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+ g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+ g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin());
+ }
+ virtual ParamIteratorInterface<ParamType>* End() const {
+ return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+ g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+ g8_.end(), g9_, g9_.end(), g10_, g10_.end());
+ }
+
+ private:
+ class Iterator : public ParamIteratorInterface<ParamType> {
+ public:
+ Iterator(const ParamGeneratorInterface<ParamType>* base,
+ const ParamGenerator<T1>& g1,
+ const typename ParamGenerator<T1>::iterator& current1,
+ const ParamGenerator<T2>& g2,
+ const typename ParamGenerator<T2>::iterator& current2,
+ const ParamGenerator<T3>& g3,
+ const typename ParamGenerator<T3>::iterator& current3,
+ const ParamGenerator<T4>& g4,
+ const typename ParamGenerator<T4>::iterator& current4,
+ const ParamGenerator<T5>& g5,
+ const typename ParamGenerator<T5>::iterator& current5,
+ const ParamGenerator<T6>& g6,
+ const typename ParamGenerator<T6>::iterator& current6,
+ const ParamGenerator<T7>& g7,
+ const typename ParamGenerator<T7>::iterator& current7,
+ const ParamGenerator<T8>& g8,
+ const typename ParamGenerator<T8>::iterator& current8,
+ const ParamGenerator<T9>& g9,
+ const typename ParamGenerator<T9>::iterator& current9,
+ const ParamGenerator<T10>& g10,
+ const typename ParamGenerator<T10>::iterator& current10)
+ : base_(base),
+ begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+ begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+ begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+ begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+ begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+ begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+ begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+ begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
+ begin9_(g9.begin()), end9_(g9.end()), current9_(current9),
+ begin10_(g10.begin()), end10_(g10.end()), current10_(current10) {
+ ComputeCurrentValue();
+ }
+ virtual ~Iterator() {}
+
+ virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+ return base_;
+ }
+ // Advance should not be called on beyond-of-range iterators
+ // so no component iterators must be beyond end of range, either.
+ virtual void Advance() {
+ assert(!AtEnd());
+ ++current10_;
+ if (current10_ == end10_) {
+ current10_ = begin10_;
+ ++current9_;
+ }
+ if (current9_ == end9_) {
+ current9_ = begin9_;
+ ++current8_;
+ }
+ if (current8_ == end8_) {
+ current8_ = begin8_;
+ ++current7_;
+ }
+ if (current7_ == end7_) {
+ current7_ = begin7_;
+ ++current6_;
+ }
+ if (current6_ == end6_) {
+ current6_ = begin6_;
+ ++current5_;
+ }
+ if (current5_ == end5_) {
+ current5_ = begin5_;
+ ++current4_;
+ }
+ if (current4_ == end4_) {
+ current4_ = begin4_;
+ ++current3_;
+ }
+ if (current3_ == end3_) {
+ current3_ = begin3_;
+ ++current2_;
+ }
+ if (current2_ == end2_) {
+ current2_ = begin2_;
+ ++current1_;
+ }
+ ComputeCurrentValue();
+ }
+ virtual ParamIteratorInterface<ParamType>* Clone() const {
+ return new Iterator(*this);
+ }
+ virtual const ParamType* Current() const { return &current_value_; }
+ virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+ // Having the same base generator guarantees that the other
+ // iterator is of the same type and we can downcast.
+ GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+ << "The program attempted to compare iterators "
+ << "from different generators." << std::endl;
+ const Iterator* typed_other =
+ CheckedDowncastToActualType<const Iterator>(&other);
+ // We must report iterators equal if they both point beyond their
+ // respective ranges. That can happen in a variety of fashions,
+ // so we have to consult AtEnd().
+ return (AtEnd() && typed_other->AtEnd()) ||
+ (
+ current1_ == typed_other->current1_ &&
+ current2_ == typed_other->current2_ &&
+ current3_ == typed_other->current3_ &&
+ current4_ == typed_other->current4_ &&
+ current5_ == typed_other->current5_ &&
+ current6_ == typed_other->current6_ &&
+ current7_ == typed_other->current7_ &&
+ current8_ == typed_other->current8_ &&
+ current9_ == typed_other->current9_ &&
+ current10_ == typed_other->current10_);
+ }
+
+ private:
+ Iterator(const Iterator& other)
+ : base_(other.base_),
+ begin1_(other.begin1_),
+ end1_(other.end1_),
+ current1_(other.current1_),
+ begin2_(other.begin2_),
+ end2_(other.end2_),
+ current2_(other.current2_),
+ begin3_(other.begin3_),
+ end3_(other.end3_),
+ current3_(other.current3_),
+ begin4_(other.begin4_),
+ end4_(other.end4_),
+ current4_(other.current4_),
+ begin5_(other.begin5_),
+ end5_(other.end5_),
+ current5_(other.current5_),
+ begin6_(other.begin6_),
+ end6_(other.end6_),
+ current6_(other.current6_),
+ begin7_(other.begin7_),
+ end7_(other.end7_),
+ current7_(other.current7_),
+ begin8_(other.begin8_),
+ end8_(other.end8_),
+ current8_(other.current8_),
+ begin9_(other.begin9_),
+ end9_(other.end9_),
+ current9_(other.current9_),
+ begin10_(other.begin10_),
+ end10_(other.end10_),
+ current10_(other.current10_) {
+ ComputeCurrentValue();
+ }
+
+ void ComputeCurrentValue() {
+ if (!AtEnd())
+ current_value_ = ParamType(*current1_, *current2_, *current3_,
+ *current4_, *current5_, *current6_, *current7_, *current8_,
+ *current9_, *current10_);
+ }
+ bool AtEnd() const {
+ // We must report iterator past the end of the range when either of the
+ // component iterators has reached the end of its range.
+ return
+ current1_ == end1_ ||
+ current2_ == end2_ ||
+ current3_ == end3_ ||
+ current4_ == end4_ ||
+ current5_ == end5_ ||
+ current6_ == end6_ ||
+ current7_ == end7_ ||
+ current8_ == end8_ ||
+ current9_ == end9_ ||
+ current10_ == end10_;
+ }
+
+ // No implementation - assignment is unsupported.
+ void operator=(const Iterator& other);
+
+ const ParamGeneratorInterface<ParamType>* const base_;
+ // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+ // current[i]_ is the actual traversing iterator.
+ const typename ParamGenerator<T1>::iterator begin1_;
+ const typename ParamGenerator<T1>::iterator end1_;
+ typename ParamGenerator<T1>::iterator current1_;
+ const typename ParamGenerator<T2>::iterator begin2_;
+ const typename ParamGenerator<T2>::iterator end2_;
+ typename ParamGenerator<T2>::iterator current2_;
+ const typename ParamGenerator<T3>::iterator begin3_;
+ const typename ParamGenerator<T3>::iterator end3_;
+ typename ParamGenerator<T3>::iterator current3_;
+ const typename ParamGenerator<T4>::iterator begin4_;
+ const typename ParamGenerator<T4>::iterator end4_;
+ typename ParamGenerator<T4>::iterator current4_;
+ const typename ParamGenerator<T5>::iterator begin5_;
+ const typename ParamGenerator<T5>::iterator end5_;
+ typename ParamGenerator<T5>::iterator current5_;
+ const typename ParamGenerator<T6>::iterator begin6_;
+ const typename ParamGenerator<T6>::iterator end6_;
+ typename ParamGenerator<T6>::iterator current6_;
+ const typename ParamGenerator<T7>::iterator begin7_;
+ const typename ParamGenerator<T7>::iterator end7_;
+ typename ParamGenerator<T7>::iterator current7_;
+ const typename ParamGenerator<T8>::iterator begin8_;
+ const typename ParamGenerator<T8>::iterator end8_;
+ typename ParamGenerator<T8>::iterator current8_;
+ const typename ParamGenerator<T9>::iterator begin9_;
+ const typename ParamGenerator<T9>::iterator end9_;
+ typename ParamGenerator<T9>::iterator current9_;
+ const typename ParamGenerator<T10>::iterator begin10_;
+ const typename ParamGenerator<T10>::iterator end10_;
+ typename ParamGenerator<T10>::iterator current10_;
+ ParamType current_value_;
+ }; // class CartesianProductGenerator10::Iterator
+
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductGenerator10& other);
+
+ const ParamGenerator<T1> g1_;
+ const ParamGenerator<T2> g2_;
+ const ParamGenerator<T3> g3_;
+ const ParamGenerator<T4> g4_;
+ const ParamGenerator<T5> g5_;
+ const ParamGenerator<T6> g6_;
+ const ParamGenerator<T7> g7_;
+ const ParamGenerator<T8> g8_;
+ const ParamGenerator<T9> g9_;
+ const ParamGenerator<T10> g10_;
+}; // class CartesianProductGenerator10
+
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Helper classes providing Combine() with polymorphic features. They allow
+// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
+// convertible to U.
+//
+template <class Generator1, class Generator2>
+class CartesianProductHolder2 {
+ public:
+CartesianProductHolder2(const Generator1& g1, const Generator2& g2)
+ : g1_(g1), g2_(g2) {}
+ template <typename T1, typename T2>
+ operator ParamGenerator< ::std::tr1::tuple<T1, T2> >() const {
+ return ParamGenerator< ::std::tr1::tuple<T1, T2> >(
+ new CartesianProductGenerator2<T1, T2>(
+ static_cast<ParamGenerator<T1> >(g1_),
+ static_cast<ParamGenerator<T2> >(g2_)));
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductHolder2& other);
+
+ const Generator1 g1_;
+ const Generator2 g2_;
+}; // class CartesianProductHolder2
+
+template <class Generator1, class Generator2, class Generator3>
+class CartesianProductHolder3 {
+ public:
+CartesianProductHolder3(const Generator1& g1, const Generator2& g2,
+ const Generator3& g3)
+ : g1_(g1), g2_(g2), g3_(g3) {}
+ template <typename T1, typename T2, typename T3>
+ operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >() const {
+ return ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >(
+ new CartesianProductGenerator3<T1, T2, T3>(
+ static_cast<ParamGenerator<T1> >(g1_),
+ static_cast<ParamGenerator<T2> >(g2_),
+ static_cast<ParamGenerator<T3> >(g3_)));
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductHolder3& other);
+
+ const Generator1 g1_;
+ const Generator2 g2_;
+ const Generator3 g3_;
+}; // class CartesianProductHolder3
+
+template <class Generator1, class Generator2, class Generator3,
+ class Generator4>
+class CartesianProductHolder4 {
+ public:
+CartesianProductHolder4(const Generator1& g1, const Generator2& g2,
+ const Generator3& g3, const Generator4& g4)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
+ template <typename T1, typename T2, typename T3, typename T4>
+ operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >() const {
+ return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >(
+ new CartesianProductGenerator4<T1, T2, T3, T4>(
+ static_cast<ParamGenerator<T1> >(g1_),
+ static_cast<ParamGenerator<T2> >(g2_),
+ static_cast<ParamGenerator<T3> >(g3_),
+ static_cast<ParamGenerator<T4> >(g4_)));
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductHolder4& other);
+
+ const Generator1 g1_;
+ const Generator2 g2_;
+ const Generator3 g3_;
+ const Generator4 g4_;
+}; // class CartesianProductHolder4
+
+template <class Generator1, class Generator2, class Generator3,
+ class Generator4, class Generator5>
+class CartesianProductHolder5 {
+ public:
+CartesianProductHolder5(const Generator1& g1, const Generator2& g2,
+ const Generator3& g3, const Generator4& g4, const Generator5& g5)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
+ template <typename T1, typename T2, typename T3, typename T4, typename T5>
+ operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >() const {
+ return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >(
+ new CartesianProductGenerator5<T1, T2, T3, T4, T5>(
+ static_cast<ParamGenerator<T1> >(g1_),
+ static_cast<ParamGenerator<T2> >(g2_),
+ static_cast<ParamGenerator<T3> >(g3_),
+ static_cast<ParamGenerator<T4> >(g4_),
+ static_cast<ParamGenerator<T5> >(g5_)));
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductHolder5& other);
+
+ const Generator1 g1_;
+ const Generator2 g2_;
+ const Generator3 g3_;
+ const Generator4 g4_;
+ const Generator5 g5_;
+}; // class CartesianProductHolder5
+
+template <class Generator1, class Generator2, class Generator3,
+ class Generator4, class Generator5, class Generator6>
+class CartesianProductHolder6 {
+ public:
+CartesianProductHolder6(const Generator1& g1, const Generator2& g2,
+ const Generator3& g3, const Generator4& g4, const Generator5& g5,
+ const Generator6& g6)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+ operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >() const {
+ return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >(
+ new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>(
+ static_cast<ParamGenerator<T1> >(g1_),
+ static_cast<ParamGenerator<T2> >(g2_),
+ static_cast<ParamGenerator<T3> >(g3_),
+ static_cast<ParamGenerator<T4> >(g4_),
+ static_cast<ParamGenerator<T5> >(g5_),
+ static_cast<ParamGenerator<T6> >(g6_)));
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductHolder6& other);
+
+ const Generator1 g1_;
+ const Generator2 g2_;
+ const Generator3 g3_;
+ const Generator4 g4_;
+ const Generator5 g5_;
+ const Generator6 g6_;
+}; // class CartesianProductHolder6
+
+template <class Generator1, class Generator2, class Generator3,
+ class Generator4, class Generator5, class Generator6, class Generator7>
+class CartesianProductHolder7 {
+ public:
+CartesianProductHolder7(const Generator1& g1, const Generator2& g2,
+ const Generator3& g3, const Generator4& g4, const Generator5& g5,
+ const Generator6& g6, const Generator7& g7)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7>
+ operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+ T7> >() const {
+ return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >(
+ new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>(
+ static_cast<ParamGenerator<T1> >(g1_),
+ static_cast<ParamGenerator<T2> >(g2_),
+ static_cast<ParamGenerator<T3> >(g3_),
+ static_cast<ParamGenerator<T4> >(g4_),
+ static_cast<ParamGenerator<T5> >(g5_),
+ static_cast<ParamGenerator<T6> >(g6_),
+ static_cast<ParamGenerator<T7> >(g7_)));
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductHolder7& other);
+
+ const Generator1 g1_;
+ const Generator2 g2_;
+ const Generator3 g3_;
+ const Generator4 g4_;
+ const Generator5 g5_;
+ const Generator6 g6_;
+ const Generator7 g7_;
+}; // class CartesianProductHolder7
+
+template <class Generator1, class Generator2, class Generator3,
+ class Generator4, class Generator5, class Generator6, class Generator7,
+ class Generator8>
+class CartesianProductHolder8 {
+ public:
+CartesianProductHolder8(const Generator1& g1, const Generator2& g2,
+ const Generator3& g3, const Generator4& g4, const Generator5& g5,
+ const Generator6& g6, const Generator7& g7, const Generator8& g8)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
+ g8_(g8) {}
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8>
+ operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7,
+ T8> >() const {
+ return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >(
+ new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>(
+ static_cast<ParamGenerator<T1> >(g1_),
+ static_cast<ParamGenerator<T2> >(g2_),
+ static_cast<ParamGenerator<T3> >(g3_),
+ static_cast<ParamGenerator<T4> >(g4_),
+ static_cast<ParamGenerator<T5> >(g5_),
+ static_cast<ParamGenerator<T6> >(g6_),
+ static_cast<ParamGenerator<T7> >(g7_),
+ static_cast<ParamGenerator<T8> >(g8_)));
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductHolder8& other);
+
+ const Generator1 g1_;
+ const Generator2 g2_;
+ const Generator3 g3_;
+ const Generator4 g4_;
+ const Generator5 g5_;
+ const Generator6 g6_;
+ const Generator7 g7_;
+ const Generator8 g8_;
+}; // class CartesianProductHolder8
+
+template <class Generator1, class Generator2, class Generator3,
+ class Generator4, class Generator5, class Generator6, class Generator7,
+ class Generator8, class Generator9>
+class CartesianProductHolder9 {
+ public:
+CartesianProductHolder9(const Generator1& g1, const Generator2& g2,
+ const Generator3& g3, const Generator4& g4, const Generator5& g5,
+ const Generator6& g6, const Generator7& g7, const Generator8& g8,
+ const Generator9& g9)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+ g9_(g9) {}
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9>
+ operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+ T9> >() const {
+ return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+ T9> >(
+ new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+ static_cast<ParamGenerator<T1> >(g1_),
+ static_cast<ParamGenerator<T2> >(g2_),
+ static_cast<ParamGenerator<T3> >(g3_),
+ static_cast<ParamGenerator<T4> >(g4_),
+ static_cast<ParamGenerator<T5> >(g5_),
+ static_cast<ParamGenerator<T6> >(g6_),
+ static_cast<ParamGenerator<T7> >(g7_),
+ static_cast<ParamGenerator<T8> >(g8_),
+ static_cast<ParamGenerator<T9> >(g9_)));
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductHolder9& other);
+
+ const Generator1 g1_;
+ const Generator2 g2_;
+ const Generator3 g3_;
+ const Generator4 g4_;
+ const Generator5 g5_;
+ const Generator6 g6_;
+ const Generator7 g7_;
+ const Generator8 g8_;
+ const Generator9 g9_;
+}; // class CartesianProductHolder9
+
+template <class Generator1, class Generator2, class Generator3,
+ class Generator4, class Generator5, class Generator6, class Generator7,
+ class Generator8, class Generator9, class Generator10>
+class CartesianProductHolder10 {
+ public:
+CartesianProductHolder10(const Generator1& g1, const Generator2& g2,
+ const Generator3& g3, const Generator4& g4, const Generator5& g5,
+ const Generator6& g6, const Generator7& g7, const Generator8& g8,
+ const Generator9& g9, const Generator10& g10)
+ : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+ g9_(g9), g10_(g10) {}
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+ operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+ T9, T10> >() const {
+ return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+ T9, T10> >(
+ new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
+ T10>(
+ static_cast<ParamGenerator<T1> >(g1_),
+ static_cast<ParamGenerator<T2> >(g2_),
+ static_cast<ParamGenerator<T3> >(g3_),
+ static_cast<ParamGenerator<T4> >(g4_),
+ static_cast<ParamGenerator<T5> >(g5_),
+ static_cast<ParamGenerator<T6> >(g6_),
+ static_cast<ParamGenerator<T7> >(g7_),
+ static_cast<ParamGenerator<T8> >(g8_),
+ static_cast<ParamGenerator<T9> >(g9_),
+ static_cast<ParamGenerator<T10> >(g10_)));
+ }
+
+ private:
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductHolder10& other);
+
+ const Generator1 g1_;
+ const Generator2 g2_;
+ const Generator3 g3_;
+ const Generator4 g4_;
+ const Generator5 g5_;
+ const Generator6 g6_;
+ const Generator7 g7_;
+ const Generator8 g8_;
+ const Generator9 g9_;
+ const Generator10 g10_;
+}; // class CartesianProductHolder10
+
+#endif // GTEST_HAS_COMBINE
+
+} // namespace internal
+} // namespace testing
+
+#endif // GTEST_HAS_PARAM_TEST
+
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+
+// Functions producing parameter generators.
+//
+// Google Test uses these generators to produce parameters for value-
+// parameterized tests. When a parameterized test case is instantiated
+// with a particular generator, Google Test creates and runs tests
+// for each element in the sequence produced by the generator.
+//
+// In the following sample, tests from test case FooTest are instantiated
+// each three times with parameter values 3, 5, and 8:
+//
+// class FooTest : public TestWithParam<int> { ... };
+//
+// TEST_P(FooTest, TestThis) {
+// }
+// TEST_P(FooTest, TestThat) {
+// }
+// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
+//
+
+// Range() returns generators providing sequences of values in a range.
+//
+// Synopsis:
+// Range(start, end)
+// - returns a generator producing a sequence of values {start, start+1,
+// start+2, ..., }.
+// Range(start, end, step)
+// - returns a generator producing a sequence of values {start, start+step,
+// start+step+step, ..., }.
+// Notes:
+// * The generated sequences never include end. For example, Range(1, 5)
+// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
+// returns a generator producing {1, 3, 5, 7}.
+// * start and end must have the same type. That type may be any integral or
+// floating-point type or a user defined type satisfying these conditions:
+// * It must be assignable (have operator=() defined).
+// * It must have operator+() (operator+(int-compatible type) for
+// two-operand version).
+// * It must have operator<() defined.
+// Elements in the resulting sequences will also have that type.
+// * Condition start < end must be satisfied in order for resulting sequences
+// to contain any elements.
+//
+template <typename T, typename IncrementT>
+internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
+ return internal::ParamGenerator<T>(
+ new internal::RangeGenerator<T, IncrementT>(start, end, step));
+}
+
+template <typename T>
+internal::ParamGenerator<T> Range(T start, T end) {
+ return Range(start, end, 1);
+}
+
+// ValuesIn() function allows generation of tests with parameters coming from
+// a container.
+//
+// Synopsis:
+// ValuesIn(const T (&array)[N])
+// - returns a generator producing sequences with elements from
+// a C-style array.
+// ValuesIn(const Container& container)
+// - returns a generator producing sequences with elements from
+// an STL-style container.
+// ValuesIn(Iterator begin, Iterator end)
+// - returns a generator producing sequences with elements from
+// a range [begin, end) defined by a pair of STL-style iterators. These
+// iterators can also be plain C pointers.
+//
+// Please note that ValuesIn copies the values from the containers
+// passed in and keeps them to generate tests in RUN_ALL_TESTS().
+//
+// Examples:
+//
+// This instantiates tests from test case StringTest
+// each with C-string values of "foo", "bar", and "baz":
+//
+// const char* strings[] = {"foo", "bar", "baz"};
+// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
+//
+// This instantiates tests from test case StlStringTest
+// each with STL strings with values "a" and "b":
+//
+// ::std::vector< ::std::string> GetParameterStrings() {
+// ::std::vector< ::std::string> v;
+// v.push_back("a");
+// v.push_back("b");
+// return v;
+// }
+//
+// INSTANTIATE_TEST_CASE_P(CharSequence,
+// StlStringTest,
+// ValuesIn(GetParameterStrings()));
+//
+//
+// This will also instantiate tests from CharTest
+// each with parameter values 'a' and 'b':
+//
+// ::std::list<char> GetParameterChars() {
+// ::std::list<char> list;
+// list.push_back('a');
+// list.push_back('b');
+// return list;
+// }
+// ::std::list<char> l = GetParameterChars();
+// INSTANTIATE_TEST_CASE_P(CharSequence2,
+// CharTest,
+// ValuesIn(l.begin(), l.end()));
+//
+template <typename ForwardIterator>
+internal::ParamGenerator<
+ typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
+ ForwardIterator begin,
+ ForwardIterator end) {
+ typedef typename ::std::iterator_traits<ForwardIterator>::value_type
+ ParamType;
+ return internal::ParamGenerator<ParamType>(
+ new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
+}
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
+ return ValuesIn(array, array + N);
+}
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+ const Container& container) {
+ return ValuesIn(container.begin(), container.end());
+}
+
+// Values() allows generating tests from explicitly specified list of
+// parameters.
+//
+// Synopsis:
+// Values(T v1, T v2, ..., T vN)
+// - returns a generator producing sequences with elements v1, v2, ..., vN.
+//
+// For example, this instantiates tests from test case BarTest each
+// with values "one", "two", and "three":
+//
+// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
+//
+// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
+// The exact type of values will depend on the type of parameter in BazTest.
+//
+// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
+//
+// Currently, Values() supports from 1 to 50 parameters.
+//
+template <typename T1>
+internal::ValueArray1<T1> Values(T1 v1) {
+ return internal::ValueArray1<T1>(v1);
+}
+
+template <typename T1, typename T2>
+internal::ValueArray2<T1, T2> Values(T1 v1, T2 v2) {
+ return internal::ValueArray2<T1, T2>(v1, v2);
+}
+
+template <typename T1, typename T2, typename T3>
+internal::ValueArray3<T1, T2, T3> Values(T1 v1, T2 v2, T3 v3) {
+ return internal::ValueArray3<T1, T2, T3>(v1, v2, v3);
+}
+
+template <typename T1, typename T2, typename T3, typename T4>
+internal::ValueArray4<T1, T2, T3, T4> Values(T1 v1, T2 v2, T3 v3, T4 v4) {
+ return internal::ValueArray4<T1, T2, T3, T4>(v1, v2, v3, v4);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+internal::ValueArray5<T1, T2, T3, T4, T5> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+ T5 v5) {
+ return internal::ValueArray5<T1, T2, T3, T4, T5>(v1, v2, v3, v4, v5);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+internal::ValueArray6<T1, T2, T3, T4, T5, T6> Values(T1 v1, T2 v2, T3 v3,
+ T4 v4, T5 v5, T6 v6) {
+ return internal::ValueArray6<T1, T2, T3, T4, T5, T6>(v1, v2, v3, v4, v5, v6);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7>
+internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7> Values(T1 v1, T2 v2, T3 v3,
+ T4 v4, T5 v5, T6 v6, T7 v7) {
+ return internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7>(v1, v2, v3, v4, v5,
+ v6, v7);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8>
+internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8> Values(T1 v1, T2 v2,
+ T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+ return internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8>(v1, v2, v3, v4,
+ v5, v6, v7, v8);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9>
+internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9> Values(T1 v1, T2 v2,
+ T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+ return internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(v1, v2, v3,
+ v4, v5, v6, v7, v8, v9);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Values(T1 v1,
+ T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+ return internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(v1,
+ v2, v3, v4, v5, v6, v7, v8, v9, v10);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11>
+internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
+ T11> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11) {
+ return internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
+ T11>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12>
+internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12) {
+ return internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13>
+internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13) {
+ return internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14>
+internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+ return internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+ v14);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15>
+internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+ T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
+ return internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+ v13, v14, v15);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16>
+internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+ T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+ T16 v16) {
+ return internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+ v12, v13, v14, v15, v16);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17>
+internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+ T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+ T16 v16, T17 v17) {
+ return internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+ v11, v12, v13, v14, v15, v16, v17);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18>
+internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+ T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+ T16 v16, T17 v17, T18 v18) {
+ return internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+ v10, v11, v12, v13, v14, v15, v16, v17, v18);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19>
+internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+ T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+ T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) {
+ return internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19>(v1, v2, v3, v4, v5, v6, v7, v8,
+ v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20>
+internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+ T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+ T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) {
+ return internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20>(v1, v2, v3, v4, v5, v6, v7,
+ v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21>
+internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+ T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+ T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) {
+ return internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(v1, v2, v3, v4, v5, v6,
+ v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22>
+internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22> Values(T1 v1, T2 v2, T3 v3,
+ T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+ T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+ T21 v21, T22 v22) {
+ return internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>(v1, v2, v3, v4,
+ v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+ v20, v21, v22);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23>
+internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> Values(T1 v1, T2 v2,
+ T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+ T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+ T21 v21, T22 v22, T23 v23) {
+ return internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>(v1, v2, v3,
+ v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+ v20, v21, v22, v23);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24>
+internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Values(T1 v1, T2 v2,
+ T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+ T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+ T21 v21, T22 v22, T23 v23, T24 v24) {
+ return internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>(v1, v2,
+ v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
+ v19, v20, v21, v22, v23, v24);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25>
+internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Values(T1 v1,
+ T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
+ T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
+ T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) {
+ return internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25>(v1,
+ v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
+ v18, v19, v20, v21, v22, v23, v24, v25);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26>
+internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26) {
+ return internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
+ v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27>
+internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+ T27> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27) {
+ return internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
+ v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28>
+internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+ T28> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28) {
+ return internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+ v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
+ v28);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29>
+internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29) {
+ return internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+ v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
+ v27, v28, v29);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30>
+internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+ T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+ T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+ T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) {
+ return internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+ v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
+ v26, v27, v28, v29, v30);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31>
+internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+ T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+ T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+ T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) {
+ return internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+ v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
+ v25, v26, v27, v28, v29, v30, v31);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32>
+internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+ T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+ T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+ T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+ T32 v32) {
+ return internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+ v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+ v24, v25, v26, v27, v28, v29, v30, v31, v32);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33>
+internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+ T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+ T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+ T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+ T32 v32, T33 v33) {
+ return internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33>(v1, v2, v3, v4, v5, v6, v7, v8,
+ v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+ v24, v25, v26, v27, v28, v29, v30, v31, v32, v33);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34>
+internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+ T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+ T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
+ T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
+ T31 v31, T32 v32, T33 v33, T34 v34) {
+ return internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34>(v1, v2, v3, v4, v5, v6, v7,
+ v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
+ v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35>
+internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+ T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+ T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+ T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+ T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) {
+ return internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35>(v1, v2, v3, v4, v5, v6,
+ v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
+ v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36>
+internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+ T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+ T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+ T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+ T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) {
+ return internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36>(v1, v2, v3, v4,
+ v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+ v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+ v34, v35, v36);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37>
+internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37> Values(T1 v1, T2 v2, T3 v3,
+ T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+ T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+ T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+ T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+ T37 v37) {
+ return internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37>(v1, v2, v3,
+ v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+ v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+ v34, v35, v36, v37);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38>
+internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Values(T1 v1, T2 v2,
+ T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+ T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+ T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+ T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+ T37 v37, T38 v38) {
+ return internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38>(v1, v2,
+ v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
+ v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32,
+ v33, v34, v35, v36, v37, v38);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39>
+internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Values(T1 v1, T2 v2,
+ T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+ T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+ T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+ T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+ T37 v37, T38 v38, T39 v39) {
+ return internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39>(v1,
+ v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
+ v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
+ v32, v33, v34, v35, v36, v37, v38, v39);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40>
+internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Values(T1 v1,
+ T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
+ T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
+ T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27,
+ T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35,
+ T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) {
+ return internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+ T40>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
+ v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,
+ v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41>
+internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+ T41> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) {
+ return internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+ T40, T41>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
+ v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28,
+ v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42>
+internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+ T42> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+ T42 v42) {
+ return internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+ T40, T41, T42>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+ v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
+ v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41,
+ v42);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43>
+internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+ T43> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+ T42 v42, T43 v43) {
+ return internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+ T40, T41, T42, T43>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+ v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
+ v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40,
+ v41, v42, v43);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44>
+internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+ T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+ T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+ T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+ T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+ T42 v42, T43 v43, T44 v44) {
+ return internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+ T40, T41, T42, T43, T44>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+ v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
+ v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,
+ v40, v41, v42, v43, v44);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45>
+internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44, T45> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+ T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+ T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+ T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
+ T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
+ T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) {
+ return internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+ T40, T41, T42, T43, T44, T45>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+ v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
+ v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38,
+ v39, v40, v41, v42, v43, v44, v45);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46>
+internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44, T45, T46> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+ T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+ T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+ T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+ T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+ T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) {
+ return internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+ T40, T41, T42, T43, T44, T45, T46>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+ v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+ v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
+ v38, v39, v40, v41, v42, v43, v44, v45, v46);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47>
+internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44, T45, T46, T47> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+ T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+ T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+ T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+ T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+ T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) {
+ return internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+ T40, T41, T42, T43, T44, T45, T46, T47>(v1, v2, v3, v4, v5, v6, v7, v8,
+ v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+ v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
+ v38, v39, v40, v41, v42, v43, v44, v45, v46, v47);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47, typename T48>
+internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44, T45, T46, T47, T48> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+ T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+ T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+ T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+ T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+ T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47,
+ T48 v48) {
+ return internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+ T40, T41, T42, T43, T44, T45, T46, T47, T48>(v1, v2, v3, v4, v5, v6, v7,
+ v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
+ v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36,
+ v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47, typename T48, typename T49>
+internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44, T45, T46, T47, T48, T49> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+ T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+ T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
+ T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
+ T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38,
+ T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46,
+ T47 v47, T48 v48, T49 v49) {
+ return internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+ T40, T41, T42, T43, T44, T45, T46, T47, T48, T49>(v1, v2, v3, v4, v5, v6,
+ v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
+ v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35,
+ v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14, typename T15,
+ typename T16, typename T17, typename T18, typename T19, typename T20,
+ typename T21, typename T22, typename T23, typename T24, typename T25,
+ typename T26, typename T27, typename T28, typename T29, typename T30,
+ typename T31, typename T32, typename T33, typename T34, typename T35,
+ typename T36, typename T37, typename T38, typename T39, typename T40,
+ typename T41, typename T42, typename T43, typename T44, typename T45,
+ typename T46, typename T47, typename T48, typename T49, typename T50>
+internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+ T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+ T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+ T44, T45, T46, T47, T48, T49, T50> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+ T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+ T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+ T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+ T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37,
+ T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45,
+ T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) {
+ return internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+ T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+ T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+ T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>(v1, v2, v3, v4,
+ v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+ v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+ v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47,
+ v48, v49, v50);
+}
+
+// Bool() allows generating tests with parameters in a set of (false, true).
+//
+// Synopsis:
+// Bool()
+// - returns a generator producing sequences with elements {false, true}.
+//
+// It is useful when testing code that depends on Boolean flags. Combinations
+// of multiple flags can be tested when several Bool()'s are combined using
+// Combine() function.
+//
+// In the following example all tests in the test case FlagDependentTest
+// will be instantiated twice with parameters false and true.
+//
+// class FlagDependentTest : public testing::TestWithParam<bool> {
+// virtual void SetUp() {
+// external_flag = GetParam();
+// }
+// }
+// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
+//
+inline internal::ParamGenerator<bool> Bool() {
+ return Values(false, true);
+}
+
+#if GTEST_HAS_COMBINE
+// Combine() allows the user to combine two or more sequences to produce
+// values of a Cartesian product of those sequences' elements.
+//
+// Synopsis:
+// Combine(gen1, gen2, ..., genN)
+// - returns a generator producing sequences with elements coming from
+// the Cartesian product of elements from the sequences generated by
+// gen1, gen2, ..., genN. The sequence elements will have a type of
+// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
+// of elements from sequences produces by gen1, gen2, ..., genN.
+//
+// Combine can have up to 10 arguments. This number is currently limited
+// by the maximum number of elements in the tuple implementation used by Google
+// Test.
+//
+// Example:
+//
+// This will instantiate tests in test case AnimalTest each one with
+// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
+// tuple("dog", BLACK), and tuple("dog", WHITE):
+//
+// enum Color { BLACK, GRAY, WHITE };
+// class AnimalTest
+// : public testing::TestWithParam<tuple<const char*, Color> > {...};
+//
+// TEST_P(AnimalTest, AnimalLooksNice) {...}
+//
+// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
+// Combine(Values("cat", "dog"),
+// Values(BLACK, WHITE)));
+//
+// This will instantiate tests in FlagDependentTest with all variations of two
+// Boolean flags:
+//
+// class FlagDependentTest
+// : public testing::TestWithParam<tuple(bool, bool)> > {
+// virtual void SetUp() {
+// // Assigns external_flag_1 and external_flag_2 values from the tuple.
+// tie(external_flag_1, external_flag_2) = GetParam();
+// }
+// };
+//
+// TEST_P(FlagDependentTest, TestFeature1) {
+// // Test your code using external_flag_1 and external_flag_2 here.
+// }
+// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
+// Combine(Bool(), Bool()));
+//
+template <typename Generator1, typename Generator2>
+internal::CartesianProductHolder2<Generator1, Generator2> Combine(
+ const Generator1& g1, const Generator2& g2) {
+ return internal::CartesianProductHolder2<Generator1, Generator2>(
+ g1, g2);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3>
+internal::CartesianProductHolder3<Generator1, Generator2, Generator3> Combine(
+ const Generator1& g1, const Generator2& g2, const Generator3& g3) {
+ return internal::CartesianProductHolder3<Generator1, Generator2, Generator3>(
+ g1, g2, g3);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+ typename Generator4>
+internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
+ Generator4> Combine(
+ const Generator1& g1, const Generator2& g2, const Generator3& g3,
+ const Generator4& g4) {
+ return internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
+ Generator4>(
+ g1, g2, g3, g4);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+ typename Generator4, typename Generator5>
+internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
+ Generator4, Generator5> Combine(
+ const Generator1& g1, const Generator2& g2, const Generator3& g3,
+ const Generator4& g4, const Generator5& g5) {
+ return internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
+ Generator4, Generator5>(
+ g1, g2, g3, g4, g5);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+ typename Generator4, typename Generator5, typename Generator6>
+internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
+ Generator4, Generator5, Generator6> Combine(
+ const Generator1& g1, const Generator2& g2, const Generator3& g3,
+ const Generator4& g4, const Generator5& g5, const Generator6& g6) {
+ return internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
+ Generator4, Generator5, Generator6>(
+ g1, g2, g3, g4, g5, g6);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+ typename Generator4, typename Generator5, typename Generator6,
+ typename Generator7>
+internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
+ Generator4, Generator5, Generator6, Generator7> Combine(
+ const Generator1& g1, const Generator2& g2, const Generator3& g3,
+ const Generator4& g4, const Generator5& g5, const Generator6& g6,
+ const Generator7& g7) {
+ return internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
+ Generator4, Generator5, Generator6, Generator7>(
+ g1, g2, g3, g4, g5, g6, g7);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+ typename Generator4, typename Generator5, typename Generator6,
+ typename Generator7, typename Generator8>
+internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
+ Generator4, Generator5, Generator6, Generator7, Generator8> Combine(
+ const Generator1& g1, const Generator2& g2, const Generator3& g3,
+ const Generator4& g4, const Generator5& g5, const Generator6& g6,
+ const Generator7& g7, const Generator8& g8) {
+ return internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
+ Generator4, Generator5, Generator6, Generator7, Generator8>(
+ g1, g2, g3, g4, g5, g6, g7, g8);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+ typename Generator4, typename Generator5, typename Generator6,
+ typename Generator7, typename Generator8, typename Generator9>
+internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
+ Generator4, Generator5, Generator6, Generator7, Generator8,
+ Generator9> Combine(
+ const Generator1& g1, const Generator2& g2, const Generator3& g3,
+ const Generator4& g4, const Generator5& g5, const Generator6& g6,
+ const Generator7& g7, const Generator8& g8, const Generator9& g9) {
+ return internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
+ Generator4, Generator5, Generator6, Generator7, Generator8, Generator9>(
+ g1, g2, g3, g4, g5, g6, g7, g8, g9);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+ typename Generator4, typename Generator5, typename Generator6,
+ typename Generator7, typename Generator8, typename Generator9,
+ typename Generator10>
+internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
+ Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
+ Generator10> Combine(
+ const Generator1& g1, const Generator2& g2, const Generator3& g3,
+ const Generator4& g4, const Generator5& g5, const Generator6& g6,
+ const Generator7& g7, const Generator8& g8, const Generator9& g9,
+ const Generator10& g10) {
+ return internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
+ Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
+ Generator10>(
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10);
+}
+#endif // GTEST_HAS_COMBINE
+
+
+
+#define TEST_P(test_case_name, test_name) \
+ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
+ : public test_case_name { \
+ public: \
+ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
+ virtual void TestBody(); \
+ private: \
+ static int AddToRegistry() { \
+ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
+ GetTestCasePatternHolder<test_case_name>(\
+ #test_case_name, __FILE__, __LINE__)->AddTestPattern(\
+ #test_case_name, \
+ #test_name, \
+ new ::testing::internal::TestMetaFactory< \
+ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
+ return 0; \
+ } \
+ static int gtest_registering_dummy_; \
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(\
+ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
+ }; \
+ int GTEST_TEST_CLASS_NAME_(test_case_name, \
+ test_name)::gtest_registering_dummy_ = \
+ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
+ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
+
+#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
+ ::testing::internal::ParamGenerator<test_case_name::ParamType> \
+ gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
+ int gtest_##prefix##test_case_name##_dummy_ = \
+ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
+ GetTestCasePatternHolder<test_case_name>(\
+ #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
+ #prefix, \
+ &gtest_##prefix##test_case_name##_EvalGenerator_, \
+ __FILE__, __LINE__)
+
+} // namespace testing
+
+#endif // GTEST_HAS_PARAM_TEST
+
+#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+// Copyright 2006, Google Inc.
+// All rights reserved.
+//
+// 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: wan@google.com (Zhanyong Wan)
+//
+// Google C++ Testing Framework definitions useful in production code.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
+
+// When you need to test the private or protected members of a class,
+// use the FRIEND_TEST macro to declare your tests as friends of the
+// class. For example:
+//
+// class MyClass {
+// private:
+// void MyMethod();
+// FRIEND_TEST(MyClassTest, MyMethod);
+// };
+//
+// class MyClassTest : public testing::Test {
+// // ...
+// };
+//
+// TEST_F(MyClassTest, MyMethod) {
+// // Can call MyClass::MyMethod() here.
+// }
+
+#define FRIEND_TEST(test_case_name, test_name)\
+friend class test_case_name##_##test_name##_Test
+
+#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// 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: mheule@google.com (Markus Heule)
+//
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
+#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
+
+#include <iosfwd>
+#include <vector>
+
+namespace testing {
+
+// A copyable object representing the result of a test part (i.e. an
+// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
+//
+// Don't inherit from TestPartResult as its destructor is not virtual.
+class GTEST_API_ TestPartResult {
+ public:
+ // The possible outcomes of a test part (i.e. an assertion or an
+ // explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
+ enum Type {
+ kSuccess, // Succeeded.
+ kNonFatalFailure, // Failed but the test can continue.
+ kFatalFailure // Failed and the test should be terminated.
+ };
+
+ // C'tor. TestPartResult does NOT have a default constructor.
+ // Always use this constructor (with parameters) to create a
+ // TestPartResult object.
+ TestPartResult(Type a_type,
+ const char* a_file_name,
+ int a_line_number,
+ const char* a_message)
+ : type_(a_type),
+ file_name_(a_file_name),
+ line_number_(a_line_number),
+ summary_(ExtractSummary(a_message)),
+ message_(a_message) {
+ }
+
+ // Gets the outcome of the test part.
+ Type type() const { return type_; }
+
+ // Gets the name of the source file where the test part took place, or
+ // NULL if it's unknown.
+ const char* file_name() const { return file_name_.c_str(); }
+
+ // Gets the line in the source file where the test part took place,
+ // or -1 if it's unknown.
+ int line_number() const { return line_number_; }
+
+ // Gets the summary of the failure message.
+ const char* summary() const { return summary_.c_str(); }
+
+ // Gets the message associated with the test part.
+ const char* message() const { return message_.c_str(); }
+
+ // Returns true iff the test part passed.
+ bool passed() const { return type_ == kSuccess; }
+
+ // Returns true iff the test part failed.
+ bool failed() const { return type_ != kSuccess; }
+
+ // Returns true iff the test part non-fatally failed.
+ bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
+
+ // Returns true iff the test part fatally failed.
+ bool fatally_failed() const { return type_ == kFatalFailure; }
+ private:
+ Type type_;
+
+ // Gets the summary of the failure message by omitting the stack
+ // trace in it.
+ static internal::String ExtractSummary(const char* message);
+
+ // The name of the source file where the test part took place, or
+ // NULL if the source file is unknown.
+ internal::String file_name_;
+ // The line in the source file where the test part took place, or -1
+ // if the line number is unknown.
+ int line_number_;
+ internal::String summary_; // The test failure summary.
+ internal::String message_; // The test failure message.
+};
+
+// Prints a TestPartResult object.
+std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
+
+// An array of TestPartResult objects.
+//
+// Don't inherit from TestPartResultArray as its destructor is not
+// virtual.
+class GTEST_API_ TestPartResultArray {
+ public:
+ TestPartResultArray() {}
+
+ // Appends the given TestPartResult to the array.
+ void Append(const TestPartResult& result);
+
+ // Returns the TestPartResult at the given index (0-based).
+ const TestPartResult& GetTestPartResult(int index) const;
+
+ // Returns the number of TestPartResult objects in the array.
+ int size() const;
+
+ private:
+ std::vector<TestPartResult> array_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
+};
+
+// This interface knows how to report a test part result.
+class TestPartResultReporterInterface {
+ public:
+ virtual ~TestPartResultReporterInterface() {}
+
+ virtual void ReportTestPartResult(const TestPartResult& result) = 0;
+};
+
+namespace internal {
+
+// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
+// statement generates new fatal failures. To do so it registers itself as the
+// current test part result reporter. Besides checking if fatal failures were
+// reported, it only delegates the reporting to the former result reporter.
+// The original result reporter is restored in the destructor.
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+class GTEST_API_ HasNewFatalFailureHelper
+ : public TestPartResultReporterInterface {
+ public:
+ HasNewFatalFailureHelper();
+ virtual ~HasNewFatalFailureHelper();
+ virtual void ReportTestPartResult(const TestPartResult& result);
+ bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
+ private:
+ bool has_new_fatal_failure_;
+ TestPartResultReporterInterface* original_reporter_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);
+};
+
+} // namespace internal
+
+} // namespace testing
+
+#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// 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: wan@google.com (Zhanyong Wan)
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+
+// This header implements typed tests and type-parameterized tests.
+
+// Typed (aka type-driven) tests repeat the same test for types in a
+// list. You must know which types you want to test with when writing
+// typed tests. Here's how you do it:
+
+#if 0
+
+// First, define a fixture class template. It should be parameterized
+// by a type. Remember to derive it from testing::Test.
+template <typename T>
+class FooTest : public testing::Test {
+ public:
+ ...
+ typedef std::list<T> List;
+ static T shared_;
+ T value_;
+};
+
+// Next, associate a list of types with the test case, which will be
+// repeated for each type in the list. The typedef is necessary for
+// the macro to parse correctly.
+typedef testing::Types<char, int, unsigned int> MyTypes;
+TYPED_TEST_CASE(FooTest, MyTypes);
+
+// If the type list contains only one type, you can write that type
+// directly without Types<...>:
+// TYPED_TEST_CASE(FooTest, int);
+
+// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
+// tests for this test case as you want.
+TYPED_TEST(FooTest, DoesBlah) {
+ // Inside a test, refer to TypeParam to get the type parameter.
+ // Since we are inside a derived class template, C++ requires use to
+ // visit the members of FooTest via 'this'.
+ TypeParam n = this->value_;
+
+ // To visit static members of the fixture, add the TestFixture::
+ // prefix.
+ n += TestFixture::shared_;
+
+ // To refer to typedefs in the fixture, add the "typename
+ // TestFixture::" prefix.
+ typename TestFixture::List values;
+ values.push_back(n);
+ ...
+}
+
+TYPED_TEST(FooTest, HasPropertyA) { ... }
+
+#endif // 0
+
+// Type-parameterized tests are abstract test patterns parameterized
+// by a type. Compared with typed tests, type-parameterized tests
+// allow you to define the test pattern without knowing what the type
+// parameters are. The defined pattern can be instantiated with
+// different types any number of times, in any number of translation
+// units.
+//
+// If you are designing an interface or concept, you can define a
+// suite of type-parameterized tests to verify properties that any
+// valid implementation of the interface/concept should have. Then,
+// each implementation can easily instantiate the test suite to verify
+// that it conforms to the requirements, without having to write
+// similar tests repeatedly. Here's an example:
+
+#if 0
+
+// First, define a fixture class template. It should be parameterized
+// by a type. Remember to derive it from testing::Test.
+template <typename T>
+class FooTest : public testing::Test {
+ ...
+};
+
+// Next, declare that you will define a type-parameterized test case
+// (the _P suffix is for "parameterized" or "pattern", whichever you
+// prefer):
+TYPED_TEST_CASE_P(FooTest);
+
+// Then, use TYPED_TEST_P() to define as many type-parameterized tests
+// for this type-parameterized test case as you want.
+TYPED_TEST_P(FooTest, DoesBlah) {
+ // Inside a test, refer to TypeParam to get the type parameter.
+ TypeParam n = 0;
+ ...
+}
+
+TYPED_TEST_P(FooTest, HasPropertyA) { ... }
+
+// Now the tricky part: you need to register all test patterns before
+// you can instantiate them. The first argument of the macro is the
+// test case name; the rest are the names of the tests in this test
+// case.
+REGISTER_TYPED_TEST_CASE_P(FooTest,
+ DoesBlah, HasPropertyA);
+
+// Finally, you are free to instantiate the pattern with the types you
+// want. If you put the above code in a header file, you can #include
+// it in multiple C++ source files and instantiate it multiple times.
+//
+// To distinguish different instances of the pattern, the first
+// argument to the INSTANTIATE_* macro is a prefix that will be added
+// to the actual test case name. Remember to pick unique prefixes for
+// different instances.
+typedef testing::Types<char, int, unsigned int> MyTypes;
+INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
+
+// If the type list contains only one type, you can write that type
+// directly without Types<...>:
+// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
+
+#endif // 0
+
+
+// Implements typed tests.
+
+#if GTEST_HAS_TYPED_TEST
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the name of the typedef for the type parameters of the
+// given test case.
+#define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
+
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
+#define TYPED_TEST_CASE(CaseName, Types) \
+ typedef ::testing::internal::TypeList< Types >::type \
+ GTEST_TYPE_PARAMS_(CaseName)
+
+#define TYPED_TEST(CaseName, TestName) \
+ template <typename gtest_TypeParam_> \
+ class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
+ : public CaseName<gtest_TypeParam_> { \
+ private: \
+ typedef CaseName<gtest_TypeParam_> TestFixture; \
+ typedef gtest_TypeParam_ TypeParam; \
+ virtual void TestBody(); \
+ }; \
+ bool gtest_##CaseName##_##TestName##_registered_ = \
+ ::testing::internal::TypeParameterizedTest< \
+ CaseName, \
+ ::testing::internal::TemplateSel< \
+ GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
+ GTEST_TYPE_PARAMS_(CaseName)>::Register(\
+ "", #CaseName, #TestName, 0); \
+ template <typename gtest_TypeParam_> \
+ void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
+
+#endif // GTEST_HAS_TYPED_TEST
+
+// Implements type-parameterized tests.
+
+#if GTEST_HAS_TYPED_TEST_P
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the namespace name that the type-parameterized tests for
+// the given type-parameterized test case are defined in. The exact
+// name of the namespace is subject to change without notice.
+#define GTEST_CASE_NAMESPACE_(TestCaseName) \
+ gtest_case_##TestCaseName##_
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the name of the variable used to remember the names of
+// the defined tests in the given test case.
+#define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
+ gtest_typed_test_case_p_state_##TestCaseName##_
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
+//
+// Expands to the name of the variable used to remember the names of
+// the registered tests in the given test case.
+#define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
+ gtest_registered_test_names_##TestCaseName##_
+
+// The variables defined in the type-parameterized test macros are
+// static as typically these macros are used in a .h file that can be
+// #included in multiple translation units linked together.
+#define TYPED_TEST_CASE_P(CaseName) \
+ static ::testing::internal::TypedTestCasePState \
+ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
+
+#define TYPED_TEST_P(CaseName, TestName) \
+ namespace GTEST_CASE_NAMESPACE_(CaseName) { \
+ template <typename gtest_TypeParam_> \
+ class TestName : public CaseName<gtest_TypeParam_> { \
+ private: \
+ typedef CaseName<gtest_TypeParam_> TestFixture; \
+ typedef gtest_TypeParam_ TypeParam; \
+ virtual void TestBody(); \
+ }; \
+ static bool gtest_##TestName##_defined_ = \
+ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
+ __FILE__, __LINE__, #CaseName, #TestName); \
+ } \
+ template <typename gtest_TypeParam_> \
+ void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
+
+#define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
+ namespace GTEST_CASE_NAMESPACE_(CaseName) { \
+ typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
+ } \
+ static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
+ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
+ __FILE__, __LINE__, #__VA_ARGS__)
+
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
+#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
+ bool gtest_##Prefix##_##CaseName = \
+ ::testing::internal::TypeParameterizedTestCase<CaseName, \
+ GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
+ ::testing::internal::TypeList< Types >::type>::Register(\
+ #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
+
+#endif // GTEST_HAS_TYPED_TEST_P
+
+#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+
+// Depending on the platform, different string classes are available.
+// On Linux, in addition to ::std::string, Google also makes use of
+// class ::string, which has the same interface as ::std::string, but
+// has a different implementation.
+//
+// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that
+// ::string is available AND is a distinct type to ::std::string, or
+// define it to 0 to indicate otherwise.
+//
+// If the user's ::std::string and ::string are the same class due to
+// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0.
+//
+// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined
+// heuristically.
+
+namespace testing {
+
+// Declares the flags.
+
+// This flag temporary enables the disabled tests.
+GTEST_DECLARE_bool_(also_run_disabled_tests);
+
+// This flag brings the debugger on an assertion failure.
+GTEST_DECLARE_bool_(break_on_failure);
+
+// This flag controls whether Google Test catches all test-thrown exceptions
+// and logs them as failures.
+GTEST_DECLARE_bool_(catch_exceptions);
+
+// This flag enables using colors in terminal output. Available values are
+// "yes" to enable colors, "no" (disable colors), or "auto" (the default)
+// to let Google Test decide.
+GTEST_DECLARE_string_(color);
+
+// This flag sets up the filter to select by name using a glob pattern
+// the tests to run. If the filter is not given all tests are executed.
+GTEST_DECLARE_string_(filter);
+
+// This flag causes the Google Test to list tests. None of the tests listed
+// are actually run if the flag is provided.
+GTEST_DECLARE_bool_(list_tests);
+
+// This flag controls whether Google Test emits a detailed XML report to a file
+// in addition to its normal textual output.
+GTEST_DECLARE_string_(output);
+
+// This flags control whether Google Test prints the elapsed time for each
+// test.
+GTEST_DECLARE_bool_(print_time);
+
+// This flag specifies the random number seed.
+GTEST_DECLARE_int32_(random_seed);
+
+// This flag sets how many times the tests are repeated. The default value
+// is 1. If the value is -1 the tests are repeating forever.
+GTEST_DECLARE_int32_(repeat);
+
+// This flag controls whether Google Test includes Google Test internal
+// stack frames in failure stack traces.
+GTEST_DECLARE_bool_(show_internal_stack_frames);
+
+// When this flag is specified, tests' order is randomized on every iteration.
+GTEST_DECLARE_bool_(shuffle);
+
+// This flag specifies the maximum number of stack frames to be
+// printed in a failure message.
+GTEST_DECLARE_int32_(stack_trace_depth);
+
+// When this flag is specified, a failed assertion will throw an
+// exception if exceptions are enabled, or exit the program with a
+// non-zero code otherwise.
+GTEST_DECLARE_bool_(throw_on_failure);
+
+// The upper limit for valid stack trace depths.
+const int kMaxStackTraceDepth = 100;
+
+namespace internal {
+
+class AssertHelper;
+class DefaultGlobalTestPartResultReporter;
+class ExecDeathTest;
+class NoExecDeathTest;
+class FinalSuccessChecker;
+class GTestFlagSaver;
+class TestInfoImpl;
+class TestResultAccessor;
+class TestEventListenersAccessor;
+class TestEventRepeater;
+class WindowsDeathTest;
+class UnitTestImpl* GetUnitTestImpl();
+void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
+ const String& message);
+class PrettyUnitTestResultPrinter;
+class XmlUnitTestResultPrinter;
+
+// Converts a streamable value to a String. A NULL pointer is
+// converted to "(null)". When the input value is a ::string,
+// ::std::string, ::wstring, or ::std::wstring object, each NUL
+// character in it is replaced with "\\0".
+// Declared in gtest-internal.h but defined here, so that it has access
+// to the definition of the Message class, required by the ARM
+// compiler.
+template <typename T>
+String StreamableToString(const T& streamable) {
+ return (Message() << streamable).GetString();
+}
+
+} // namespace internal
+
+// A class for indicating whether an assertion was successful. When
+// the assertion wasn't successful, the AssertionResult object
+// remembers a non-empty message that describes how it failed.
+//
+// To create an instance of this class, use one of the factory functions
+// (AssertionSuccess() and AssertionFailure()).
+//
+// This class is useful for two purposes:
+// 1. Defining predicate functions to be used with Boolean test assertions
+// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts
+// 2. Defining predicate-format functions to be
+// used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
+//
+// For example, if you define IsEven predicate:
+//
+// testing::AssertionResult IsEven(int n) {
+// if ((n % 2) == 0)
+// return testing::AssertionSuccess();
+// else
+// return testing::AssertionFailure() << n << " is odd";
+// }
+//
+// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))
+// will print the message
+//
+// Value of: IsEven(Fib(5))
+// Actual: false (5 is odd)
+// Expected: true
+//
+// instead of a more opaque
+//
+// Value of: IsEven(Fib(5))
+// Actual: false
+// Expected: true
+//
+// in case IsEven is a simple Boolean predicate.
+//
+// If you expect your predicate to be reused and want to support informative
+// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up
+// about half as often as positive ones in our tests), supply messages for
+// both success and failure cases:
+//
+// testing::AssertionResult IsEven(int n) {
+// if ((n % 2) == 0)
+// return testing::AssertionSuccess() << n << " is even";
+// else
+// return testing::AssertionFailure() << n << " is odd";
+// }
+//
+// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print
+//
+// Value of: IsEven(Fib(6))
+// Actual: true (8 is even)
+// Expected: false
+//
+// NB: Predicates that support negative Boolean assertions have reduced
+// performance in positive ones so be careful not to use them in tests
+// that have lots (tens of thousands) of positive Boolean assertions.
+//
+// To use this class with EXPECT_PRED_FORMAT assertions such as:
+//
+// // Verifies that Foo() returns an even number.
+// EXPECT_PRED_FORMAT1(IsEven, Foo());
+//
+// you need to define:
+//
+// testing::AssertionResult IsEven(const char* expr, int n) {
+// if ((n % 2) == 0)
+// return testing::AssertionSuccess();
+// else
+// return testing::AssertionFailure()
+// << "Expected: " << expr << " is even\n Actual: it's " << n;
+// }
+//
+// If Foo() returns 5, you will see the following message:
+//
+// Expected: Foo() is even
+// Actual: it's 5
+//
+class GTEST_API_ AssertionResult {
+ public:
+ // Copy constructor.
+ // Used in EXPECT_TRUE/FALSE(assertion_result).
+ AssertionResult(const AssertionResult& other);
+ // Used in the EXPECT_TRUE/FALSE(bool_expression).
+ explicit AssertionResult(bool success) : success_(success) {}
+
+ // Returns true iff the assertion succeeded.
+ operator bool() const { return success_; } // NOLINT
+
+ // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
+ AssertionResult operator!() const;
+
+ // Returns the text streamed into this AssertionResult. Test assertions
+ // use it when they fail (i.e., the predicate's outcome doesn't match the
+ // assertion's expectation). When nothing has been streamed into the
+ // object, returns an empty string.
+ const char* message() const {
+ return message_.get() != NULL && message_->c_str() != NULL ?
+ message_->c_str() : "";
+ }
+ // TODO(vladl@google.com): Remove this after making sure no clients use it.
+ // Deprecated; please use message() instead.
+ const char* failure_message() const { return message(); }
+
+ // Streams a custom failure message into this object.
+ template <typename T> AssertionResult& operator<<(const T& value);
+
+ private:
+ // No implementation - we want AssertionResult to be
+ // copy-constructible but not assignable.
+ void operator=(const AssertionResult& other);
+
+ // Stores result of the assertion predicate.
+ bool success_;
+ // Stores the message describing the condition in case the expectation
+ // construct is not satisfied with the predicate's outcome.
+ // Referenced via a pointer to avoid taking too much stack frame space
+ // with test assertions.
+ internal::scoped_ptr<internal::String> message_;
+}; // class AssertionResult
+
+// Streams a custom failure message into this object.
+template <typename T>
+AssertionResult& AssertionResult::operator<<(const T& value) {
+ Message msg;
+ if (message_.get() != NULL)
+ msg << *message_;
+ msg << value;
+ message_.reset(new internal::String(msg.GetString()));
+ return *this;
+}
+
+// Makes a successful assertion result.
+GTEST_API_ AssertionResult AssertionSuccess();
+
+// Makes a failed assertion result.
+GTEST_API_ AssertionResult AssertionFailure();
+
+// Makes a failed assertion result with the given failure message.
+// Deprecated; use AssertionFailure() << msg.
+GTEST_API_ AssertionResult AssertionFailure(const Message& msg);
+
+// The abstract class that all tests inherit from.
+//
+// In Google Test, a unit test program contains one or many TestCases, and
+// each TestCase contains one or many Tests.
+//
+// When you define a test using the TEST macro, you don't need to
+// explicitly derive from Test - the TEST macro automatically does
+// this for you.
+//
+// The only time you derive from Test is when defining a test fixture
+// to be used a TEST_F. For example:
+//
+// class FooTest : public testing::Test {
+// protected:
+// virtual void SetUp() { ... }
+// virtual void TearDown() { ... }
+// ...
+// };
+//
+// TEST_F(FooTest, Bar) { ... }
+// TEST_F(FooTest, Baz) { ... }
+//
+// Test is not copyable.
+class GTEST_API_ Test {
+ public:
+ friend class internal::TestInfoImpl;
+
+ // Defines types for pointers to functions that set up and tear down
+ // a test case.
+ typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc;
+ typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc;
+
+ // The d'tor is virtual as we intend to inherit from Test.
+ virtual ~Test();
+
+ // Sets up the stuff shared by all tests in this test case.
+ //
+ // Google Test will call Foo::SetUpTestCase() before running the first
+ // test in test case Foo. Hence a sub-class can define its own
+ // SetUpTestCase() method to shadow the one defined in the super
+ // class.
+ static void SetUpTestCase() {}
+
+ // Tears down the stuff shared by all tests in this test case.
+ //
+ // Google Test will call Foo::TearDownTestCase() after running the last
+ // test in test case Foo. Hence a sub-class can define its own
+ // TearDownTestCase() method to shadow the one defined in the super
+ // class.
+ static void TearDownTestCase() {}
+
+ // Returns true iff the current test has a fatal failure.
+ static bool HasFatalFailure();
+
+ // Returns true iff the current test has a non-fatal failure.
+ static bool HasNonfatalFailure();
+
+ // Returns true iff the current test has a (either fatal or
+ // non-fatal) failure.
+ static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }
+
+ // Logs a property for the current test. Only the last value for a given
+ // key is remembered.
+ // These are public static so they can be called from utility functions
+ // that are not members of the test fixture.
+ // The arguments are const char* instead strings, as Google Test is used
+ // on platforms where string doesn't compile.
+ //
+ // Note that a driving consideration for these RecordProperty methods
+ // was to produce xml output suited to the Greenspan charting utility,
+ // which at present will only chart values that fit in a 32-bit int. It
+ // is the user's responsibility to restrict their values to 32-bit ints
+ // if they intend them to be used with Greenspan.
+ static void RecordProperty(const char* key, const char* value);
+ static void RecordProperty(const char* key, int value);
+
+ protected:
+ // Creates a Test object.
+ Test();
+
+ // Sets up the test fixture.
+ virtual void SetUp();
+
+ // Tears down the test fixture.
+ virtual void TearDown();
+
+ private:
+ // Returns true iff the current test has the same fixture class as
+ // the first test in the current test case.
+ static bool HasSameFixtureClass();
+
+ // Runs the test after the test fixture has been set up.
+ //
+ // A sub-class must implement this to define the test logic.
+ //
+ // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM.
+ // Instead, use the TEST or TEST_F macro.
+ virtual void TestBody() = 0;
+
+ // Sets up, executes, and tears down the test.
+ void Run();
+
+ // Uses a GTestFlagSaver to save and restore all Google Test flags.
+ const internal::GTestFlagSaver* const gtest_flag_saver_;
+
+ // Often a user mis-spells SetUp() as Setup() and spends a long time
+ // wondering why it is never called by Google Test. The declaration of
+ // the following method is solely for catching such an error at
+ // compile time:
+ //
+ // - The return type is deliberately chosen to be not void, so it
+ // will be a conflict if a user declares void Setup() in his test
+ // fixture.
+ //
+ // - This method is private, so it will be another compiler error
+ // if a user calls it from his test fixture.
+ //
+ // DO NOT OVERRIDE THIS FUNCTION.
+ //
+ // If you see an error about overriding the following function or
+ // about it being private, you have mis-spelled SetUp() as Setup().
+ struct Setup_should_be_spelled_SetUp {};
+ virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
+
+ // We disallow copying Tests.
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(Test);
+};
+
+typedef internal::TimeInMillis TimeInMillis;
+
+// A copyable object representing a user specified test property which can be
+// output as a key/value string pair.
+//
+// Don't inherit from TestProperty as its destructor is not virtual.
+class TestProperty {
+ public:
+ // C'tor. TestProperty does NOT have a default constructor.
+ // Always use this constructor (with parameters) to create a
+ // TestProperty object.
+ TestProperty(const char* a_key, const char* a_value) :
+ key_(a_key), value_(a_value) {
+ }
+
+ // Gets the user supplied key.
+ const char* key() const {
+ return key_.c_str();
+ }
+
+ // Gets the user supplied value.
+ const char* value() const {
+ return value_.c_str();
+ }
+
+ // Sets a new value, overriding the one supplied in the constructor.
+ void SetValue(const char* new_value) {
+ value_ = new_value;
+ }
+
+ private:
+ // The key supplied by the user.
+ internal::String key_;
+ // The value supplied by the user.
+ internal::String value_;
+};
+
+// The result of a single Test. This includes a list of
+// TestPartResults, a list of TestProperties, a count of how many
+// death tests there are in the Test, and how much time it took to run
+// the Test.
+//
+// TestResult is not copyable.
+class GTEST_API_ TestResult {
+ public:
+ // Creates an empty TestResult.
+ TestResult();
+
+ // D'tor. Do not inherit from TestResult.
+ ~TestResult();
+
+ // Gets the number of all test parts. This is the sum of the number
+ // of successful test parts and the number of failed test parts.
+ int total_part_count() const;
+
+ // Returns the number of the test properties.
+ int test_property_count() const;
+
+ // Returns true iff the test passed (i.e. no test part failed).
+ bool Passed() const { return !Failed(); }
+
+ // Returns true iff the test failed.
+ bool Failed() const;
+
+ // Returns true iff the test fatally failed.
+ bool HasFatalFailure() const;
+
+ // Returns true iff the test has a non-fatal failure.
+ bool HasNonfatalFailure() const;
+
+ // Returns the elapsed time, in milliseconds.
+ TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+ // Returns the i-th test part result among all the results. i can range
+ // from 0 to test_property_count() - 1. If i is not in that range, aborts
+ // the program.
+ const TestPartResult& GetTestPartResult(int i) const;
+
+ // Returns the i-th test property. i can range from 0 to
+ // test_property_count() - 1. If i is not in that range, aborts the
+ // program.
+ const TestProperty& GetTestProperty(int i) const;
+
+ private:
+ friend class TestInfo;
+ friend class UnitTest;
+ friend class internal::DefaultGlobalTestPartResultReporter;
+ friend class internal::ExecDeathTest;
+ friend class internal::TestInfoImpl;
+ friend class internal::TestResultAccessor;
+ friend class internal::UnitTestImpl;
+ friend class internal::WindowsDeathTest;
+
+ // Gets the vector of TestPartResults.
+ const std::vector<TestPartResult>& test_part_results() const {
+ return test_part_results_;
+ }
+
+ // Gets the vector of TestProperties.
+ const std::vector<TestProperty>& test_properties() const {
+ return test_properties_;
+ }
+
+ // Sets the elapsed time.
+ void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }
+
+ // Adds a test property to the list. The property is validated and may add
+ // a non-fatal failure if invalid (e.g., if it conflicts with reserved
+ // key names). If a property is already recorded for the same key, the
+ // value will be updated, rather than storing multiple values for the same
+ // key.
+ void RecordProperty(const TestProperty& test_property);
+
+ // Adds a failure if the key is a reserved attribute of Google Test
+ // testcase tags. Returns true if the property is valid.
+ // TODO(russr): Validate attribute names are legal and human readable.
+ static bool ValidateTestProperty(const TestProperty& test_property);
+
+ // Adds a test part result to the list.
+ void AddTestPartResult(const TestPartResult& test_part_result);
+
+ // Returns the death test count.
+ int death_test_count() const { return death_test_count_; }
+
+ // Increments the death test count, returning the new count.
+ int increment_death_test_count() { return ++death_test_count_; }
+
+ // Clears the test part results.
+ void ClearTestPartResults();
+
+ // Clears the object.
+ void Clear();
+
+ // Protects mutable state of the property vector and of owned
+ // properties, whose values may be updated.
+ internal::Mutex test_properites_mutex_;
+
+ // The vector of TestPartResults
+ std::vector<TestPartResult> test_part_results_;
+ // The vector of TestProperties
+ std::vector<TestProperty> test_properties_;
+ // Running count of death tests.
+ int death_test_count_;
+ // The elapsed time, in milliseconds.
+ TimeInMillis elapsed_time_;
+
+ // We disallow copying TestResult.
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult);
+}; // class TestResult
+
+// A TestInfo object stores the following information about a test:
+//
+// Test case name
+// Test name
+// Whether the test should be run
+// A function pointer that creates the test object when invoked
+// Test result
+//
+// The constructor of TestInfo registers itself with the UnitTest
+// singleton such that the RUN_ALL_TESTS() macro knows which tests to
+// run.
+class GTEST_API_ TestInfo {
+ public:
+ // Destructs a TestInfo object. This function is not virtual, so
+ // don't inherit from TestInfo.
+ ~TestInfo();
+
+ // Returns the test case name.
+ const char* test_case_name() const;
+
+ // Returns the test name.
+ const char* name() const;
+
+ // Returns the test case comment.
+ const char* test_case_comment() const;
+
+ // Returns the test comment.
+ const char* comment() const;
+
+ // Returns true if this test should run, that is if the test is not disabled
+ // (or it is disabled but the also_run_disabled_tests flag has been specified)
+ // and its full name matches the user-specified filter.
+ //
+ // Google Test allows the user to filter the tests by their full names.
+ // The full name of a test Bar in test case Foo is defined as
+ // "Foo.Bar". Only the tests that match the filter will run.
+ //
+ // A filter is a colon-separated list of glob (not regex) patterns,
+ // optionally followed by a '-' and a colon-separated list of
+ // negative patterns (tests to exclude). A test is run if it
+ // matches one of the positive patterns and does not match any of
+ // the negative patterns.
+ //
+ // For example, *A*:Foo.* is a filter that matches any string that
+ // contains the character 'A' or starts with "Foo.".
+ bool should_run() const;
+
+ // Returns the result of the test.
+ const TestResult* result() const;
+
+ private:
+#if GTEST_HAS_DEATH_TEST
+ friend class internal::DefaultDeathTestFactory;
+#endif // GTEST_HAS_DEATH_TEST
+ friend class Test;
+ friend class TestCase;
+ friend class internal::TestInfoImpl;
+ friend class internal::UnitTestImpl;
+ friend TestInfo* internal::MakeAndRegisterTestInfo(
+ const char* test_case_name, const char* name,
+ const char* test_case_comment, const char* comment,
+ internal::TypeId fixture_class_id,
+ Test::SetUpTestCaseFunc set_up_tc,
+ Test::TearDownTestCaseFunc tear_down_tc,
+ internal::TestFactoryBase* factory);
+
+ // Returns true if this test matches the user-specified filter.
+ bool matches_filter() const;
+
+ // Increments the number of death tests encountered in this test so
+ // far.
+ int increment_death_test_count();
+
+ // Accessors for the implementation object.
+ internal::TestInfoImpl* impl() { return impl_; }
+ const internal::TestInfoImpl* impl() const { return impl_; }
+
+ // Constructs a TestInfo object. The newly constructed instance assumes
+ // ownership of the factory object.
+ TestInfo(const char* test_case_name, const char* name,
+ const char* test_case_comment, const char* comment,
+ internal::TypeId fixture_class_id,
+ internal::TestFactoryBase* factory);
+
+ // An opaque implementation object.
+ internal::TestInfoImpl* impl_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo);
+};
+
+// A test case, which consists of a vector of TestInfos.
+//
+// TestCase is not copyable.
+class GTEST_API_ TestCase {
+ public:
+ // Creates a TestCase with the given name.
+ //
+ // TestCase does NOT have a default constructor. Always use this
+ // constructor to create a TestCase object.
+ //
+ // Arguments:
+ //
+ // name: name of the test case
+ // set_up_tc: pointer to the function that sets up the test case
+ // tear_down_tc: pointer to the function that tears down the test case
+ TestCase(const char* name, const char* comment,
+ Test::SetUpTestCaseFunc set_up_tc,
+ Test::TearDownTestCaseFunc tear_down_tc);
+
+ // Destructor of TestCase.
+ virtual ~TestCase();
+
+ // Gets the name of the TestCase.
+ const char* name() const { return name_.c_str(); }
+
+ // Returns the test case comment.
+ const char* comment() const { return comment_.c_str(); }
+
+ // Returns true if any test in this test case should run.
+ bool should_run() const { return should_run_; }
+
+ // Gets the number of successful tests in this test case.
+ int successful_test_count() const;
+
+ // Gets the number of failed tests in this test case.
+ int failed_test_count() const;
+
+ // Gets the number of disabled tests in this test case.
+ int disabled_test_count() const;
+
+ // Get the number of tests in this test case that should run.
+ int test_to_run_count() const;
+
+ // Gets the number of all tests in this test case.
+ int total_test_count() const;
+
+ // Returns true iff the test case passed.
+ bool Passed() const { return !Failed(); }
+
+ // Returns true iff the test case failed.
+ bool Failed() const { return failed_test_count() > 0; }
+
+ // Returns the elapsed time, in milliseconds.
+ TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+ // Returns the i-th test among all the tests. i can range from 0 to
+ // total_test_count() - 1. If i is not in that range, returns NULL.
+ const TestInfo* GetTestInfo(int i) const;
+
+ private:
+ friend class Test;
+ friend class internal::UnitTestImpl;
+
+ // Gets the (mutable) vector of TestInfos in this TestCase.
+ std::vector<TestInfo*>& test_info_list() { return test_info_list_; }
+
+ // Gets the (immutable) vector of TestInfos in this TestCase.
+ const std::vector<TestInfo*>& test_info_list() const {
+ return test_info_list_;
+ }
+
+ // Returns the i-th test among all the tests. i can range from 0 to
+ // total_test_count() - 1. If i is not in that range, returns NULL.
+ TestInfo* GetMutableTestInfo(int i);
+
+ // Sets the should_run member.
+ void set_should_run(bool should) { should_run_ = should; }
+
+ // Adds a TestInfo to this test case. Will delete the TestInfo upon
+ // destruction of the TestCase object.
+ void AddTestInfo(TestInfo * test_info);
+
+ // Clears the results of all tests in this test case.
+ void ClearResult();
+
+ // Clears the results of all tests in the given test case.
+ static void ClearTestCaseResult(TestCase* test_case) {
+ test_case->ClearResult();
+ }
+
+ // Runs every test in this TestCase.
+ void Run();
+
+ // Returns true iff test passed.
+ static bool TestPassed(const TestInfo * test_info);
+
+ // Returns true iff test failed.
+ static bool TestFailed(const TestInfo * test_info);
+
+ // Returns true iff test is disabled.
+ static bool TestDisabled(const TestInfo * test_info);
+
+ // Returns true if the given test should run.
+ static bool ShouldRunTest(const TestInfo *test_info);
+
+ // Shuffles the tests in this test case.
+ void ShuffleTests(internal::Random* random);
+
+ // Restores the test order to before the first shuffle.
+ void UnshuffleTests();
+
+ // Name of the test case.
+ internal::String name_;
+ // Comment on the test case.
+ internal::String comment_;
+ // The vector of TestInfos in their original order. It owns the
+ // elements in the vector.
+ std::vector<TestInfo*> test_info_list_;
+ // Provides a level of indirection for the test list to allow easy
+ // shuffling and restoring the test order. The i-th element in this
+ // vector is the index of the i-th test in the shuffled test list.
+ std::vector<int> test_indices_;
+ // Pointer to the function that sets up the test case.
+ Test::SetUpTestCaseFunc set_up_tc_;
+ // Pointer to the function that tears down the test case.
+ Test::TearDownTestCaseFunc tear_down_tc_;
+ // True iff any test in this test case should run.
+ bool should_run_;
+ // Elapsed time, in milliseconds.
+ TimeInMillis elapsed_time_;
+
+ // We disallow copying TestCases.
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase);
+};
+
+// An Environment object is capable of setting up and tearing down an
+// environment. The user should subclass this to define his own
+// environment(s).
+//
+// An Environment object does the set-up and tear-down in virtual
+// methods SetUp() and TearDown() instead of the constructor and the
+// destructor, as:
+//
+// 1. You cannot safely throw from a destructor. This is a problem
+// as in some cases Google Test is used where exceptions are enabled, and
+// we may want to implement ASSERT_* using exceptions where they are
+// available.
+// 2. You cannot use ASSERT_* directly in a constructor or
+// destructor.
+class Environment {
+ public:
+ // The d'tor is virtual as we need to subclass Environment.
+ virtual ~Environment() {}
+
+ // Override this to define how to set up the environment.
+ virtual void SetUp() {}
+
+ // Override this to define how to tear down the environment.
+ virtual void TearDown() {}
+ private:
+ // If you see an error about overriding the following function or
+ // about it being private, you have mis-spelled SetUp() as Setup().
+ struct Setup_should_be_spelled_SetUp {};
+ virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
+};
+
+// The interface for tracing execution of tests. The methods are organized in
+// the order the corresponding events are fired.
+class TestEventListener {
+ public:
+ virtual ~TestEventListener() {}
+
+ // Fired before any test activity starts.
+ virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;
+
+ // Fired before each iteration of tests starts. There may be more than
+ // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration
+ // index, starting from 0.
+ virtual void OnTestIterationStart(const UnitTest& unit_test,
+ int iteration) = 0;
+
+ // Fired before environment set-up for each iteration of tests starts.
+ virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0;
+
+ // Fired after environment set-up for each iteration of tests ends.
+ virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;
+
+ // Fired before the test case starts.
+ virtual void OnTestCaseStart(const TestCase& test_case) = 0;
+
+ // Fired before the test starts.
+ virtual void OnTestStart(const TestInfo& test_info) = 0;
+
+ // Fired after a failed assertion or a SUCCESS().
+ virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;
+
+ // Fired after the test ends.
+ virtual void OnTestEnd(const TestInfo& test_info) = 0;
+
+ // Fired after the test case ends.
+ virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
+
+ // Fired before environment tear-down for each iteration of tests starts.
+ virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;
+
+ // Fired after environment tear-down for each iteration of tests ends.
+ virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;
+
+ // Fired after each iteration of tests finishes.
+ virtual void OnTestIterationEnd(const UnitTest& unit_test,
+ int iteration) = 0;
+
+ // Fired after all test activities have ended.
+ virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;
+};
+
+// The convenience class for users who need to override just one or two
+// methods and are not concerned that a possible change to a signature of
+// the methods they override will not be caught during the build. For
+// comments about each method please see the definition of TestEventListener
+// above.
+class EmptyTestEventListener : public TestEventListener {
+ public:
+ virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
+ virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
+ int /*iteration*/) {}
+ virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {}
+ virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
+ virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
+ virtual void OnTestStart(const TestInfo& /*test_info*/) {}
+ virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {}
+ virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
+ virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
+ virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {}
+ virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
+ virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
+ int /*iteration*/) {}
+ virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+};
+
+// TestEventListeners lets users add listeners to track events in Google Test.
+class GTEST_API_ TestEventListeners {
+ public:
+ TestEventListeners();
+ ~TestEventListeners();
+
+ // Appends an event listener to the end of the list. Google Test assumes
+ // the ownership of the listener (i.e. it will delete the listener when
+ // the test program finishes).
+ void Append(TestEventListener* listener);
+
+ // Removes the given event listener from the list and returns it. It then
+ // becomes the caller's responsibility to delete the listener. Returns
+ // NULL if the listener is not found in the list.
+ TestEventListener* Release(TestEventListener* listener);
+
+ // Returns the standard listener responsible for the default console
+ // output. Can be removed from the listeners list to shut down default
+ // console output. Note that removing this object from the listener list
+ // with Release transfers its ownership to the caller and makes this
+ // function return NULL the next time.
+ TestEventListener* default_result_printer() const {
+ return default_result_printer_;
+ }
+
+ // Returns the standard listener responsible for the default XML output
+ // controlled by the --gtest_output=xml flag. Can be removed from the
+ // listeners list by users who want to shut down the default XML output
+ // controlled by this flag and substitute it with custom one. Note that
+ // removing this object from the listener list with Release transfers its
+ // ownership to the caller and makes this function return NULL the next
+ // time.
+ TestEventListener* default_xml_generator() const {
+ return default_xml_generator_;
+ }
+
+ private:
+ friend class TestCase;
+ friend class internal::DefaultGlobalTestPartResultReporter;
+ friend class internal::NoExecDeathTest;
+ friend class internal::TestEventListenersAccessor;
+ friend class internal::TestInfoImpl;
+ friend class internal::UnitTestImpl;
+
+ // Returns repeater that broadcasts the TestEventListener events to all
+ // subscribers.
+ TestEventListener* repeater();
+
+ // Sets the default_result_printer attribute to the provided listener.
+ // The listener is also added to the listener list and previous
+ // default_result_printer is removed from it and deleted. The listener can
+ // also be NULL in which case it will not be added to the list. Does
+ // nothing if the previous and the current listener objects are the same.
+ void SetDefaultResultPrinter(TestEventListener* listener);
+
+ // Sets the default_xml_generator attribute to the provided listener. The
+ // listener is also added to the listener list and previous
+ // default_xml_generator is removed from it and deleted. The listener can
+ // also be NULL in which case it will not be added to the list. Does
+ // nothing if the previous and the current listener objects are the same.
+ void SetDefaultXmlGenerator(TestEventListener* listener);
+
+ // Controls whether events will be forwarded by the repeater to the
+ // listeners in the list.
+ bool EventForwardingEnabled() const;
+ void SuppressEventForwarding();
+
+ // The actual list of listeners.
+ internal::TestEventRepeater* repeater_;
+ // Listener responsible for the standard result output.
+ TestEventListener* default_result_printer_;
+ // Listener responsible for the creation of the XML output file.
+ TestEventListener* default_xml_generator_;
+
+ // We disallow copying TestEventListeners.
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners);
+};
+
+// A UnitTest consists of a vector of TestCases.
+//
+// This is a singleton class. The only instance of UnitTest is
+// created when UnitTest::GetInstance() is first called. This
+// instance is never deleted.
+//
+// UnitTest is not copyable.
+//
+// This class is thread-safe as long as the methods are called
+// according to their specification.
+class GTEST_API_ UnitTest {
+ public:
+ // Gets the singleton UnitTest object. The first time this method
+ // is called, a UnitTest object is constructed and returned.
+ // Consecutive calls will return the same object.
+ static UnitTest* GetInstance();
+
+ // Runs all tests in this UnitTest object and prints the result.
+ // Returns 0 if successful, or 1 otherwise.
+ //
+ // This method can only be called from the main thread.
+ //
+ // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+ int Run() GTEST_MUST_USE_RESULT_;
+
+ // Returns the working directory when the first TEST() or TEST_F()
+ // was executed. The UnitTest object owns the string.
+ const char* original_working_dir() const;
+
+ // Returns the TestCase object for the test that's currently running,
+ // or NULL if no test is running.
+ const TestCase* current_test_case() const;
+
+ // Returns the TestInfo object for the test that's currently running,
+ // or NULL if no test is running.
+ const TestInfo* current_test_info() const;
+
+ // Returns the random seed used at the start of the current test run.
+ int random_seed() const;
+
+#if GTEST_HAS_PARAM_TEST
+ // Returns the ParameterizedTestCaseRegistry object used to keep track of
+ // value-parameterized tests and instantiate and register them.
+ //
+ // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+ internal::ParameterizedTestCaseRegistry& parameterized_test_registry();
+#endif // GTEST_HAS_PARAM_TEST
+
+ // Gets the number of successful test cases.
+ int successful_test_case_count() const;
+
+ // Gets the number of failed test cases.
+ int failed_test_case_count() const;
+
+ // Gets the number of all test cases.
+ int total_test_case_count() const;
+
+ // Gets the number of all test cases that contain at least one test
+ // that should run.
+ int test_case_to_run_count() const;
+
+ // Gets the number of successful tests.
+ int successful_test_count() const;
+
+ // Gets the number of failed tests.
+ int failed_test_count() const;
+
+ // Gets the number of disabled tests.
+ int disabled_test_count() const;
+
+ // Gets the number of all tests.
+ int total_test_count() const;
+
+ // Gets the number of tests that should run.
+ int test_to_run_count() const;
+
+ // Gets the elapsed time, in milliseconds.
+ TimeInMillis elapsed_time() const;
+
+ // Returns true iff the unit test passed (i.e. all test cases passed).
+ bool Passed() const;
+
+ // Returns true iff the unit test failed (i.e. some test case failed
+ // or something outside of all tests failed).
+ bool Failed() const;
+
+ // Gets the i-th test case among all the test cases. i can range from 0 to
+ // total_test_case_count() - 1. If i is not in that range, returns NULL.
+ const TestCase* GetTestCase(int i) const;
+
+ // Returns the list of event listeners that can be used to track events
+ // inside Google Test.
+ TestEventListeners& listeners();
+
+ private:
+ // Registers and returns a global test environment. When a test
+ // program is run, all global test environments will be set-up in
+ // the order they were registered. After all tests in the program
+ // have finished, all global test environments will be torn-down in
+ // the *reverse* order they were registered.
+ //
+ // The UnitTest object takes ownership of the given environment.
+ //
+ // This method can only be called from the main thread.
+ Environment* AddEnvironment(Environment* env);
+
+ // Adds a TestPartResult to the current TestResult object. All
+ // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc)
+ // eventually call this to report their results. The user code
+ // should use the assertion macros instead of calling this directly.
+ void AddTestPartResult(TestPartResult::Type result_type,
+ const char* file_name,
+ int line_number,
+ const internal::String& message,
+ const internal::String& os_stack_trace);
+
+ // Adds a TestProperty to the current TestResult object. If the result already
+ // contains a property with the same key, the value will be updated.
+ void RecordPropertyForCurrentTest(const char* key, const char* value);
+
+ // Gets the i-th test case among all the test cases. i can range from 0 to
+ // total_test_case_count() - 1. If i is not in that range, returns NULL.
+ TestCase* GetMutableTestCase(int i);
+
+ // Accessors for the implementation object.
+ internal::UnitTestImpl* impl() { return impl_; }
+ const internal::UnitTestImpl* impl() const { return impl_; }
+
+ // These classes and funcions are friends as they need to access private
+ // members of UnitTest.
+ friend class Test;
+ friend class internal::AssertHelper;
+ friend class internal::ScopedTrace;
+ friend Environment* AddGlobalTestEnvironment(Environment* env);
+ friend internal::UnitTestImpl* internal::GetUnitTestImpl();
+ friend void internal::ReportFailureInUnknownLocation(
+ TestPartResult::Type result_type,
+ const internal::String& message);
+
+ // Creates an empty UnitTest.
+ UnitTest();
+
+ // D'tor
+ virtual ~UnitTest();
+
+ // Pushes a trace defined by SCOPED_TRACE() on to the per-thread
+ // Google Test trace stack.
+ void PushGTestTrace(const internal::TraceInfo& trace);
+
+ // Pops a trace from the per-thread Google Test trace stack.
+ void PopGTestTrace();
+
+ // Protects mutable state in *impl_. This is mutable as some const
+ // methods need to lock it too.
+ mutable internal::Mutex mutex_;
+
+ // Opaque implementation object. This field is never changed once
+ // the object is constructed. We don't mark it as const here, as
+ // doing so will cause a warning in the constructor of UnitTest.
+ // Mutable state in *impl_ is protected by mutex_.
+ internal::UnitTestImpl* impl_;
+
+ // We disallow copying UnitTest.
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest);
+};
+
+// A convenient wrapper for adding an environment for the test
+// program.
+//
+// You should call this before RUN_ALL_TESTS() is called, probably in
+// main(). If you use gtest_main, you need to call this before main()
+// starts for it to take effect. For example, you can define a global
+// variable like this:
+//
+// testing::Environment* const foo_env =
+// testing::AddGlobalTestEnvironment(new FooEnvironment);
+//
+// However, we strongly recommend you to write your own main() and
+// call AddGlobalTestEnvironment() there, as relying on initialization
+// of global variables makes the code harder to read and may cause
+// problems when you register multiple environments from different
+// translation units and the environments have dependencies among them
+// (remember that the compiler doesn't guarantee the order in which
+// global variables from different translation units are initialized).
+inline Environment* AddGlobalTestEnvironment(Environment* env) {
+ return UnitTest::GetInstance()->AddEnvironment(env);
+}
+
+// Initializes Google Test. This must be called before calling
+// RUN_ALL_TESTS(). In particular, it parses a command line for the
+// flags that Google Test recognizes. Whenever a Google Test flag is
+// seen, it is removed from argv, and *argc is decremented.
+//
+// No value is returned. Instead, the Google Test flag variables are
+// updated.
+//
+// Calling the function for the second time has no user-visible effect.
+GTEST_API_ void InitGoogleTest(int* argc, char** argv);
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);
+
+namespace internal {
+
+// These overloaded versions handle ::std::string and ::std::wstring.
+GTEST_API_ inline String FormatForFailureMessage(const ::std::string& str) {
+ return (Message() << '"' << str << '"').GetString();
+}
+
+#if GTEST_HAS_STD_WSTRING
+GTEST_API_ inline String FormatForFailureMessage(const ::std::wstring& wstr) {
+ return (Message() << "L\"" << wstr << '"').GetString();
+}
+#endif // GTEST_HAS_STD_WSTRING
+
+// These overloaded versions handle ::string and ::wstring.
+#if GTEST_HAS_GLOBAL_STRING
+GTEST_API_ inline String FormatForFailureMessage(const ::string& str) {
+ return (Message() << '"' << str << '"').GetString();
+}
+#endif // GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+GTEST_API_ inline String FormatForFailureMessage(const ::wstring& wstr) {
+ return (Message() << "L\"" << wstr << '"').GetString();
+}
+#endif // GTEST_HAS_GLOBAL_WSTRING
+
+// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
+// operand to be used in a failure message. The type (but not value)
+// of the other operand may affect the format. This allows us to
+// print a char* as a raw pointer when it is compared against another
+// char*, and print it as a C string when it is compared against an
+// std::string object, for example.
+//
+// The default implementation ignores the type of the other operand.
+// Some specialized versions are used to handle formatting wide or
+// narrow C strings.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+template <typename T1, typename T2>
+String FormatForComparisonFailureMessage(const T1& value,
+ const T2& /* other_operand */) {
+ return FormatForFailureMessage(value);
+}
+
+// The helper function for {ASSERT|EXPECT}_EQ.
+template <typename T1, typename T2>
+AssertionResult CmpHelperEQ(const char* expected_expression,
+ const char* actual_expression,
+ const T1& expected,
+ const T2& actual) {
+#ifdef _MSC_VER
+#pragma warning(push) // Saves the current warning state.
+#pragma warning(disable:4389) // Temporarily disables warning on
+ // signed/unsigned mismatch.
+#endif
+
+ if (expected == actual) {
+ return AssertionSuccess();
+ }
+
+#ifdef _MSC_VER
+#pragma warning(pop) // Restores the warning state.
+#endif
+
+ return EqFailure(expected_expression,
+ actual_expression,
+ FormatForComparisonFailureMessage(expected, actual),
+ FormatForComparisonFailureMessage(actual, expected),
+ false);
+}
+
+// With this overloaded version, we allow anonymous enums to be used
+// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums
+// can be implicitly cast to BiggestInt.
+GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression,
+ const char* actual_expression,
+ BiggestInt expected,
+ BiggestInt actual);
+
+// The helper class for {ASSERT|EXPECT}_EQ. The template argument
+// lhs_is_null_literal is true iff the first argument to ASSERT_EQ()
+// is a null pointer literal. The following default implementation is
+// for lhs_is_null_literal being false.
+template <bool lhs_is_null_literal>
+class EqHelper {
+ public:
+ // This templatized version is for the general case.
+ template <typename T1, typename T2>
+ static AssertionResult Compare(const char* expected_expression,
+ const char* actual_expression,
+ const T1& expected,
+ const T2& actual) {
+ return CmpHelperEQ(expected_expression, actual_expression, expected,
+ actual);
+ }
+
+ // With this overloaded version, we allow anonymous enums to be used
+ // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous
+ // enums can be implicitly cast to BiggestInt.
+ //
+ // Even though its body looks the same as the above version, we
+ // cannot merge the two, as it will make anonymous enums unhappy.
+ static AssertionResult Compare(const char* expected_expression,
+ const char* actual_expression,
+ BiggestInt expected,
+ BiggestInt actual) {
+ return CmpHelperEQ(expected_expression, actual_expression, expected,
+ actual);
+ }
+};
+
+// This specialization is used when the first argument to ASSERT_EQ()
+// is a null pointer literal.
+template <>
+class EqHelper<true> {
+ public:
+ // We define two overloaded versions of Compare(). The first
+ // version will be picked when the second argument to ASSERT_EQ() is
+ // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or
+ // EXPECT_EQ(false, a_bool).
+ template <typename T1, typename T2>
+ static AssertionResult Compare(const char* expected_expression,
+ const char* actual_expression,
+ const T1& expected,
+ const T2& actual) {
+ return CmpHelperEQ(expected_expression, actual_expression, expected,
+ actual);
+ }
+
+ // This version will be picked when the second argument to
+ // ASSERT_EQ() is a pointer, e.g. ASSERT_EQ(NULL, a_pointer).
+ template <typename T1, typename T2>
+ static AssertionResult Compare(const char* expected_expression,
+ const char* actual_expression,
+ const T1& /* expected */,
+ T2* actual) {
+ // We already know that 'expected' is a null pointer.
+ return CmpHelperEQ(expected_expression, actual_expression,
+ static_cast<T2*>(NULL), actual);
+ }
+};
+
+// A macro for implementing the helper functions needed to implement
+// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste
+// of similar code.
+//
+// For each templatized helper function, we also define an overloaded
+// version for BiggestInt in order to reduce code bloat and allow
+// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled
+// with gcc 4.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+#define GTEST_IMPL_CMP_HELPER_(op_name, op)\
+template <typename T1, typename T2>\
+AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
+ const T1& val1, const T2& val2) {\
+ if (val1 op val2) {\
+ return AssertionSuccess();\
+ } else {\
+ Message msg;\
+ msg << "Expected: (" << expr1 << ") " #op " (" << expr2\
+ << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\
+ << " vs " << FormatForComparisonFailureMessage(val2, val1);\
+ return AssertionFailure(msg);\
+ }\
+}\
+GTEST_API_ AssertionResult CmpHelper##op_name(\
+ const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2)
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+
+// Implements the helper function for {ASSERT|EXPECT}_NE
+GTEST_IMPL_CMP_HELPER_(NE, !=);
+// Implements the helper function for {ASSERT|EXPECT}_LE
+GTEST_IMPL_CMP_HELPER_(LE, <=);
+// Implements the helper function for {ASSERT|EXPECT}_LT
+GTEST_IMPL_CMP_HELPER_(LT, < );
+// Implements the helper function for {ASSERT|EXPECT}_GE
+GTEST_IMPL_CMP_HELPER_(GE, >=);
+// Implements the helper function for {ASSERT|EXPECT}_GT
+GTEST_IMPL_CMP_HELPER_(GT, > );
+
+#undef GTEST_IMPL_CMP_HELPER_
+
+// The helper function for {ASSERT|EXPECT}_STREQ.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression,
+ const char* actual_expression,
+ const char* expected,
+ const char* actual);
+
+// The helper function for {ASSERT|EXPECT}_STRCASEEQ.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,
+ const char* actual_expression,
+ const char* expected,
+ const char* actual);
+
+// The helper function for {ASSERT|EXPECT}_STRNE.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
+ const char* s2_expression,
+ const char* s1,
+ const char* s2);
+
+// The helper function for {ASSERT|EXPECT}_STRCASENE.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
+ const char* s2_expression,
+ const char* s1,
+ const char* s2);
+
+
+// Helper function for *_STREQ on wide strings.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression,
+ const char* actual_expression,
+ const wchar_t* expected,
+ const wchar_t* actual);
+
+// Helper function for *_STRNE on wide strings.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
+ const char* s2_expression,
+ const wchar_t* s1,
+ const wchar_t* s2);
+
+} // namespace internal
+
+// IsSubstring() and IsNotSubstring() are intended to be used as the
+// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by
+// themselves. They check whether needle is a substring of haystack
+// (NULL is considered a substring of itself only), and return an
+// appropriate error message when they fail.
+//
+// The {needle,haystack}_expr arguments are the stringified
+// expressions that generated the two real arguments.
+GTEST_API_ AssertionResult IsSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const char* needle, const char* haystack);
+GTEST_API_ AssertionResult IsSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const wchar_t* needle, const wchar_t* haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const char* needle, const char* haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const wchar_t* needle, const wchar_t* haystack);
+GTEST_API_ AssertionResult IsSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const ::std::string& needle, const ::std::string& haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const ::std::string& needle, const ::std::string& haystack);
+
+#if GTEST_HAS_STD_WSTRING
+GTEST_API_ AssertionResult IsSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const ::std::wstring& needle, const ::std::wstring& haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+ const char* needle_expr, const char* haystack_expr,
+ const ::std::wstring& needle, const ::std::wstring& haystack);
+#endif // GTEST_HAS_STD_WSTRING
+
+namespace internal {
+
+// Helper template function for comparing floating-points.
+//
+// Template parameter:
+//
+// RawType: the raw floating-point type (either float or double)
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+template <typename RawType>
+AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression,
+ const char* actual_expression,
+ RawType expected,
+ RawType actual) {
+ const FloatingPoint<RawType> lhs(expected), rhs(actual);
+
+ if (lhs.AlmostEquals(rhs)) {
+ return AssertionSuccess();
+ }
+
+ StrStream expected_ss;
+ expected_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+ << expected;
+
+ StrStream actual_ss;
+ actual_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+ << actual;
+
+ return EqFailure(expected_expression,
+ actual_expression,
+ StrStreamToString(&expected_ss),
+ StrStreamToString(&actual_ss),
+ false);
+}
+
+// Helper function for implementing ASSERT_NEAR.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
+ const char* expr2,
+ const char* abs_error_expr,
+ double val1,
+ double val2,
+ double abs_error);
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+// A class that enables one to stream messages to assertion macros
+class GTEST_API_ AssertHelper {
+ public:
+ // Constructor.
+ AssertHelper(TestPartResult::Type type,
+ const char* file,
+ int line,
+ const char* message);
+ ~AssertHelper();
+
+ // Message assignment is a semantic trick to enable assertion
+ // streaming; see the GTEST_MESSAGE_ macro below.
+ void operator=(const Message& message) const;
+
+ private:
+ // We put our data in a struct so that the size of the AssertHelper class can
+ // be as small as possible. This is important because gcc is incapable of
+ // re-using stack space even for temporary variables, so every EXPECT_EQ
+ // reserves stack space for another AssertHelper.
+ struct AssertHelperData {
+ AssertHelperData(TestPartResult::Type t,
+ const char* srcfile,
+ int line_num,
+ const char* msg)
+ : type(t), file(srcfile), line(line_num), message(msg) { }
+
+ TestPartResult::Type const type;
+ const char* const file;
+ int const line;
+ String const message;
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData);
+ };
+
+ AssertHelperData* const data_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);
+};
+
+} // namespace internal
+
+#if GTEST_HAS_PARAM_TEST
+// The abstract base class that all value-parameterized tests inherit from.
+//
+// This class adds support for accessing the test parameter value via
+// the GetParam() method.
+//
+// Use it with one of the parameter generator defining functions, like Range(),
+// Values(), ValuesIn(), Bool(), and Combine().
+//
+// class FooTest : public ::testing::TestWithParam<int> {
+// protected:
+// FooTest() {
+// // Can use GetParam() here.
+// }
+// virtual ~FooTest() {
+// // Can use GetParam() here.
+// }
+// virtual void SetUp() {
+// // Can use GetParam() here.
+// }
+// virtual void TearDown {
+// // Can use GetParam() here.
+// }
+// };
+// TEST_P(FooTest, DoesBar) {
+// // Can use GetParam() method here.
+// Foo foo;
+// ASSERT_TRUE(foo.DoesBar(GetParam()));
+// }
+// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
+
+template <typename T>
+class TestWithParam : public Test {
+ public:
+ typedef T ParamType;
+
+ // The current parameter value. Is also available in the test fixture's
+ // constructor.
+ const ParamType& GetParam() const { return *parameter_; }
+
+ private:
+ // Sets parameter value. The caller is responsible for making sure the value
+ // remains alive and unchanged throughout the current test.
+ static void SetParam(const ParamType* parameter) {
+ parameter_ = parameter;
+ }
+
+ // Static value used for accessing parameter during a test lifetime.
+ static const ParamType* parameter_;
+
+ // TestClass must be a subclass of TestWithParam<T>.
+ template <class TestClass> friend class internal::ParameterizedTestFactory;
+};
+
+template <typename T>
+const T* TestWithParam<T>::parameter_ = NULL;
+
+#endif // GTEST_HAS_PARAM_TEST
+
+// Macros for indicating success/failure in test code.
+
+// ADD_FAILURE unconditionally adds a failure to the current test.
+// SUCCEED generates a success - it doesn't automatically make the
+// current test successful, as a test is only successful when it has
+// no failure.
+//
+// EXPECT_* verifies that a certain condition is satisfied. If not,
+// it behaves like ADD_FAILURE. In particular:
+//
+// EXPECT_TRUE verifies that a Boolean condition is true.
+// EXPECT_FALSE verifies that a Boolean condition is false.
+//
+// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except
+// that they will also abort the current function on failure. People
+// usually want the fail-fast behavior of FAIL and ASSERT_*, but those
+// writing data-driven tests often find themselves using ADD_FAILURE
+// and EXPECT_* more.
+//
+// Examples:
+//
+// EXPECT_TRUE(server.StatusIsOK());
+// ASSERT_FALSE(server.HasPendingRequest(port))
+// << "There are still pending requests " << "on port " << port;
+
+// Generates a nonfatal failure with a generic message.
+#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed")
+
+// Generates a fatal failure with a generic message.
+#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed")
+
+// Define this macro to 1 to omit the definition of FAIL(), which is a
+// generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_FAIL
+#define FAIL() GTEST_FAIL()
+#endif
+
+// Generates a success with a generic message.
+#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded")
+
+// Define this macro to 1 to omit the definition of SUCCEED(), which
+// is a generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_SUCCEED
+#define SUCCEED() GTEST_SUCCEED()
+#endif
+
+// Macros for testing exceptions.
+//
+// * {ASSERT|EXPECT}_THROW(statement, expected_exception):
+// Tests that the statement throws the expected exception.
+// * {ASSERT|EXPECT}_NO_THROW(statement):
+// Tests that the statement doesn't throw any exception.
+// * {ASSERT|EXPECT}_ANY_THROW(statement):
+// Tests that the statement throws an exception.
+
+#define EXPECT_THROW(statement, expected_exception) \
+ GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_NO_THROW(statement) \
+ GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_ANY_THROW(statement) \
+ GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_THROW(statement, expected_exception) \
+ GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_)
+#define ASSERT_NO_THROW(statement) \
+ GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_)
+#define ASSERT_ANY_THROW(statement) \
+ GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)
+
+// Boolean assertions. Condition can be either a Boolean expression or an
+// AssertionResult. For more information on how to use AssertionResult with
+// these macros see comments on that class.
+#define EXPECT_TRUE(condition) \
+ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
+ GTEST_NONFATAL_FAILURE_)
+#define EXPECT_FALSE(condition) \
+ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
+ GTEST_NONFATAL_FAILURE_)
+#define ASSERT_TRUE(condition) \
+ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
+ GTEST_FATAL_FAILURE_)
+#define ASSERT_FALSE(condition) \
+ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
+ GTEST_FATAL_FAILURE_)
+
+// Includes the auto-generated header that implements a family of
+// generic predicate assertion macros.
+// Copyright 2006, Google Inc.
+// All rights reserved.
+//
+// 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 is AUTOMATICALLY GENERATED on 10/02/2008 by command
+// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
+//
+// Implements a family of generic predicate assertion macros.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+
+// Makes sure this header is not included before gtest.h.
+#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
+#error Do not include gtest_pred_impl.h directly. Include gtest.h instead.
+#endif // GTEST_INCLUDE_GTEST_GTEST_H_
+
+// This header implements a family of generic predicate assertion
+// macros:
+//
+// ASSERT_PRED_FORMAT1(pred_format, v1)
+// ASSERT_PRED_FORMAT2(pred_format, v1, v2)
+// ...
+//
+// where pred_format is a function or functor that takes n (in the
+// case of ASSERT_PRED_FORMATn) values and their source expression
+// text, and returns a testing::AssertionResult. See the definition
+// of ASSERT_EQ in gtest.h for an example.
+//
+// If you don't care about formatting, you can use the more
+// restrictive version:
+//
+// ASSERT_PRED1(pred, v1)
+// ASSERT_PRED2(pred, v1, v2)
+// ...
+//
+// where pred is an n-ary function or functor that returns bool,
+// and the values v1, v2, ..., must support the << operator for
+// streaming to std::ostream.
+//
+// We also define the EXPECT_* variations.
+//
+// For now we only support predicates whose arity is at most 5.
+// Please email googletestframework@googlegroups.com if you need
+// support for higher arities.
+
+// GTEST_ASSERT_ is the basic statement to which all of the assertions
+// in this file reduce. Don't use this in your code.
+
+#define GTEST_ASSERT_(expression, on_failure) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (const ::testing::AssertionResult gtest_ar = (expression)) \
+ ; \
+ else \
+ on_failure(gtest_ar.failure_message())
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use
+// this in your code.
+template <typename Pred,
+ typename T1>
+AssertionResult AssertPred1Helper(const char* pred_text,
+ const char* e1,
+ Pred pred,
+ const T1& v1) {
+ if (pred(v1)) return AssertionSuccess();
+
+ Message msg;
+ msg << pred_text << "("
+ << e1 << ") evaluates to false, where"
+ << "\n" << e1 << " evaluates to " << v1;
+ return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
+ GTEST_ASSERT_(pred_format(#v1, v1),\
+ on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
+// this in your code.
+#define GTEST_PRED1_(pred, v1, on_failure)\
+ GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \
+ #v1, \
+ pred, \
+ v1), on_failure)
+
+// Unary predicate assertion macros.
+#define EXPECT_PRED_FORMAT1(pred_format, v1) \
+ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED1(pred, v1) \
+ GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT1(pred_format, v1) \
+ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED1(pred, v1) \
+ GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use
+// this in your code.
+template <typename Pred,
+ typename T1,
+ typename T2>
+AssertionResult AssertPred2Helper(const char* pred_text,
+ const char* e1,
+ const char* e2,
+ Pred pred,
+ const T1& v1,
+ const T2& v2) {
+ if (pred(v1, v2)) return AssertionSuccess();
+
+ Message msg;
+ msg << pred_text << "("
+ << e1 << ", "
+ << e2 << ") evaluates to false, where"
+ << "\n" << e1 << " evaluates to " << v1
+ << "\n" << e2 << " evaluates to " << v2;
+ return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
+ GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2),\
+ on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
+// this in your code.
+#define GTEST_PRED2_(pred, v1, v2, on_failure)\
+ GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \
+ #v1, \
+ #v2, \
+ pred, \
+ v1, \
+ v2), on_failure)
+
+// Binary predicate assertion macros.
+#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
+ GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED2(pred, v1, v2) \
+ GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
+ GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED2(pred, v1, v2) \
+ GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use
+// this in your code.
+template <typename Pred,
+ typename T1,
+ typename T2,
+ typename T3>
+AssertionResult AssertPred3Helper(const char* pred_text,
+ const char* e1,
+ const char* e2,
+ const char* e3,
+ Pred pred,
+ const T1& v1,
+ const T2& v2,
+ const T3& v3) {
+ if (pred(v1, v2, v3)) return AssertionSuccess();
+
+ Message msg;
+ msg << pred_text << "("
+ << e1 << ", "
+ << e2 << ", "
+ << e3 << ") evaluates to false, where"
+ << "\n" << e1 << " evaluates to " << v1
+ << "\n" << e2 << " evaluates to " << v2
+ << "\n" << e3 << " evaluates to " << v3;
+ return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
+ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3),\
+ on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
+// this in your code.
+#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\
+ GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \
+ #v1, \
+ #v2, \
+ #v3, \
+ pred, \
+ v1, \
+ v2, \
+ v3), on_failure)
+
+// Ternary predicate assertion macros.
+#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
+ GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED3(pred, v1, v2, v3) \
+ GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
+ GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED3(pred, v1, v2, v3) \
+ GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use
+// this in your code.
+template <typename Pred,
+ typename T1,
+ typename T2,
+ typename T3,
+ typename T4>
+AssertionResult AssertPred4Helper(const char* pred_text,
+ const char* e1,
+ const char* e2,
+ const char* e3,
+ const char* e4,
+ Pred pred,
+ const T1& v1,
+ const T2& v2,
+ const T3& v3,
+ const T4& v4) {
+ if (pred(v1, v2, v3, v4)) return AssertionSuccess();
+
+ Message msg;
+ msg << pred_text << "("
+ << e1 << ", "
+ << e2 << ", "
+ << e3 << ", "
+ << e4 << ") evaluates to false, where"
+ << "\n" << e1 << " evaluates to " << v1
+ << "\n" << e2 << " evaluates to " << v2
+ << "\n" << e3 << " evaluates to " << v3
+ << "\n" << e4 << " evaluates to " << v4;
+ return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
+ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4),\
+ on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
+// this in your code.
+#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\
+ GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \
+ #v1, \
+ #v2, \
+ #v3, \
+ #v4, \
+ pred, \
+ v1, \
+ v2, \
+ v3, \
+ v4), on_failure)
+
+// 4-ary predicate assertion macros.
+#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
+ GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
+ GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
+ GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
+ GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use
+// this in your code.
+template <typename Pred,
+ typename T1,
+ typename T2,
+ typename T3,
+ typename T4,
+ typename T5>
+AssertionResult AssertPred5Helper(const char* pred_text,
+ const char* e1,
+ const char* e2,
+ const char* e3,
+ const char* e4,
+ const char* e5,
+ Pred pred,
+ const T1& v1,
+ const T2& v2,
+ const T3& v3,
+ const T4& v4,
+ const T5& v5) {
+ if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
+
+ Message msg;
+ msg << pred_text << "("
+ << e1 << ", "
+ << e2 << ", "
+ << e3 << ", "
+ << e4 << ", "
+ << e5 << ") evaluates to false, where"
+ << "\n" << e1 << " evaluates to " << v1
+ << "\n" << e2 << " evaluates to " << v2
+ << "\n" << e3 << " evaluates to " << v3
+ << "\n" << e4 << " evaluates to " << v4
+ << "\n" << e5 << " evaluates to " << v5;
+ return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
+ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5),\
+ on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
+// this in your code.
+#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\
+ GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \
+ #v1, \
+ #v2, \
+ #v3, \
+ #v4, \
+ #v5, \
+ pred, \
+ v1, \
+ v2, \
+ v3, \
+ v4, \
+ v5), on_failure)
+
+// 5-ary predicate assertion macros.
+#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
+ GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
+ GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
+ GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
+ GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
+
+
+
+#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+
+// Macros for testing equalities and inequalities.
+//
+// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
+// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2
+// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2
+// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2
+// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2
+// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2
+//
+// When they are not, Google Test prints both the tested expressions and
+// their actual values. The values must be compatible built-in types,
+// or you will get a compiler error. By "compatible" we mean that the
+// values can be compared by the respective operator.
+//
+// Note:
+//
+// 1. It is possible to make a user-defined type work with
+// {ASSERT|EXPECT}_??(), but that requires overloading the
+// comparison operators and is thus discouraged by the Google C++
+// Usage Guide. Therefore, you are advised to use the
+// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are
+// equal.
+//
+// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on
+// pointers (in particular, C strings). Therefore, if you use it
+// with two C strings, you are testing how their locations in memory
+// are related, not how their content is related. To compare two C
+// strings by content, use {ASSERT|EXPECT}_STR*().
+//
+// 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to
+// {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you
+// what the actual value is when it fails, and similarly for the
+// other comparisons.
+//
+// 4. Do not depend on the order in which {ASSERT|EXPECT}_??()
+// evaluate their arguments, which is undefined.
+//
+// 5. These macros evaluate their arguments exactly once.
+//
+// Examples:
+//
+// EXPECT_NE(5, Foo());
+// EXPECT_EQ(NULL, a_pointer);
+// ASSERT_LT(i, array_size);
+// ASSERT_GT(records.size(), 0) << "There is no record left.";
+
+#define EXPECT_EQ(expected, actual) \
+ EXPECT_PRED_FORMAT2(::testing::internal:: \
+ EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \
+ expected, actual)
+#define EXPECT_NE(expected, actual) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual)
+#define EXPECT_LE(val1, val2) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)
+#define EXPECT_LT(val1, val2) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)
+#define EXPECT_GE(val1, val2) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)
+#define EXPECT_GT(val1, val2) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)
+
+#define ASSERT_EQ(expected, actual) \
+ ASSERT_PRED_FORMAT2(::testing::internal:: \
+ EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \
+ expected, actual)
+#define ASSERT_NE(val1, val2) \
+ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)
+#define ASSERT_LE(val1, val2) \
+ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)
+#define ASSERT_LT(val1, val2) \
+ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)
+#define ASSERT_GE(val1, val2) \
+ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)
+#define ASSERT_GT(val1, val2) \
+ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)
+
+// C String Comparisons. All tests treat NULL and any non-NULL string
+// as different. Two NULLs are equal.
+//
+// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2
+// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2
+// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case
+// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case
+//
+// For wide or narrow string objects, you can use the
+// {ASSERT|EXPECT}_??() macros.
+//
+// Don't depend on the order in which the arguments are evaluated,
+// which is undefined.
+//
+// These macros evaluate their arguments exactly once.
+
+#define EXPECT_STREQ(expected, actual) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)
+#define EXPECT_STRNE(s1, s2) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
+#define EXPECT_STRCASEEQ(expected, actual) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)
+#define EXPECT_STRCASENE(s1, s2)\
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)
+
+#define ASSERT_STREQ(expected, actual) \
+ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)
+#define ASSERT_STRNE(s1, s2) \
+ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
+#define ASSERT_STRCASEEQ(expected, actual) \
+ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)
+#define ASSERT_STRCASENE(s1, s2)\
+ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)
+
+// Macros for comparing floating-point numbers.
+//
+// * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual):
+// Tests that two float values are almost equal.
+// * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual):
+// Tests that two double values are almost equal.
+// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error):
+// Tests that v1 and v2 are within the given distance to each other.
+//
+// Google Test uses ULP-based comparison to automatically pick a default
+// error bound that is appropriate for the operands. See the
+// FloatingPoint template class in gtest-internal.h if you are
+// interested in the implementation details.
+
+#define EXPECT_FLOAT_EQ(expected, actual)\
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
+ expected, actual)
+
+#define EXPECT_DOUBLE_EQ(expected, actual)\
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
+ expected, actual)
+
+#define ASSERT_FLOAT_EQ(expected, actual)\
+ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
+ expected, actual)
+
+#define ASSERT_DOUBLE_EQ(expected, actual)\
+ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
+ expected, actual)
+
+#define EXPECT_NEAR(val1, val2, abs_error)\
+ EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \
+ val1, val2, abs_error)
+
+#define ASSERT_NEAR(val1, val2, abs_error)\
+ ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \
+ val1, val2, abs_error)
+
+// These predicate format functions work on floating-point values, and
+// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g.
+//
+// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0);
+
+// Asserts that val1 is less than, or almost equal to, val2. Fails
+// otherwise. In particular, it fails if either val1 or val2 is NaN.
+GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2,
+ float val1, float val2);
+GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
+ double val1, double val2);
+
+
+#if GTEST_OS_WINDOWS
+
+// Macros that test for HRESULT failure and success, these are only useful
+// on Windows, and rely on Windows SDK macros and APIs to compile.
+//
+// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr)
+//
+// When expr unexpectedly fails or succeeds, Google Test prints the
+// expected result and the actual result with both a human-readable
+// string representation of the error, if available, as well as the
+// hex result code.
+#define EXPECT_HRESULT_SUCCEEDED(expr) \
+ EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
+
+#define ASSERT_HRESULT_SUCCEEDED(expr) \
+ ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
+
+#define EXPECT_HRESULT_FAILED(expr) \
+ EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))
+
+#define ASSERT_HRESULT_FAILED(expr) \
+ ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))
+
+#endif // GTEST_OS_WINDOWS
+
+// Macros that execute statement and check that it doesn't generate new fatal
+// failures in the current thread.
+//
+// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement);
+//
+// Examples:
+//
+// EXPECT_NO_FATAL_FAILURE(Process());
+// ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed";
+//
+#define ASSERT_NO_FATAL_FAILURE(statement) \
+ GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_)
+#define EXPECT_NO_FATAL_FAILURE(statement) \
+ GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)
+
+// Causes a trace (including the source file path, the current line
+// number, and the given message) to be included in every test failure
+// message generated by code in the current scope. The effect is
+// undone when the control leaves the current scope.
+//
+// The message argument can be anything streamable to std::ostream.
+//
+// In the implementation, we include the current line number as part
+// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s
+// to appear in the same block - as long as they are on different
+// lines.
+#define SCOPED_TRACE(message) \
+ ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
+ __FILE__, __LINE__, ::testing::Message() << (message))
+
+namespace internal {
+
+// This template is declared, but intentionally undefined.
+template <typename T1, typename T2>
+struct StaticAssertTypeEqHelper;
+
+template <typename T>
+struct StaticAssertTypeEqHelper<T, T> {};
+
+} // namespace internal
+
+// Compile-time assertion for type equality.
+// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are
+// the same type. The value it returns is not interesting.
+//
+// Instead of making StaticAssertTypeEq a class template, we make it a
+// function template that invokes a helper class template. This
+// prevents a user from misusing StaticAssertTypeEq<T1, T2> by
+// defining objects of that type.
+//
+// CAVEAT:
+//
+// When used inside a method of a class template,
+// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is
+// instantiated. For example, given:
+//
+// template <typename T> class Foo {
+// public:
+// void Bar() { testing::StaticAssertTypeEq<int, T>(); }
+// };
+//
+// the code:
+//
+// void Test1() { Foo<bool> foo; }
+//
+// will NOT generate a compiler error, as Foo<bool>::Bar() is never
+// actually instantiated. Instead, you need:
+//
+// void Test2() { Foo<bool> foo; foo.Bar(); }
+//
+// to cause a compiler error.
+template <typename T1, typename T2>
+bool StaticAssertTypeEq() {
+ internal::StaticAssertTypeEqHelper<T1, T2>();
+ return true;
+}
+
+// Defines a test.
+//
+// The first parameter is the name of the test case, and the second
+// parameter is the name of the test within the test case.
+//
+// The convention is to end the test case name with "Test". For
+// example, a test case for the Foo class can be named FooTest.
+//
+// The user should put his test code between braces after using this
+// macro. Example:
+//
+// TEST(FooTest, InitializesCorrectly) {
+// Foo foo;
+// EXPECT_TRUE(foo.StatusIsOK());
+// }
+
+// Note that we call GetTestTypeId() instead of GetTypeId<
+// ::testing::Test>() here to get the type ID of testing::Test. This
+// is to work around a suspected linker bug when using Google Test as
+// a framework on Mac OS X. The bug causes GetTypeId<
+// ::testing::Test>() to return different values depending on whether
+// the call is from the Google Test framework itself or from user test
+// code. GetTestTypeId() is guaranteed to always return the same
+// value, as it always calls GetTypeId<>() from the Google Test
+// framework.
+#define GTEST_TEST(test_case_name, test_name)\
+ GTEST_TEST_(test_case_name, test_name, \
+ ::testing::Test, ::testing::internal::GetTestTypeId())
+
+// Define this macro to 1 to omit the definition of TEST(), which
+// is a generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_TEST
+#define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)
+#endif
+
+// Defines a test that uses a test fixture.
+//
+// The first parameter is the name of the test fixture class, which
+// also doubles as the test case name. The second parameter is the
+// name of the test within the test case.
+//
+// A test fixture class must be declared earlier. The user should put
+// his test code between braces after using this macro. Example:
+//
+// class FooTest : public testing::Test {
+// protected:
+// virtual void SetUp() { b_.AddElement(3); }
+//
+// Foo a_;
+// Foo b_;
+// };
+//
+// TEST_F(FooTest, InitializesCorrectly) {
+// EXPECT_TRUE(a_.StatusIsOK());
+// }
+//
+// TEST_F(FooTest, ReturnsElementCountCorrectly) {
+// EXPECT_EQ(0, a_.size());
+// EXPECT_EQ(1, b_.size());
+// }
+
+#define TEST_F(test_fixture, test_name)\
+ GTEST_TEST_(test_fixture, test_name, test_fixture, \
+ ::testing::internal::GetTypeId<test_fixture>())
+
+// Use this macro in main() to run all tests. It returns 0 if all
+// tests are successful, or 1 otherwise.
+//
+// RUN_ALL_TESTS() should be invoked after the command line has been
+// parsed by InitGoogleTest().
+
+#define RUN_ALL_TESTS()\
+ (::testing::UnitTest::GetInstance()->Run())
+
+} // namespace testing
+
+#endif // GTEST_INCLUDE_GTEST_GTEST_H_
diff --git a/gtest/fused-src/gtest/gtest_main.cc b/gtest/fused-src/gtest/gtest_main.cc
new file mode 100644
index 0000000..d20c02f
--- /dev/null
+++ b/gtest/fused-src/gtest/gtest_main.cc
@@ -0,0 +1,39 @@
+// Copyright 2006, Google Inc.
+// All rights reserved.
+//
+// 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 <iostream>
+
+#include <gtest/gtest.h>
+
+int main(int argc, char **argv) {
+ std::cout << "Running main() from gtest_main.cc\n";
+
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/gtest/include/gtest/gtest-death-test.h b/gtest/include/gtest/gtest-death-test.h
index fdb497f..121dc1f 100644
--- a/gtest/include/gtest/gtest-death-test.h
+++ b/gtest/include/gtest/gtest-death-test.h
@@ -176,7 +176,7 @@ GTEST_DECLARE_string_(death_test_style);
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
// Tests that an exit code describes a normal exit with a given exit code.
-class ExitedWithCode {
+class GTEST_API_ ExitedWithCode {
public:
explicit ExitedWithCode(int exit_code);
bool operator()(int exit_status) const;
@@ -190,7 +190,7 @@ class ExitedWithCode {
#if !GTEST_OS_WINDOWS
// Tests that an exit code describes an exit due to termination by a
// given signal.
-class KilledBySignal {
+class GTEST_API_ KilledBySignal {
public:
explicit KilledBySignal(int signum);
bool operator()(int exit_status) const;
diff --git a/gtest/include/gtest/gtest-message.h b/gtest/include/gtest/gtest-message.h
index 6398712..f135b69 100644
--- a/gtest/include/gtest/gtest-message.h
+++ b/gtest/include/gtest/gtest-message.h
@@ -46,6 +46,8 @@
#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
+#include <limits>
+
#include <gtest/internal/gtest-string.h>
#include <gtest/internal/gtest-internal.h>
@@ -77,7 +79,7 @@ namespace testing {
// latter (it causes an access violation if you do). The Message
// class hides this difference by treating a NULL char pointer as
// "(null)".
-class Message {
+class GTEST_API_ Message {
private:
// The type of basic IO manipulators (endl, ends, and flush) for
// narrow streams.
@@ -89,7 +91,11 @@ class Message {
// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's
// stack frame leading to huge stack frames in some cases; gcc does not reuse
// the stack space.
- Message() : ss_(new internal::StrStream) {}
+ Message() : ss_(new internal::StrStream) {
+ // By default, we want there to be enough precision when printing
+ // a double to a Message.
+ *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);
+ }
// Copy constructor.
Message(const Message& msg) : ss_(new internal::StrStream) { // NOLINT
diff --git a/gtest/include/gtest/gtest-param-test.h b/gtest/include/gtest/gtest-param-test.h
index 6c8622a..8100696 100644
--- a/gtest/include/gtest/gtest-param-test.h
+++ b/gtest/include/gtest/gtest-param-test.h
@@ -133,9 +133,12 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
// in the given test case, whether their definitions come before or
// AFTER the INSTANTIATE_TEST_CASE_P statement.
//
-// Please also note that generator expressions are evaluated in
-// RUN_ALL_TESTS(), after main() has started. This allows evaluation of
-// parameter list based on command line parameters.
+// Please also note that generator expressions (including parameters to the
+// generators) are evaluated in InitGoogleTest(), after main() has started.
+// This allows the user on one hand, to adjust generator parameters in order
+// to dynamically determine a set of tests to run and on the other hand,
+// give the user a chance to inspect the generated tests with Google Test
+// reflection API before RUN_ALL_TESTS() is executed.
//
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
// for more examples.
@@ -152,12 +155,15 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
#include <utility>
#endif
-#if GTEST_HAS_PARAM_TEST
-
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*. Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
#include <gtest/internal/gtest-internal.h>
#include <gtest/internal/gtest-param-util.h>
#include <gtest/internal/gtest-param-util-generated.h>
+#if GTEST_HAS_PARAM_TEST
+
namespace testing {
// Functions producing parameter generators.
diff --git a/gtest/include/gtest/gtest-param-test.h.pump b/gtest/include/gtest/gtest-param-test.h.pump
index c761f12..a231188 100644
--- a/gtest/include/gtest/gtest-param-test.h.pump
+++ b/gtest/include/gtest/gtest-param-test.h.pump
@@ -52,7 +52,7 @@ $var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
// class. It must be derived from testing::TestWithParam<T>, where T is
// the type of your parameter values. TestWithParam<T> is itself derived
// from testing::Test. T can be any copyable type. If it's a raw pointer,
-// you are responsible for managing the lifespan of the pointed values.
+// you are responsible for managing the lifespan of the pointed values.
class FooTest : public ::testing::TestWithParam<const char*> {
// You can implement all the usual class fixture members here.
@@ -60,7 +60,7 @@ class FooTest : public ::testing::TestWithParam<const char*> {
// Then, use the TEST_P macro to define as many parameterized tests
// for this fixture as you want. The _P suffix is for "parameterized"
-// or "pattern", whichever you prefer to think.
+// or "pattern", whichever you prefer to think.
TEST_P(FooTest, DoesBlah) {
// Inside a test, access the test parameter with the GetParam() method
@@ -124,7 +124,7 @@ const char* pets[] = {"cat", "dog"};
INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
// The tests from the instantiation above will have these names:
-//
+//
// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
@@ -147,17 +147,21 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
#endif // 0
-
-#include <utility>
-
#include <gtest/internal/gtest-port.h>
-#if GTEST_HAS_PARAM_TEST
+#if !GTEST_OS_SYMBIAN
+#include <utility>
+#endif
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*. Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
#include <gtest/internal/gtest-internal.h>
#include <gtest/internal/gtest-param-util.h>
#include <gtest/internal/gtest-param-util-generated.h>
+#if GTEST_HAS_PARAM_TEST
+
namespace testing {
// Functions producing parameter generators.
diff --git a/gtest/include/gtest/gtest-spi.h b/gtest/include/gtest/gtest-spi.h
index 2953411..c41da48 100644
--- a/gtest/include/gtest/gtest-spi.h
+++ b/gtest/include/gtest/gtest-spi.h
@@ -48,7 +48,7 @@ namespace testing {
// generated in the same thread that created this object or it can intercept
// all generated failures. The scope of this mock object can be controlled with
// the second argument to the two arguments constructor.
-class ScopedFakeTestPartResultReporter
+class GTEST_API_ ScopedFakeTestPartResultReporter
: public TestPartResultReporterInterface {
public:
// The two possible mocking modes of this object.
@@ -93,7 +93,7 @@ namespace internal {
// TestPartResultArray contains exactly one failure that has the given
// type and contains the given substring. If that's not the case, a
// non-fatal failure will be generated.
-class SingleFailureChecker {
+class GTEST_API_ SingleFailureChecker {
public:
// The constructor remembers the arguments.
SingleFailureChecker(const TestPartResultArray* results,
diff --git a/gtest/include/gtest/gtest-test-part.h b/gtest/include/gtest/gtest-test-part.h
index 58e7df9..f714759 100644
--- a/gtest/include/gtest/gtest-test-part.h
+++ b/gtest/include/gtest/gtest-test-part.h
@@ -34,6 +34,7 @@
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#include <iosfwd>
+#include <vector>
#include <gtest/internal/gtest-internal.h>
#include <gtest/internal/gtest-string.h>
@@ -43,7 +44,7 @@ namespace testing {
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
//
// Don't inherit from TestPartResult as its destructor is not virtual.
-class TestPartResult {
+class GTEST_API_ TestPartResult {
public:
// The possible outcomes of a test part (i.e. an assertion or an
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
@@ -56,15 +57,15 @@ class TestPartResult {
// C'tor. TestPartResult does NOT have a default constructor.
// Always use this constructor (with parameters) to create a
// TestPartResult object.
- TestPartResult(Type type,
- const char* file_name,
- int line_number,
- const char* message)
- : type_(type),
- file_name_(file_name),
- line_number_(line_number),
- summary_(ExtractSummary(message)),
- message_(message) {
+ TestPartResult(Type a_type,
+ const char* a_file_name,
+ int a_line_number,
+ const char* a_message)
+ : type_(a_type),
+ file_name_(a_file_name),
+ line_number_(a_line_number),
+ summary_(ExtractSummary(a_message)),
+ message_(a_message) {
}
// Gets the outcome of the test part.
@@ -117,15 +118,11 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
// An array of TestPartResult objects.
//
-// We define this class as we cannot use STL containers when compiling
-// Google Test with MSVC 7.1 and exceptions disabled.
-//
// Don't inherit from TestPartResultArray as its destructor is not
// virtual.
-class TestPartResultArray {
+class GTEST_API_ TestPartResultArray {
public:
- TestPartResultArray();
- ~TestPartResultArray();
+ TestPartResultArray() {}
// Appends the given TestPartResult to the array.
void Append(const TestPartResult& result);
@@ -135,9 +132,9 @@ class TestPartResultArray {
// Returns the number of TestPartResult objects in the array.
int size() const;
+
private:
- // Internally we use a Vector to implement the array.
- internal::Vector<TestPartResult>* const array_;
+ std::vector<TestPartResult> array_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
};
@@ -158,7 +155,8 @@ namespace internal {
// reported, it only delegates the reporting to the former result reporter.
// The original result reporter is restored in the destructor.
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
-class HasNewFatalFailureHelper : public TestPartResultReporterInterface {
+class GTEST_API_ HasNewFatalFailureHelper
+ : public TestPartResultReporterInterface {
public:
HasNewFatalFailureHelper();
virtual ~HasNewFatalFailureHelper();
diff --git a/gtest/include/gtest/gtest-typed-test.h b/gtest/include/gtest/gtest-typed-test.h
index 519edfe..1ec8eb8 100644
--- a/gtest/include/gtest/gtest-typed-test.h
+++ b/gtest/include/gtest/gtest-typed-test.h
@@ -159,8 +159,11 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
// given test case.
#define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
#define TYPED_TEST_CASE(CaseName, Types) \
- typedef ::testing::internal::TypeList<Types>::type \
+ typedef ::testing::internal::TypeList< Types >::type \
GTEST_TYPE_PARAMS_(CaseName)
#define TYPED_TEST(CaseName, TestName) \
@@ -241,11 +244,14 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
__FILE__, __LINE__, #__VA_ARGS__)
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
bool gtest_##Prefix##_##CaseName = \
::testing::internal::TypeParameterizedTestCase<CaseName, \
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
- ::testing::internal::TypeList<Types>::type>::Register(\
+ ::testing::internal::TypeList< Types >::type>::Register(\
#Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
#endif // GTEST_HAS_TYPED_TEST_P
diff --git a/gtest/include/gtest/gtest.h b/gtest/include/gtest/gtest.h
index 9be15fb..921fad1 100644
--- a/gtest/include/gtest/gtest.h
+++ b/gtest/include/gtest/gtest.h
@@ -52,6 +52,8 @@
#define GTEST_INCLUDE_GTEST_GTEST_H_
#include <limits>
+#include <vector>
+
#include <gtest/internal/gtest-internal.h>
#include <gtest/internal/gtest-string.h>
#include <gtest/gtest-death-test.h>
@@ -62,24 +64,19 @@
#include <gtest/gtest-typed-test.h>
// Depending on the platform, different string classes are available.
-// On Windows, ::std::string compiles only when exceptions are
-// enabled. On Linux, in addition to ::std::string, Google also makes
-// use of class ::string, which has the same interface as
-// ::std::string, but has a different implementation.
-//
-// The user can tell us whether ::std::string is available in his
-// environment by defining the macro GTEST_HAS_STD_STRING to either 1
-// or 0 on the compiler command line. He can also define
-// GTEST_HAS_GLOBAL_STRING to 1 to indicate that ::string is available
-// AND is a distinct type to ::std::string, or define it to 0 to
-// indicate otherwise.
+// On Linux, in addition to ::std::string, Google also makes use of
+// class ::string, which has the same interface as ::std::string, but
+// has a different implementation.
+//
+// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that
+// ::string is available AND is a distinct type to ::std::string, or
+// define it to 0 to indicate otherwise.
//
// If the user's ::std::string and ::string are the same class due to
-// aliasing, he should define GTEST_HAS_STD_STRING to 1 and
-// GTEST_HAS_GLOBAL_STRING to 0.
+// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0.
//
-// If the user doesn't define GTEST_HAS_STD_STRING and/or
-// GTEST_HAS_GLOBAL_STRING, they are defined heuristically.
+// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined
+// heuristically.
namespace testing {
@@ -177,64 +174,146 @@ String StreamableToString(const T& streamable) {
// A class for indicating whether an assertion was successful. When
// the assertion wasn't successful, the AssertionResult object
-// remembers a non-empty message that described how it failed.
-//
-// This class is useful for defining predicate-format functions to be
-// used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
+// remembers a non-empty message that describes how it failed.
//
-// The constructor of AssertionResult is private. To create an
-// instance of this class, use one of the factory functions
+// To create an instance of this class, use one of the factory functions
// (AssertionSuccess() and AssertionFailure()).
//
-// For example, in order to be able to write:
+// This class is useful for two purposes:
+// 1. Defining predicate functions to be used with Boolean test assertions
+// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts
+// 2. Defining predicate-format functions to be
+// used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
+//
+// For example, if you define IsEven predicate:
+//
+// testing::AssertionResult IsEven(int n) {
+// if ((n % 2) == 0)
+// return testing::AssertionSuccess();
+// else
+// return testing::AssertionFailure() << n << " is odd";
+// }
+//
+// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))
+// will print the message
+//
+// Value of: IsEven(Fib(5))
+// Actual: false (5 is odd)
+// Expected: true
+//
+// instead of a more opaque
+//
+// Value of: IsEven(Fib(5))
+// Actual: false
+// Expected: true
+//
+// in case IsEven is a simple Boolean predicate.
+//
+// If you expect your predicate to be reused and want to support informative
+// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up
+// about half as often as positive ones in our tests), supply messages for
+// both success and failure cases:
+//
+// testing::AssertionResult IsEven(int n) {
+// if ((n % 2) == 0)
+// return testing::AssertionSuccess() << n << " is even";
+// else
+// return testing::AssertionFailure() << n << " is odd";
+// }
+//
+// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print
+//
+// Value of: IsEven(Fib(6))
+// Actual: true (8 is even)
+// Expected: false
+//
+// NB: Predicates that support negative Boolean assertions have reduced
+// performance in positive ones so be careful not to use them in tests
+// that have lots (tens of thousands) of positive Boolean assertions.
+//
+// To use this class with EXPECT_PRED_FORMAT assertions such as:
//
// // Verifies that Foo() returns an even number.
// EXPECT_PRED_FORMAT1(IsEven, Foo());
//
-// you just need to define:
+// you need to define:
//
// testing::AssertionResult IsEven(const char* expr, int n) {
-// if ((n % 2) == 0) return testing::AssertionSuccess();
-//
-// Message msg;
-// msg << "Expected: " << expr << " is even\n"
-// << " Actual: it's " << n;
-// return testing::AssertionFailure(msg);
+// if ((n % 2) == 0)
+// return testing::AssertionSuccess();
+// else
+// return testing::AssertionFailure()
+// << "Expected: " << expr << " is even\n Actual: it's " << n;
// }
//
// If Foo() returns 5, you will see the following message:
//
// Expected: Foo() is even
// Actual: it's 5
-class AssertionResult {
+//
+class GTEST_API_ AssertionResult {
public:
- // Declares factory functions for making successful and failed
- // assertion results as friends.
- friend AssertionResult AssertionSuccess();
- friend AssertionResult AssertionFailure(const Message&);
+ // Copy constructor.
+ // Used in EXPECT_TRUE/FALSE(assertion_result).
+ AssertionResult(const AssertionResult& other);
+ // Used in the EXPECT_TRUE/FALSE(bool_expression).
+ explicit AssertionResult(bool success) : success_(success) {}
// Returns true iff the assertion succeeded.
- operator bool() const { return failure_message_.c_str() == NULL; } // NOLINT
+ operator bool() const { return success_; } // NOLINT
+
+ // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
+ AssertionResult operator!() const;
+
+ // Returns the text streamed into this AssertionResult. Test assertions
+ // use it when they fail (i.e., the predicate's outcome doesn't match the
+ // assertion's expectation). When nothing has been streamed into the
+ // object, returns an empty string.
+ const char* message() const {
+ return message_.get() != NULL && message_->c_str() != NULL ?
+ message_->c_str() : "";
+ }
+ // TODO(vladl@google.com): Remove this after making sure no clients use it.
+ // Deprecated; please use message() instead.
+ const char* failure_message() const { return message(); }
- // Returns the assertion's failure message.
- const char* failure_message() const { return failure_message_.c_str(); }
+ // Streams a custom failure message into this object.
+ template <typename T> AssertionResult& operator<<(const T& value);
private:
- // The default constructor. It is used when the assertion succeeded.
- AssertionResult() {}
-
- // The constructor used when the assertion failed.
- explicit AssertionResult(const internal::String& failure_message);
-
- // Stores the assertion's failure message.
- internal::String failure_message_;
-};
+ // No implementation - we want AssertionResult to be
+ // copy-constructible but not assignable.
+ void operator=(const AssertionResult& other);
+
+ // Stores result of the assertion predicate.
+ bool success_;
+ // Stores the message describing the condition in case the expectation
+ // construct is not satisfied with the predicate's outcome.
+ // Referenced via a pointer to avoid taking too much stack frame space
+ // with test assertions.
+ internal::scoped_ptr<internal::String> message_;
+}; // class AssertionResult
+
+// Streams a custom failure message into this object.
+template <typename T>
+AssertionResult& AssertionResult::operator<<(const T& value) {
+ Message msg;
+ if (message_.get() != NULL)
+ msg << *message_;
+ msg << value;
+ message_.reset(new internal::String(msg.GetString()));
+ return *this;
+}
// Makes a successful assertion result.
-AssertionResult AssertionSuccess();
+GTEST_API_ AssertionResult AssertionSuccess();
+
+// Makes a failed assertion result.
+GTEST_API_ AssertionResult AssertionFailure();
// Makes a failed assertion result with the given failure message.
-AssertionResult AssertionFailure(const Message& msg);
+// Deprecated; use AssertionFailure() << msg.
+GTEST_API_ AssertionResult AssertionFailure(const Message& msg);
// The abstract class that all tests inherit from.
//
@@ -259,7 +338,7 @@ AssertionResult AssertionFailure(const Message& msg);
// TEST_F(FooTest, Baz) { ... }
//
// Test is not copyable.
-class Test {
+class GTEST_API_ Test {
public:
friend class internal::TestInfoImpl;
@@ -375,8 +454,8 @@ class TestProperty {
// C'tor. TestProperty does NOT have a default constructor.
// Always use this constructor (with parameters) to create a
// TestProperty object.
- TestProperty(const char* key, const char* value) :
- key_(key), value_(value) {
+ TestProperty(const char* a_key, const char* a_value) :
+ key_(a_key), value_(a_value) {
}
// Gets the user supplied key.
@@ -407,7 +486,7 @@ class TestProperty {
// the Test.
//
// TestResult is not copyable.
-class TestResult {
+class GTEST_API_ TestResult {
public:
// Creates an empty TestResult.
TestResult();
@@ -458,13 +537,13 @@ class TestResult {
friend class internal::WindowsDeathTest;
// Gets the vector of TestPartResults.
- const internal::Vector<TestPartResult>& test_part_results() const {
- return *test_part_results_;
+ const std::vector<TestPartResult>& test_part_results() const {
+ return test_part_results_;
}
// Gets the vector of TestProperties.
- const internal::Vector<TestProperty>& test_properties() const {
- return *test_properties_;
+ const std::vector<TestProperty>& test_properties() const {
+ return test_properties_;
}
// Sets the elapsed time.
@@ -502,9 +581,9 @@ class TestResult {
internal::Mutex test_properites_mutex_;
// The vector of TestPartResults
- internal::scoped_ptr<internal::Vector<TestPartResult> > test_part_results_;
+ std::vector<TestPartResult> test_part_results_;
// The vector of TestProperties
- internal::scoped_ptr<internal::Vector<TestProperty> > test_properties_;
+ std::vector<TestProperty> test_properties_;
// Running count of death tests.
int death_test_count_;
// The elapsed time, in milliseconds.
@@ -525,7 +604,7 @@ class TestResult {
// The constructor of TestInfo registers itself with the UnitTest
// singleton such that the RUN_ALL_TESTS() macro knows which tests to
// run.
-class TestInfo {
+class GTEST_API_ TestInfo {
public:
// Destructs a TestInfo object. This function is not virtual, so
// don't inherit from TestInfo.
@@ -607,7 +686,7 @@ class TestInfo {
// A test case, which consists of a vector of TestInfos.
//
// TestCase is not copyable.
-class TestCase {
+class GTEST_API_ TestCase {
public:
// Creates a TestCase with the given name.
//
@@ -668,11 +747,11 @@ class TestCase {
friend class internal::UnitTestImpl;
// Gets the (mutable) vector of TestInfos in this TestCase.
- internal::Vector<TestInfo*>& test_info_list() { return *test_info_list_; }
+ std::vector<TestInfo*>& test_info_list() { return test_info_list_; }
// Gets the (immutable) vector of TestInfos in this TestCase.
- const internal::Vector<TestInfo *> & test_info_list() const {
- return *test_info_list_;
+ const std::vector<TestInfo*>& test_info_list() const {
+ return test_info_list_;
}
// Returns the i-th test among all the tests. i can range from 0 to
@@ -721,11 +800,11 @@ class TestCase {
internal::String comment_;
// The vector of TestInfos in their original order. It owns the
// elements in the vector.
- const internal::scoped_ptr<internal::Vector<TestInfo*> > test_info_list_;
+ std::vector<TestInfo*> test_info_list_;
// Provides a level of indirection for the test list to allow easy
// shuffling and restoring the test order. The i-th element in this
// vector is the index of the i-th test in the shuffled test list.
- const internal::scoped_ptr<internal::Vector<int> > test_indices_;
+ std::vector<int> test_indices_;
// Pointer to the function that sets up the test case.
Test::SetUpTestCaseFunc set_up_tc_;
// Pointer to the function that tears down the test case.
@@ -845,7 +924,7 @@ class EmptyTestEventListener : public TestEventListener {
};
// TestEventListeners lets users add listeners to track events in Google Test.
-class TestEventListeners {
+class GTEST_API_ TestEventListeners {
public:
TestEventListeners();
~TestEventListeners();
@@ -932,7 +1011,7 @@ class TestEventListeners {
//
// This class is thread-safe as long as the methods are called
// according to their specification.
-class UnitTest {
+class GTEST_API_ UnitTest {
public:
// Gets the singleton UnitTest object. The first time this method
// is called, a UnitTest object is constructed and returned.
@@ -1119,36 +1198,34 @@ inline Environment* AddGlobalTestEnvironment(Environment* env) {
// updated.
//
// Calling the function for the second time has no user-visible effect.
-void InitGoogleTest(int* argc, char** argv);
+GTEST_API_ void InitGoogleTest(int* argc, char** argv);
// This overloaded version can be used in Windows programs compiled in
// UNICODE mode.
-void InitGoogleTest(int* argc, wchar_t** argv);
+GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);
namespace internal {
// These overloaded versions handle ::std::string and ::std::wstring.
-#if GTEST_HAS_STD_STRING
-inline String FormatForFailureMessage(const ::std::string& str) {
+GTEST_API_ inline String FormatForFailureMessage(const ::std::string& str) {
return (Message() << '"' << str << '"').GetString();
}
-#endif // GTEST_HAS_STD_STRING
#if GTEST_HAS_STD_WSTRING
-inline String FormatForFailureMessage(const ::std::wstring& wstr) {
+GTEST_API_ inline String FormatForFailureMessage(const ::std::wstring& wstr) {
return (Message() << "L\"" << wstr << '"').GetString();
}
#endif // GTEST_HAS_STD_WSTRING
// These overloaded versions handle ::string and ::wstring.
#if GTEST_HAS_GLOBAL_STRING
-inline String FormatForFailureMessage(const ::string& str) {
+GTEST_API_ inline String FormatForFailureMessage(const ::string& str) {
return (Message() << '"' << str << '"').GetString();
}
#endif // GTEST_HAS_GLOBAL_STRING
#if GTEST_HAS_GLOBAL_WSTRING
-inline String FormatForFailureMessage(const ::wstring& wstr) {
+GTEST_API_ inline String FormatForFailureMessage(const ::wstring& wstr) {
return (Message() << "L\"" << wstr << '"').GetString();
}
#endif // GTEST_HAS_GLOBAL_WSTRING
@@ -1201,10 +1278,10 @@ AssertionResult CmpHelperEQ(const char* expected_expression,
// With this overloaded version, we allow anonymous enums to be used
// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums
// can be implicitly cast to BiggestInt.
-AssertionResult CmpHelperEQ(const char* expected_expression,
- const char* actual_expression,
- BiggestInt expected,
- BiggestInt actual);
+GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression,
+ const char* actual_expression,
+ BiggestInt expected,
+ BiggestInt actual);
// The helper class for {ASSERT|EXPECT}_EQ. The template argument
// lhs_is_null_literal is true iff the first argument to ASSERT_EQ()
@@ -1293,72 +1370,72 @@ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
return AssertionFailure(msg);\
}\
}\
-AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
- BiggestInt val1, BiggestInt val2);
+GTEST_API_ AssertionResult CmpHelper##op_name(\
+ const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2)
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
// Implements the helper function for {ASSERT|EXPECT}_NE
-GTEST_IMPL_CMP_HELPER_(NE, !=)
+GTEST_IMPL_CMP_HELPER_(NE, !=);
// Implements the helper function for {ASSERT|EXPECT}_LE
-GTEST_IMPL_CMP_HELPER_(LE, <=)
+GTEST_IMPL_CMP_HELPER_(LE, <=);
// Implements the helper function for {ASSERT|EXPECT}_LT
-GTEST_IMPL_CMP_HELPER_(LT, < )
+GTEST_IMPL_CMP_HELPER_(LT, < );
// Implements the helper function for {ASSERT|EXPECT}_GE
-GTEST_IMPL_CMP_HELPER_(GE, >=)
+GTEST_IMPL_CMP_HELPER_(GE, >=);
// Implements the helper function for {ASSERT|EXPECT}_GT
-GTEST_IMPL_CMP_HELPER_(GT, > )
+GTEST_IMPL_CMP_HELPER_(GT, > );
#undef GTEST_IMPL_CMP_HELPER_
// The helper function for {ASSERT|EXPECT}_STREQ.
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
-AssertionResult CmpHelperSTREQ(const char* expected_expression,
- const char* actual_expression,
- const char* expected,
- const char* actual);
+GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression,
+ const char* actual_expression,
+ const char* expected,
+ const char* actual);
// The helper function for {ASSERT|EXPECT}_STRCASEEQ.
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
-AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,
- const char* actual_expression,
- const char* expected,
- const char* actual);
+GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,
+ const char* actual_expression,
+ const char* expected,
+ const char* actual);
// The helper function for {ASSERT|EXPECT}_STRNE.
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
-AssertionResult CmpHelperSTRNE(const char* s1_expression,
- const char* s2_expression,
- const char* s1,
- const char* s2);
+GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
+ const char* s2_expression,
+ const char* s1,
+ const char* s2);
// The helper function for {ASSERT|EXPECT}_STRCASENE.
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
-AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
- const char* s2_expression,
- const char* s1,
- const char* s2);
+GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
+ const char* s2_expression,
+ const char* s1,
+ const char* s2);
// Helper function for *_STREQ on wide strings.
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
-AssertionResult CmpHelperSTREQ(const char* expected_expression,
- const char* actual_expression,
- const wchar_t* expected,
- const wchar_t* actual);
+GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression,
+ const char* actual_expression,
+ const wchar_t* expected,
+ const wchar_t* actual);
// Helper function for *_STRNE on wide strings.
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
-AssertionResult CmpHelperSTRNE(const char* s1_expression,
- const char* s2_expression,
- const wchar_t* s1,
- const wchar_t* s2);
+GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
+ const char* s2_expression,
+ const wchar_t* s1,
+ const wchar_t* s2);
} // namespace internal
@@ -1370,32 +1447,30 @@ AssertionResult CmpHelperSTRNE(const char* s1_expression,
//
// The {needle,haystack}_expr arguments are the stringified
// expressions that generated the two real arguments.
-AssertionResult IsSubstring(
+GTEST_API_ AssertionResult IsSubstring(
const char* needle_expr, const char* haystack_expr,
const char* needle, const char* haystack);
-AssertionResult IsSubstring(
+GTEST_API_ AssertionResult IsSubstring(
const char* needle_expr, const char* haystack_expr,
const wchar_t* needle, const wchar_t* haystack);
-AssertionResult IsNotSubstring(
+GTEST_API_ AssertionResult IsNotSubstring(
const char* needle_expr, const char* haystack_expr,
const char* needle, const char* haystack);
-AssertionResult IsNotSubstring(
+GTEST_API_ AssertionResult IsNotSubstring(
const char* needle_expr, const char* haystack_expr,
const wchar_t* needle, const wchar_t* haystack);
-#if GTEST_HAS_STD_STRING
-AssertionResult IsSubstring(
+GTEST_API_ AssertionResult IsSubstring(
const char* needle_expr, const char* haystack_expr,
const ::std::string& needle, const ::std::string& haystack);
-AssertionResult IsNotSubstring(
+GTEST_API_ AssertionResult IsNotSubstring(
const char* needle_expr, const char* haystack_expr,
const ::std::string& needle, const ::std::string& haystack);
-#endif // GTEST_HAS_STD_STRING
#if GTEST_HAS_STD_WSTRING
-AssertionResult IsSubstring(
+GTEST_API_ AssertionResult IsSubstring(
const char* needle_expr, const char* haystack_expr,
const ::std::wstring& needle, const ::std::wstring& haystack);
-AssertionResult IsNotSubstring(
+GTEST_API_ AssertionResult IsNotSubstring(
const char* needle_expr, const char* haystack_expr,
const ::std::wstring& needle, const ::std::wstring& haystack);
#endif // GTEST_HAS_STD_WSTRING
@@ -1438,16 +1513,16 @@ AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression,
// Helper function for implementing ASSERT_NEAR.
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
-AssertionResult DoubleNearPredFormat(const char* expr1,
- const char* expr2,
- const char* abs_error_expr,
- double val1,
- double val2,
- double abs_error);
+GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
+ const char* expr2,
+ const char* abs_error_expr,
+ double val1,
+ double val2,
+ double abs_error);
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// A class that enables one to stream messages to assertion macros
-class AssertHelper {
+class GTEST_API_ AssertHelper {
public:
// Constructor.
AssertHelper(TestPartResult::Type type,
@@ -1576,10 +1651,22 @@ const T* TestWithParam<T>::parameter_ = NULL;
#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed")
// Generates a fatal failure with a generic message.
-#define FAIL() GTEST_FATAL_FAILURE_("Failed")
+#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed")
+
+// Define this macro to 1 to omit the definition of FAIL(), which is a
+// generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_FAIL
+#define FAIL() GTEST_FAIL()
+#endif
// Generates a success with a generic message.
-#define SUCCEED() GTEST_SUCCESS_("Succeeded")
+#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded")
+
+// Define this macro to 1 to omit the definition of SUCCEED(), which
+// is a generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_SUCCEED
+#define SUCCEED() GTEST_SUCCEED()
+#endif
// Macros for testing exceptions.
//
@@ -1603,7 +1690,9 @@ const T* TestWithParam<T>::parameter_ = NULL;
#define ASSERT_ANY_THROW(statement) \
GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)
-// Boolean assertions.
+// Boolean assertions. Condition can be either a Boolean expression or an
+// AssertionResult. For more information on how to use AssertionResult with
+// these macros see comments on that class.
#define EXPECT_TRUE(condition) \
GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
GTEST_NONFATAL_FAILURE_)
@@ -1776,10 +1865,10 @@ const T* TestWithParam<T>::parameter_ = NULL;
// Asserts that val1 is less than, or almost equal to, val2. Fails
// otherwise. In particular, it fails if either val1 or val2 is NaN.
-AssertionResult FloatLE(const char* expr1, const char* expr2,
- float val1, float val2);
-AssertionResult DoubleLE(const char* expr1, const char* expr2,
- double val1, double val2);
+GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2,
+ float val1, float val2);
+GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
+ double val1, double val2);
#if GTEST_OS_WINDOWS
@@ -1909,10 +1998,15 @@ bool StaticAssertTypeEq() {
// code. GetTestTypeId() is guaranteed to always return the same
// value, as it always calls GetTypeId<>() from the Google Test
// framework.
-#define TEST(test_case_name, test_name)\
+#define GTEST_TEST(test_case_name, test_name)\
GTEST_TEST_(test_case_name, test_name, \
::testing::Test, ::testing::internal::GetTestTypeId())
+// Define this macro to 1 to omit the definition of TEST(), which
+// is a generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_TEST
+#define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)
+#endif
// Defines a test that uses a test fixture.
//
diff --git a/gtest/include/gtest/internal/gtest-death-test-internal.h b/gtest/include/gtest/internal/gtest-death-test-internal.h
index 5aba1a0..e433084 100644
--- a/gtest/include/gtest/internal/gtest-death-test-internal.h
+++ b/gtest/include/gtest/internal/gtest-death-test-internal.h
@@ -64,7 +64,7 @@ const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
// by wait(2)
// exit code: The integer code passed to exit(3), _exit(2), or
// returned from main()
-class DeathTest {
+class GTEST_API_ DeathTest {
public:
// Create returns false if there was an error determining the
// appropriate action to take for the current death test; for example,
@@ -147,7 +147,7 @@ class DefaultDeathTestFactory : public DeathTestFactory {
// Returns true if exit_status describes a process that was terminated
// by a signal, or exited normally with a nonzero exit code.
-bool ExitedUnsuccessfully(int exit_status);
+GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
// ASSERT_EXIT*, and EXPECT_EXIT*.
@@ -189,11 +189,12 @@ bool ExitedUnsuccessfully(int exit_status);
// RUN_ALL_TESTS was called.
class InternalRunDeathTestFlag {
public:
- InternalRunDeathTestFlag(const String& file,
- int line,
- int index,
- int write_fd)
- : file_(file), line_(line), index_(index), write_fd_(write_fd) {}
+ InternalRunDeathTestFlag(const String& a_file,
+ int a_line,
+ int an_index,
+ int a_write_fd)
+ : file_(a_file), line_(a_line), index_(an_index),
+ write_fd_(a_write_fd) {}
~InternalRunDeathTestFlag() {
if (write_fd_ >= 0)
diff --git a/gtest/include/gtest/internal/gtest-filepath.h b/gtest/include/gtest/internal/gtest-filepath.h
index 1b2f586..4b76d79 100644
--- a/gtest/include/gtest/internal/gtest-filepath.h
+++ b/gtest/include/gtest/internal/gtest-filepath.h
@@ -56,7 +56,7 @@ namespace internal {
// Names are NOT checked for syntax correctness -- no checking for illegal
// characters, malformed paths, etc.
-class FilePath {
+class GTEST_API_ FilePath {
public:
FilePath() : pathname_("") { }
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
@@ -189,9 +189,18 @@ class FilePath {
// particular, RemoveTrailingPathSeparator() only removes one separator, and
// it is called in CreateDirectoriesRecursively() assuming that it will change
// a pathname from directory syntax (trailing separator) to filename syntax.
+ //
+ // On Windows this method also replaces the alternate path separator '/' with
+ // the primary path separator '\\', so that for example "bar\\/\\foo" becomes
+ // "bar\\foo".
void Normalize();
+ // Returns a pointer to the last occurence of a valid path separator in
+ // the FilePath. On Windows, for example, both '/' and '\' are valid path
+ // separators. Returns NULL if no path separator was found.
+ const char* FindLastPathSeparator() const;
+
String pathname_;
}; // class FilePath
diff --git a/gtest/include/gtest/internal/gtest-internal.h b/gtest/include/gtest/internal/gtest-internal.h
index 7033b0c..31a66e9 100644
--- a/gtest/include/gtest/internal/gtest-internal.h
+++ b/gtest/include/gtest/internal/gtest-internal.h
@@ -114,14 +114,13 @@ struct TraceInfo; // Information about a trace point.
class ScopedTrace; // Implements scoped trace.
class TestInfoImpl; // Opaque implementation of TestInfo
class UnitTestImpl; // Opaque implementation of UnitTest
-template <typename E> class Vector; // A generic vector.
// How many times InitGoogleTest() has been called.
extern int g_init_gtest_count;
// The text used in failure messages to indicate the start of the
// stack trace.
-extern const char kStackTraceMarker[];
+GTEST_API_ extern const char kStackTraceMarker[];
// A secret type that Google Test users don't know about. It has no
// definition on purpose. Therefore it's impossible to create a
@@ -148,24 +147,21 @@ char (&IsNullLiteralHelper(...))[2]; // NOLINT
// A compile-time bool constant that is true if and only if x is a
// null pointer literal (i.e. NULL or any 0-valued compile-time
// integral constant).
-#ifdef GTEST_ELLIPSIS_NEEDS_COPY_
-// Passing non-POD classes through ellipsis (...) crashes the ARM
-// compiler. The Nokia Symbian and the IBM XL C/C++ compiler try to
-// instantiate a copy constructor for objects passed through ellipsis
-// (...), failing for uncopyable objects. Hence we define this to
-// false (and lose support for NULL detection).
+#ifdef GTEST_ELLIPSIS_NEEDS_POD_
+// We lose support for NULL detection where the compiler doesn't like
+// passing non-POD classes through ellipsis (...).
#define GTEST_IS_NULL_LITERAL_(x) false
#else
#define GTEST_IS_NULL_LITERAL_(x) \
(sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1)
-#endif // GTEST_ELLIPSIS_NEEDS_COPY_
+#endif // GTEST_ELLIPSIS_NEEDS_POD_
// Appends the user-supplied message to the Google-Test-generated message.
-String AppendUserMessage(const String& gtest_msg,
- const Message& user_msg);
+GTEST_API_ String AppendUserMessage(const String& gtest_msg,
+ const Message& user_msg);
// A helper class for creating scoped traces in user programs.
-class ScopedTrace {
+class GTEST_API_ ScopedTrace {
public:
// The c'tor pushes the given source file location and message onto
// a trace stack maintained by Google Test.
@@ -244,8 +240,8 @@ inline String FormatForFailureMessage(T* pointer) {
#endif // GTEST_NEEDS_IS_POINTER_
// These overloaded versions handle narrow and wide characters.
-String FormatForFailureMessage(char ch);
-String FormatForFailureMessage(wchar_t wchar);
+GTEST_API_ String FormatForFailureMessage(char ch);
+GTEST_API_ String FormatForFailureMessage(wchar_t wchar);
// When this operand is a const char* or char*, and the other operand
// is a ::std::string or ::string, we print this operand as a C string
@@ -262,9 +258,7 @@ inline String FormatForComparisonFailureMessage(\
return operand1_printer(str);\
}
-#if GTEST_HAS_STD_STRING
GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted)
-#endif // GTEST_HAS_STD_STRING
#if GTEST_HAS_STD_WSTRING
GTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted)
#endif // GTEST_HAS_STD_WSTRING
@@ -293,12 +287,18 @@ GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted)
// The ignoring_case parameter is true iff the assertion is a
// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will
// be inserted into the message.
-AssertionResult EqFailure(const char* expected_expression,
- const char* actual_expression,
- const String& expected_value,
- const String& actual_value,
- bool ignoring_case);
-
+GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
+ const char* actual_expression,
+ const String& expected_value,
+ const String& actual_value,
+ bool ignoring_case);
+
+// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
+GTEST_API_ String GetBoolAssertionFailureMessage(
+ const AssertionResult& assertion_result,
+ const char* expression_text,
+ const char* actual_predicate_value,
+ const char* expected_predicate_value);
// This template class represents an IEEE floating-point number
// (either single-precision or double-precision, depending on the
@@ -518,7 +518,7 @@ TypeId GetTypeId() {
// ::testing::Test, as the latter may give the wrong result due to a
// suspected linker bug when compiling Google Test as a Mac OS X
// framework.
-TypeId GetTestTypeId();
+GTEST_API_ TypeId GetTestTypeId();
// Defines the abstract factory interface that creates instances
// of a Test object.
@@ -551,8 +551,10 @@ class TestFactoryImpl : public TestFactoryBase {
// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}
// We pass a long instead of HRESULT to avoid causing an
// include dependency for the HRESULT type.
-AssertionResult IsHRESULTSuccess(const char* expr, long hr); // NOLINT
-AssertionResult IsHRESULTFailure(const char* expr, long hr); // NOLINT
+GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr,
+ long hr); // NOLINT
+GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,
+ long hr); // NOLINT
#endif // GTEST_OS_WINDOWS
@@ -591,7 +593,7 @@ typedef void (*TearDownTestCaseFunc)();
// factory: pointer to the factory that creates a test object.
// The newly created TestInfo instance will assume
// ownership of the factory object.
-TestInfo* MakeAndRegisterTestInfo(
+GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
const char* test_case_name, const char* name,
const char* test_case_comment, const char* comment,
TypeId fixture_class_id,
@@ -599,10 +601,15 @@ TestInfo* MakeAndRegisterTestInfo(
TearDownTestCaseFunc tear_down_tc,
TestFactoryBase* factory);
+// If *pstr starts with the given prefix, modifies *pstr to be right
+// past the prefix and returns true; otherwise leaves *pstr unchanged
+// and returns false. None of pstr, *pstr, and prefix can be NULL.
+bool SkipPrefix(const char* prefix, const char** pstr);
+
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
// State of the definition of a type-parameterized test case.
-class TypedTestCasePState {
+class GTEST_API_ TypedTestCasePState {
public:
TypedTestCasePState() : registered_(false) {}
@@ -743,13 +750,14 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> {
// For example, if Foo() calls Bar(), which in turn calls
// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
-String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count);
+GTEST_API_ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test,
+ int skip_count);
// Helpers for suppressing warnings on unreachable code or constant
// condition.
// Always returns true.
-bool AlwaysTrue();
+GTEST_API_ bool AlwaysTrue();
// Always returns false.
inline bool AlwaysFalse() { return !AlwaysTrue(); }
@@ -759,7 +767,7 @@ inline bool AlwaysFalse() { return !AlwaysTrue(); }
// doesn't use global state (and therefore can't interfere with user
// code). Unlike rand_r(), it's portable. An LCG isn't very random,
// but it's good enough for our purposes.
-class Random {
+class GTEST_API_ Random {
public:
static const UInt32 kMaxRange = 1u << 31;
@@ -858,12 +866,17 @@ class Random {
fail(gtest_msg)
-#define GTEST_TEST_BOOLEAN_(boolexpr, booltext, actual, expected, fail) \
+// Implements Boolean test assertions such as EXPECT_TRUE. expression can be
+// either a boolean expression or an AssertionResult. text is a textual
+// represenation of expression as it was passed into the EXPECT_TRUE.
+#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
- if (::testing::internal::IsTrue(boolexpr)) \
+ if (const ::testing::AssertionResult gtest_ar_ = \
+ ::testing::AssertionResult(expression)) \
; \
else \
- fail("Value of: " booltext "\n Actual: " #actual "\nExpected: " #expected)
+ fail(::testing::internal::GetBoolAssertionFailureMessage(\
+ gtest_ar_, text, #actual, #expected).c_str())
#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
diff --git a/gtest/include/gtest/internal/gtest-linked_ptr.h b/gtest/include/gtest/internal/gtest-linked_ptr.h
index f98af0b..540ef4c 100644
--- a/gtest/include/gtest/internal/gtest-linked_ptr.h
+++ b/gtest/include/gtest/internal/gtest-linked_ptr.h
@@ -77,7 +77,7 @@ namespace testing {
namespace internal {
// Protects copying of all linked_ptr objects.
-extern Mutex g_linked_ptr_mutex;
+GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
// This is used internally by all instances of linked_ptr<>. It needs to be
// a non-template class because different types of linked_ptr<> can refer to
diff --git a/gtest/include/gtest/internal/gtest-param-util-generated.h b/gtest/include/gtest/internal/gtest-param-util-generated.h
index 1358c32..ab4ab56 100644
--- a/gtest/include/gtest/internal/gtest-param-util-generated.h
+++ b/gtest/include/gtest/internal/gtest-param-util-generated.h
@@ -44,13 +44,30 @@
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*. Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+#include <gtest/internal/gtest-param-util.h>
#include <gtest/internal/gtest-port.h>
#if GTEST_HAS_PARAM_TEST
-#include <gtest/internal/gtest-param-util.h>
-
namespace testing {
+
+// Forward declarations of ValuesIn(), which is implemented in
+// include/gtest/gtest-param-test.h.
+template <typename ForwardIterator>
+internal::ParamGenerator<
+ typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
+ ForwardIterator begin, ForwardIterator end);
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+ const Container& container);
+
namespace internal {
// Used in the Values() function to provide polymorphic capabilities.
diff --git a/gtest/include/gtest/internal/gtest-param-util-generated.h.pump b/gtest/include/gtest/internal/gtest-param-util-generated.h.pump
index 2da2872..baedfbc 100644
--- a/gtest/include/gtest/internal/gtest-param-util-generated.h.pump
+++ b/gtest/include/gtest/internal/gtest-param-util-generated.h.pump
@@ -45,13 +45,30 @@ $var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*. Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+#include <gtest/internal/gtest-param-util.h>
#include <gtest/internal/gtest-port.h>
#if GTEST_HAS_PARAM_TEST
-#include <gtest/internal/gtest-param-util.h>
-
namespace testing {
+
+// Forward declarations of ValuesIn(), which is implemented in
+// include/gtest/gtest-param-test.h.
+template <typename ForwardIterator>
+internal::ParamGenerator<
+ typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
+ ForwardIterator begin, ForwardIterator end);
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+ const Container& container);
+
namespace internal {
// Used in the Values() function to provide polymorphic capabilities.
diff --git a/gtest/include/gtest/internal/gtest-param-util.h b/gtest/include/gtest/internal/gtest-param-util.h
index dcc5494..0cbb58c 100644
--- a/gtest/include/gtest/internal/gtest-param-util.h
+++ b/gtest/include/gtest/internal/gtest-param-util.h
@@ -38,17 +38,15 @@
#include <utility>
#include <vector>
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*. Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+#include <gtest/internal/gtest-internal.h>
+#include <gtest/internal/gtest-linked_ptr.h>
#include <gtest/internal/gtest-port.h>
#if GTEST_HAS_PARAM_TEST
-#if GTEST_HAS_RTTI
-#include <typeinfo>
-#endif // GTEST_HAS_RTTI
-
-#include <gtest/internal/gtest-linked_ptr.h>
-#include <gtest/internal/gtest-internal.h>
-
namespace testing {
namespace internal {
@@ -58,26 +56,8 @@ namespace internal {
// fixture class for the same test case. This may happen when
// TEST_P macro is used to define two tests with the same name
// but in different namespaces.
-void ReportInvalidTestCaseType(const char* test_case_name,
- const char* file, int line);
-
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
-//
-// Downcasts the pointer of type Base to Derived.
-// Derived must be a subclass of Base. The parameter MUST
-// point to a class of type Derived, not any subclass of it.
-// When RTTI is available, the function performs a runtime
-// check to enforce this.
-template <class Derived, class Base>
-Derived* CheckedDowncastToActualType(Base* base) {
-#if GTEST_HAS_RTTI
- GTEST_CHECK_(typeid(*base) == typeid(Derived));
- Derived* derived = dynamic_cast<Derived*>(base); // NOLINT
-#else
- Derived* derived = static_cast<Derived*>(base); // Poor man's downcast.
-#endif // GTEST_HAS_RTTI
- return derived;
-}
+GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
+ const char* file, int line);
template <typename> class ParamGeneratorInterface;
template <typename> class ParamGenerator;
@@ -169,7 +149,7 @@ class ParamGeneratorInterface {
virtual ParamIteratorInterface<T>* End() const = 0;
};
-// Wraps ParamGeneratorInetrface<T> and provides general generator syntax
+// Wraps ParamGeneratorInterface<T> and provides general generator syntax
// compatible with the STL Container concept.
// This class implements copy initialization semantics and the contained
// ParamGeneratorInterface<T> instance is shared among all copies
@@ -245,7 +225,8 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
private:
Iterator(const Iterator& other)
- : base_(other.base_), value_(other.value_), index_(other.index_),
+ : ParamIteratorInterface<T>(),
+ base_(other.base_), value_(other.value_), index_(other.index_),
step_(other.step_) {}
// No implementation - assignment is unsupported.
@@ -542,12 +523,12 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
// LocalTestInfo structure keeps information about a single test registered
// with TEST_P macro.
struct TestInfo {
- TestInfo(const char* test_case_base_name,
- const char* test_base_name,
- TestMetaFactoryBase<ParamType>* test_meta_factory) :
- test_case_base_name(test_case_base_name),
- test_base_name(test_base_name),
- test_meta_factory(test_meta_factory) {}
+ TestInfo(const char* a_test_case_base_name,
+ const char* a_test_base_name,
+ TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
+ test_case_base_name(a_test_case_base_name),
+ test_base_name(a_test_base_name),
+ test_meta_factory(a_test_meta_factory) {}
const String test_case_base_name;
const String test_base_name;
diff --git a/gtest/include/gtest/internal/gtest-port.h b/gtest/include/gtest/internal/gtest-port.h
index ee97881..a2a62be 100644
--- a/gtest/include/gtest/internal/gtest-port.h
+++ b/gtest/include/gtest/internal/gtest-port.h
@@ -42,6 +42,8 @@
//
// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2)
// is/isn't available.
+// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions
+// are enabled.
// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string
// is/isn't available (some systems define
// ::string, which is different to std::string).
@@ -52,9 +54,6 @@
// is/isn't available.
// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't
// enabled.
-// GTEST_HAS_STD_STRING - Define it to 1/0 to indicate that
-// std::string does/doesn't work (Google Test can
-// be used where std::string is unavailable).
// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that
// std::wstring does/doesn't work (Google Test can
// be used where std::wstring is unavailable).
@@ -67,11 +66,19 @@
// Test's own tr1 tuple implementation should be
// used. Unused when the user sets
// GTEST_HAS_TR1_TUPLE to 0.
+// GTEST_LINKED_AS_SHARED_LIBRARY
+// - Define to 1 when compiling tests that use
+// Google Test as a shared library (known as
+// DLL on Windows).
+// GTEST_CREATE_SHARED_LIBRARY
+// - Define to 1 when compiling Google Test itself
+// as a shared library.
// This header defines the following utilities:
//
// Macros indicating the current platform (defined to 1 if compiled on
// the given platform; otherwise undefined):
+// GTEST_OS_AIX - IBM AIX
// GTEST_OS_CYGWIN - Cygwin
// GTEST_OS_LINUX - Linux
// GTEST_OS_MAC - Mac OS X
@@ -80,7 +87,7 @@
// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile)
// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop
// GTEST_OS_WINDOWS_MINGW - MinGW
-// GTEST_OS_WINODWS_MOBILE - Windows Mobile
+// GTEST_OS_WINDOWS_MOBILE - Windows Mobile
// GTEST_OS_ZOS - z/OS
//
// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the
@@ -103,11 +110,13 @@
// GTEST_USES_POSIX_RE - enhanced POSIX regex is used.
// GTEST_USES_SIMPLE_RE - our own simple regex is used;
// the above two are mutually exclusive.
+// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().
//
// Macros for basic C++ coding:
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a
// variable don't have to be used.
+// GTEST_DISALLOW_ASSIGN_ - disables operator=.
// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=.
// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used.
//
@@ -134,7 +143,10 @@
// LogToStderr() - directs all log messages to stderr.
// FlushInfoLog() - flushes informational log messages.
//
-// Stderr capturing:
+// Stdout and stderr capturing:
+// CaptureStdout() - starts capturing stdout.
+// GetCapturedStdout() - stops capturing stdout and returns the captured
+// string.
// CaptureStderr() - starts capturing stderr.
// GetCapturedStderr() - stops capturing stderr and returns the captured
// string.
@@ -166,9 +178,12 @@
#endif // !_WIN32_WCE
#include <iostream> // NOLINT
+#include <sstream> // NOLINT
+#include <string> // NOLINT
#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
#define GTEST_FLAG_PREFIX_ "gtest_"
+#define GTEST_FLAG_PREFIX_DASH_ "gtest-"
#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_"
#define GTEST_NAME_ "Google Test"
#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/"
@@ -202,10 +217,12 @@
#define GTEST_OS_ZOS 1
#elif defined(__sun) && defined(__SVR4)
#define GTEST_OS_SOLARIS 1
+#elif defined(_AIX)
+#define GTEST_OS_AIX 1
#endif // __CYGWIN__
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_SYMBIAN || \
- GTEST_OS_SOLARIS
+ GTEST_OS_SOLARIS || GTEST_OS_AIX
// On some platforms, <regex.h> needs someone to define size_t, and
// won't compile otherwise. We can #include it here as we already
@@ -214,6 +231,7 @@
#include <regex.h> // NOLINT
#include <strings.h> // NOLINT
#include <sys/types.h> // NOLINT
+#include <time.h> // NOLINT
#include <unistd.h> // NOLINT
#define GTEST_USES_POSIX_RE 1
@@ -236,11 +254,11 @@
#define GTEST_USES_SIMPLE_RE 1
#endif // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC ||
- // GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS
-
-// Defines GTEST_HAS_EXCEPTIONS to 1 if exceptions are enabled, or 0
-// otherwise.
+ // GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS || GTEST_OS_AIX
+#ifndef GTEST_HAS_EXCEPTIONS
+// The user didn't tell us whether exceptions are enabled, so we need
+// to figure it out.
#if defined(_MSC_VER) || defined(__BORLANDC__)
// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS
// macro to enable exceptions, so we'll do the same.
@@ -249,30 +267,32 @@
#define _HAS_EXCEPTIONS 1
#endif // _HAS_EXCEPTIONS
#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
-#else // The compiler is not MSVC or C++Builder.
-// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. For
-// other compilers, we assume exceptions are disabled to be
-// conservative.
-#if defined(__GNUC__) && __EXCEPTIONS
+#elif defined(__GNUC__) && __EXCEPTIONS
+// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled.
+#define GTEST_HAS_EXCEPTIONS 1
+#elif defined(__SUNPRO_CC)
+// Sun Pro CC supports exceptions. However, there is no compile-time way of
+// detecting whether they are enabled or not. Therefore, we assume that
+// they are enabled unless the user tells us otherwise.
+#define GTEST_HAS_EXCEPTIONS 1
+#elif defined(__IBMCPP__) && __EXCEPTIONS
+// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled.
#define GTEST_HAS_EXCEPTIONS 1
#else
+// For other compilers, we assume exceptions are disabled to be
+// conservative.
#define GTEST_HAS_EXCEPTIONS 0
-#endif // defined(__GNUC__) && __EXCEPTIONS
#endif // defined(_MSC_VER) || defined(__BORLANDC__)
+#endif // GTEST_HAS_EXCEPTIONS
-// Determines whether ::std::string and ::string are available.
-
-#ifndef GTEST_HAS_STD_STRING
-// The user didn't tell us whether ::std::string is available, so we
-// need to figure it out. The only environment that we know
-// ::std::string is not available is MSVC 7.1 or lower with exceptions
-// disabled.
-#if defined(_MSC_VER) && (_MSC_VER < 1400) && !GTEST_HAS_EXCEPTIONS
-#define GTEST_HAS_STD_STRING 0
-#else
+#if !defined(GTEST_HAS_STD_STRING)
+// Even though we don't use this macro any longer, we keep it in case
+// some clients still depend on it.
#define GTEST_HAS_STD_STRING 1
-#endif
-#endif // GTEST_HAS_STD_STRING
+#elif !GTEST_HAS_STD_STRING
+// The user told us that ::std::string isn't available.
+#error "Google Test cannot be used where ::std::string isn't available."
+#endif // !defined(GTEST_HAS_STD_STRING)
#ifndef GTEST_HAS_GLOBAL_STRING
// The user didn't tell us whether ::string is available, so we need
@@ -288,14 +308,10 @@
// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring
// is available.
-#if GTEST_OS_CYGWIN || GTEST_OS_SOLARIS
// Cygwin 1.5 and below doesn't support ::std::wstring.
// Cygwin 1.7 might add wstring support; this should be updated when clear.
// Solaris' libc++ doesn't support it either.
-#define GTEST_HAS_STD_WSTRING 0
-#else
-#define GTEST_HAS_STD_WSTRING GTEST_HAS_STD_STRING
-#endif // GTEST_OS_CYGWIN || GTEST_OS_SOLARIS
+#define GTEST_HAS_STD_WSTRING (!(GTEST_OS_CYGWIN || GTEST_OS_SOLARIS))
#endif // GTEST_HAS_STD_WSTRING
@@ -306,18 +322,6 @@
(GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING)
#endif // GTEST_HAS_GLOBAL_WSTRING
-#if GTEST_HAS_STD_STRING || GTEST_HAS_GLOBAL_STRING || \
- GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
-#include <string> // NOLINT
-#endif // GTEST_HAS_STD_STRING || GTEST_HAS_GLOBAL_STRING ||
- // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
-
-#if GTEST_HAS_STD_STRING
-#include <sstream> // NOLINT
-#else
-#include <strstream> // NOLINT
-#endif // GTEST_HAS_STD_STRING
-
// Determines whether RTTI is available.
#ifndef GTEST_HAS_RTTI
// The user didn't tell us whether RTTI is enabled, so we need to
@@ -329,34 +333,49 @@
#define GTEST_HAS_RTTI 1
#else
#define GTEST_HAS_RTTI 0
-#endif // _CPPRTTI
-
-#elif defined(__GNUC__)
+#endif
// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled.
-#if GTEST_GCC_VER_ >= 40302
+#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302)
+
#ifdef __GXX_RTTI
#define GTEST_HAS_RTTI 1
#else
#define GTEST_HAS_RTTI 0
#endif // __GXX_RTTI
-#else
-// For gcc versions smaller than 4.3.2, we assume RTTI is enabled.
+
+// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if
+// both the typeid and dynamic_cast features are present.
+#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)
+
+#ifdef __RTTI_ALL__
#define GTEST_HAS_RTTI 1
-#endif // GTEST_GCC_VER >= 40302
+#else
+#define GTEST_HAS_RTTI 0
+#endif
#else
-// Unknown compiler - assume RTTI is enabled.
+// For all other compilers, we assume RTTI is enabled.
#define GTEST_HAS_RTTI 1
#endif // _MSC_VER
#endif // GTEST_HAS_RTTI
-// Determines whether <pthread.h> is available.
+// It's this header's responsibility to #include <typeinfo> when RTTI
+// is enabled.
+#if GTEST_HAS_RTTI
+#include <typeinfo>
+#endif
+
+// Determines whether Google Test can use the pthreads library.
#ifndef GTEST_HAS_PTHREAD
-// The user didn't tell us, so we need to figure it out.
+// The user didn't tell us explicitly, so we assume pthreads support is
+// available on Linux and Mac.
+//
+// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
+// to your compiler flags.
#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC)
#endif // GTEST_HAS_PTHREAD
@@ -373,17 +392,19 @@
#ifndef GTEST_USE_OWN_TR1_TUPLE
// The user didn't tell us, so we need to figure it out.
-// We use our own tr1 tuple if we aren't sure the user has an
-// implementation of it already. At this time, GCC 4.0.0+ is the only
-// mainstream compiler that comes with a TR1 tuple implementation.
-// MSVC 2008 (9.0) provides TR1 tuple in a 323 MB Feature Pack
-// download, which we cannot assume the user has. MSVC 2010 isn't
-// released yet.
-#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
+// We use our own TR1 tuple if we aren't sure the user has an
+// implementation of it already. At this time, GCC 4.0.0+ and MSVC
+// 2010 are the only mainstream compilers that come with a TR1 tuple
+// implementation. NVIDIA's CUDA NVCC compiler pretends to be GCC by
+// defining __GNUC__ and friends, but cannot compile GCC's tuple
+// implementation. MSVC 2008 (9.0) provides TR1 tuple in a 323 MB
+// Feature Pack download, which we cannot assume the user has.
+#if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \
+ || _MSC_VER >= 1600
#define GTEST_USE_OWN_TR1_TUPLE 0
#else
#define GTEST_USE_OWN_TR1_TUPLE 1
-#endif // defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
+#endif
#endif // GTEST_USE_OWN_TR1_TUPLE
@@ -425,13 +446,13 @@
#undef _TR1_FUNCTIONAL // Allows the user to #include
// <tr1/functional> if he chooses to.
#else
-#include <tr1/tuple>
+#include <tr1/tuple> // NOLINT
#endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
#else
// If the compiler is not GCC 4.0+, we assume the user is using a
// spec-conforming TR1 implementation.
-#include <tuple>
+#include <tuple> // NOLINT
#endif // GTEST_USE_OWN_TR1_TUPLE
#endif // GTEST_HAS_TR1_TUPLE
@@ -451,47 +472,49 @@
#endif // GTEST_HAS_CLONE
+// Determines whether to support stream redirection. This is used to test
+// output correctness and to implement death tests.
+#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN
+#define GTEST_HAS_STREAM_REDIRECTION_ 1
+#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN
+
// Determines whether to support death tests.
-// Google Test does not support death tests for VC 7.1 and earlier for
-// these reasons:
-// 1. std::vector does not build in VC 7.1 when exceptions are disabled.
-// 2. std::string does not build in VC 7.1 when exceptions are disabled
-// (this is covered by GTEST_HAS_STD_STRING guard).
-// 3. abort() in a VC 7.1 application compiled as GUI in debug config
-// pops up a dialog window that cannot be suppressed programmatically.
-#if GTEST_HAS_STD_STRING && \
- (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || \
- (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || GTEST_OS_WINDOWS_MINGW)
+// Google Test does not support death tests for VC 7.1 and earlier as
+// abort() in a VC 7.1 application compiled as GUI in debug config
+// pops up a dialog window that cannot be suppressed programmatically.
+#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
+ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
+ GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX)
#define GTEST_HAS_DEATH_TEST 1
#include <vector> // NOLINT
#endif
-// Determines whether to support value-parameterized tests.
-
-#if defined(__GNUC__) || (_MSC_VER >= 1400)
-// TODO(vladl@google.com): get the implementation rid of vector and list
-// to compile on MSVC 7.1.
+// We don't support MSVC 7.1 with exceptions disabled now. Therefore
+// all the compilers we care about are adequate for supporting
+// value-parameterized tests.
#define GTEST_HAS_PARAM_TEST 1
-#endif // defined(__GNUC__) || (_MSC_VER >= 1400)
// Determines whether to support type-driven tests.
-// Typed tests need <typeinfo> and variadic macros, which gcc and VC
-// 8.0+ support.
-#if defined(__GNUC__) || (_MSC_VER >= 1400)
+// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
+// Sun Pro CC, and IBM Visual Age support.
+#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \
+ defined(__IBMCPP__)
#define GTEST_HAS_TYPED_TEST 1
#define GTEST_HAS_TYPED_TEST_P 1
-#endif // defined(__GNUC__) || (_MSC_VER >= 1400)
+#endif
// Determines whether to support Combine(). This only makes sense when
-// value-parameterized tests are enabled.
-#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE
+// value-parameterized tests are enabled. The implementation doesn't
+// work on Sun Studio since it doesn't understand templated conversion
+// operators.
+#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC)
#define GTEST_HAS_COMBINE 1
-#endif // GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE
+#endif
// Determines whether the system compiler uses UTF-16 for encoding wide strings.
#define GTEST_WIDE_STRING_USES_UTF16_ \
- (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN)
+ (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX)
// Defines some utility macros.
@@ -526,11 +549,16 @@
#define GTEST_ATTRIBUTE_UNUSED_
#endif
-// A macro to disallow the evil copy constructor and operator= functions
+// A macro to disallow operator=
+// This should be used in the private: declarations for a class.
+#define GTEST_DISALLOW_ASSIGN_(type)\
+ void operator=(type const &)
+
+// A macro to disallow copy constructor and operator=
// This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\
- type(const type &);\
- void operator=(const type &)
+ type(type const &);\
+ GTEST_DISALLOW_ASSIGN_(type)
// Tell the compiler to warn about unused return values for functions declared
// with this macro. The macro should be used on function declarations
@@ -559,6 +587,20 @@
#endif // GTEST_HAS_SEH
+#ifdef _MSC_VER
+
+#if GTEST_LINKED_AS_SHARED_LIBRARY
+#define GTEST_API_ __declspec(dllimport)
+#elif GTEST_CREATE_SHARED_LIBRARY
+#define GTEST_API_ __declspec(dllexport)
+#endif
+
+#endif // _MSC_VER
+
+#ifndef GTEST_API_
+#define GTEST_API_
+#endif
+
namespace testing {
class Message;
@@ -567,19 +609,11 @@ namespace internal {
class String;
-// std::strstream is deprecated. However, we have to use it on
-// Windows as std::stringstream won't compile on Windows when
-// exceptions are disabled. We use std::stringstream on other
-// platforms to avoid compiler warnings there.
-#if GTEST_HAS_STD_STRING
typedef ::std::stringstream StrStream;
-#else
-typedef ::std::strstream StrStream;
-#endif // GTEST_HAS_STD_STRING
// A helper for suppressing warnings on constant condition. It just
// returns 'condition'.
-bool IsTrue(bool condition);
+GTEST_API_ bool IsTrue(bool condition);
// Defines scoped_ptr.
@@ -588,6 +622,8 @@ bool IsTrue(bool condition);
template <typename T>
class scoped_ptr {
public:
+ typedef T element_type;
+
explicit scoped_ptr(T* p = NULL) : ptr_(p) {}
~scoped_ptr() { reset(); }
@@ -617,14 +653,16 @@ class scoped_ptr {
// Defines RE.
-// A simple C++ wrapper for <regex.h>. It uses the POSIX Enxtended
+// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended
// Regular Expression syntax.
-class RE {
+class GTEST_API_ RE {
public:
+ // A copy constructor is required by the Standard to initialize object
+ // references from r-values.
+ RE(const RE& other) { Init(other.pattern()); }
+
// Constructs an RE from a string.
-#if GTEST_HAS_STD_STRING
RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT
-#endif // GTEST_HAS_STD_STRING
#if GTEST_HAS_GLOBAL_STRING
RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT
@@ -643,14 +681,12 @@ class RE {
//
// TODO(wan@google.com): make FullMatch() and PartialMatch() work
// when str contains NUL characters.
-#if GTEST_HAS_STD_STRING
static bool FullMatch(const ::std::string& str, const RE& re) {
return FullMatch(str.c_str(), re);
}
static bool PartialMatch(const ::std::string& str, const RE& re) {
return PartialMatch(str.c_str(), re);
}
-#endif // GTEST_HAS_STD_STRING
#if GTEST_HAS_GLOBAL_STRING
static bool FullMatch(const ::string& str, const RE& re) {
@@ -680,7 +716,7 @@ class RE {
const char* full_pattern_; // For FullMatch();
#endif
- GTEST_DISALLOW_COPY_AND_ASSIGN_(RE);
+ GTEST_DISALLOW_ASSIGN_(RE);
};
// Defines logging utilities:
@@ -699,7 +735,7 @@ enum GTestLogSeverity {
// Formats log entry severity, provides a stream object for streaming the
// log message, and terminates the message with a newline when going out of
// scope.
-class GTestLog {
+class GTEST_API_ GTestLog {
public:
GTestLog(GTestLogSeverity severity, const char* file, int line);
@@ -721,12 +757,69 @@ class GTestLog {
inline void LogToStderr() {}
inline void FlushInfoLog() { fflush(NULL); }
+// INTERNAL IMPLEMENTATION - DO NOT USE.
+//
+// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
+// is not satisfied.
+// Synopsys:
+// GTEST_CHECK_(boolean_condition);
+// or
+// GTEST_CHECK_(boolean_condition) << "Additional message";
+//
+// This checks the condition and if the condition is not satisfied
+// it prints message about the condition violation, including the
+// condition itself, plus additional message streamed into it, if any,
+// and then it aborts the program. It aborts the program irrespective of
+// whether it is built in the debug mode or not.
+#define GTEST_CHECK_(condition) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (::testing::internal::IsTrue(condition)) \
+ ; \
+ else \
+ GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
+
+// An all-mode assert to verify that the given POSIX-style function
+// call returns 0 (indicating success). Known limitation: this
+// doesn't expand to a balanced 'if' statement, so enclose the macro
+// in {} if you need to use it as the only statement in an 'if'
+// branch.
+#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \
+ if (const int gtest_error = (posix_call)) \
+ GTEST_LOG_(FATAL) << #posix_call << "failed with error " \
+ << gtest_error
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Downcasts the pointer of type Base to Derived.
+// Derived must be a subclass of Base. The parameter MUST
+// point to a class of type Derived, not any subclass of it.
+// When RTTI is available, the function performs a runtime
+// check to enforce this.
+template <class Derived, class Base>
+Derived* CheckedDowncastToActualType(Base* base) {
+#if GTEST_HAS_RTTI
+ GTEST_CHECK_(typeid(*base) == typeid(Derived));
+ return dynamic_cast<Derived*>(base); // NOLINT
+#else
+ return static_cast<Derived*>(base); // Poor man's downcast.
+#endif
+}
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+
// Defines the stderr capturer:
+// CaptureStdout - starts capturing stdout.
+// GetCapturedStdout - stops capturing stdout and returns the captured string.
// CaptureStderr - starts capturing stderr.
// GetCapturedStderr - stops capturing stderr and returns the captured string.
+//
+GTEST_API_ void CaptureStdout();
+GTEST_API_ String GetCapturedStdout();
+GTEST_API_ void CaptureStderr();
+GTEST_API_ String GetCapturedStderr();
+
+#endif // GTEST_HAS_STREAM_REDIRECTION_
-void CaptureStderr();
-String GetCapturedStderr();
#if GTEST_HAS_DEATH_TEST
@@ -740,6 +833,338 @@ const ::std::vector<String>& GetArgvs();
// Defines synchronization primitives.
+#if GTEST_HAS_PTHREAD
+
+// Sleeps for (roughly) n milli-seconds. This function is only for
+// testing Google Test's own constructs. Don't use it in user tests,
+// either directly or indirectly.
+inline void SleepMilliseconds(int n) {
+ const timespec time = {
+ 0, // 0 seconds.
+ n * 1000L * 1000L, // And n ms.
+ };
+ nanosleep(&time, NULL);
+}
+
+// Allows a controller thread to pause execution of newly created
+// threads until notified. Instances of this class must be created
+// and destroyed in the controller thread.
+//
+// This class is only for testing Google Test's own constructs. Do not
+// use it in user tests, either directly or indirectly.
+class Notification {
+ public:
+ Notification() : notified_(false) {}
+
+ // Notifies all threads created with this notification to start. Must
+ // be called from the controller thread.
+ void Notify() { notified_ = true; }
+
+ // Blocks until the controller thread notifies. Must be called from a test
+ // thread.
+ void WaitForNotification() {
+ while(!notified_) {
+ SleepMilliseconds(10);
+ }
+ }
+
+ private:
+ volatile bool notified_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
+};
+
+// As a C-function, ThreadFuncWithCLinkage cannot be templated itself.
+// Consequently, it cannot select a correct instantiation of ThreadWithParam
+// in order to call its Run(). Introducing ThreadWithParamBase as a
+// non-templated base class for ThreadWithParam allows us to bypass this
+// problem.
+class ThreadWithParamBase {
+ public:
+ virtual ~ThreadWithParamBase() {}
+ virtual void Run() = 0;
+};
+
+// pthread_create() accepts a pointer to a function type with the C linkage.
+// According to the Standard (7.5/1), function types with different linkages
+// are different even if they are otherwise identical. Some compilers (for
+// example, SunStudio) treat them as different types. Since class methods
+// cannot be defined with C-linkage we need to define a free C-function to
+// pass into pthread_create().
+extern "C" inline void* ThreadFuncWithCLinkage(void* thread) {
+ static_cast<ThreadWithParamBase*>(thread)->Run();
+ return NULL;
+}
+
+// Helper class for testing Google Test's multi-threading constructs.
+// To use it, write:
+//
+// void ThreadFunc(int param) { /* Do things with param */ }
+// Notification thread_can_start;
+// ...
+// // The thread_can_start parameter is optional; you can supply NULL.
+// ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start);
+// thread_can_start.Notify();
+//
+// These classes are only for testing Google Test's own constructs. Do
+// not use them in user tests, either directly or indirectly.
+template <typename T>
+class ThreadWithParam : public ThreadWithParamBase {
+ public:
+ typedef void (*UserThreadFunc)(T);
+
+ ThreadWithParam(
+ UserThreadFunc func, T param, Notification* thread_can_start)
+ : func_(func),
+ param_(param),
+ thread_can_start_(thread_can_start),
+ finished_(false) {
+ ThreadWithParamBase* const base = this;
+ // The thread can be created only after all fields except thread_
+ // have been initialized.
+ GTEST_CHECK_POSIX_SUCCESS_(
+ pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base));
+ }
+ ~ThreadWithParam() { Join(); }
+
+ void Join() {
+ if (!finished_) {
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));
+ finished_ = true;
+ }
+ }
+
+ virtual void Run() {
+ if (thread_can_start_ != NULL)
+ thread_can_start_->WaitForNotification();
+ func_(param_);
+ }
+
+ private:
+ const UserThreadFunc func_; // User-supplied thread function.
+ const T param_; // User-supplied parameter to the thread function.
+ // When non-NULL, used to block execution until the controller thread
+ // notifies.
+ Notification* const thread_can_start_;
+ bool finished_; // true iff we know that the thread function has finished.
+ pthread_t thread_; // The native thread object.
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
+};
+
+// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is
+// true.
+#include <pthread.h>
+
+// MutexBase and Mutex implement mutex on pthreads-based platforms. They
+// are used in conjunction with class MutexLock:
+//
+// Mutex mutex;
+// ...
+// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end
+// // of the current scope.
+//
+// MutexBase implements behavior for both statically and dynamically
+// allocated mutexes. Do not use MutexBase directly. Instead, write
+// the following to define a static mutex:
+//
+// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);
+//
+// You can forward declare a static mutex like this:
+//
+// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
+//
+// To create a dynamic mutex, just define an object of type Mutex.
+class MutexBase {
+ public:
+ // Acquires this mutex.
+ void Lock() {
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
+ owner_ = pthread_self();
+ }
+
+ // Releases this mutex.
+ void Unlock() {
+ // We don't protect writing to owner_ here, as it's the caller's
+ // responsibility to ensure that the current thread holds the
+ // mutex when this is called.
+ owner_ = 0;
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
+ }
+
+ // Does nothing if the current thread holds the mutex. Otherwise, crashes
+ // with high probability.
+ void AssertHeld() const {
+ GTEST_CHECK_(owner_ == pthread_self())
+ << "The current thread is not holding the mutex @" << this;
+ }
+
+ // A static mutex may be used before main() is entered. It may even
+ // be used before the dynamic initialization stage. Therefore we
+ // must be able to initialize a static mutex object at link time.
+ // This means MutexBase has to be a POD and its member variables
+ // have to be public.
+ public:
+ pthread_mutex_t mutex_; // The underlying pthread mutex.
+ pthread_t owner_; // The thread holding the mutex; 0 means no one holds it.
+};
+
+// Forward-declares a static mutex.
+#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
+ extern ::testing::internal::MutexBase mutex
+
+// Defines and statically (i.e. at link time) initializes a static mutex.
+#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
+ ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 }
+
+// The Mutex class can only be used for mutexes created at runtime. It
+// shares its API with MutexBase otherwise.
+class Mutex : public MutexBase {
+ public:
+ Mutex() {
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
+ owner_ = 0;
+ }
+ ~Mutex() {
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_));
+ }
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex);
+};
+
+// We cannot name this class MutexLock as the ctor declaration would
+// conflict with a macro named MutexLock, which is defined on some
+// platforms. Hence the typedef trick below.
+class GTestMutexLock {
+ public:
+ explicit GTestMutexLock(MutexBase* mutex)
+ : mutex_(mutex) { mutex_->Lock(); }
+
+ ~GTestMutexLock() { mutex_->Unlock(); }
+
+ private:
+ MutexBase* const mutex_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock);
+};
+
+typedef GTestMutexLock MutexLock;
+
+// Helpers for ThreadLocal.
+
+// pthread_key_create() requires DeleteThreadLocalValue() to have
+// C-linkage. Therefore it cannot be templatized to access
+// ThreadLocal<T>. Hence the need for class
+// ThreadLocalValueHolderBase.
+class ThreadLocalValueHolderBase {
+ public:
+ virtual ~ThreadLocalValueHolderBase() {}
+};
+
+// Called by pthread to delete thread-local data stored by
+// pthread_setspecific().
+extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
+ delete static_cast<ThreadLocalValueHolderBase*>(value_holder);
+}
+
+// Implements thread-local storage on pthreads-based systems.
+//
+// // Thread 1
+// ThreadLocal<int> tl(100); // 100 is the default value for each thread.
+//
+// // Thread 2
+// tl.set(150); // Changes the value for thread 2 only.
+// EXPECT_EQ(150, tl.get());
+//
+// // Thread 1
+// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value.
+// tl.set(200);
+// EXPECT_EQ(200, tl.get());
+//
+// The template type argument T must have a public copy constructor.
+// In addition, the default ThreadLocal constructor requires T to have
+// a public default constructor.
+//
+// An object managed for a thread by a ThreadLocal instance is deleted
+// when the thread exits. Or, if the ThreadLocal instance dies in
+// that thread, when the ThreadLocal dies. It's the user's
+// responsibility to ensure that all other threads using a ThreadLocal
+// have exited when it dies, or the per-thread objects for those
+// threads will not be deleted.
+//
+// Google Test only uses global ThreadLocal objects. That means they
+// will die after main() has returned. Therefore, no per-thread
+// object managed by Google Test will be leaked as long as all threads
+// using Google Test have exited when main() returns.
+template <typename T>
+class ThreadLocal {
+ public:
+ ThreadLocal() : key_(CreateKey()),
+ default_() {}
+ explicit ThreadLocal(const T& value) : key_(CreateKey()),
+ default_(value) {}
+
+ ~ThreadLocal() {
+ // Destroys the managed object for the current thread, if any.
+ DeleteThreadLocalValue(pthread_getspecific(key_));
+
+ // Releases resources associated with the key. This will *not*
+ // delete managed objects for other threads.
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_));
+ }
+
+ T* pointer() { return GetOrCreateValue(); }
+ const T* pointer() const { return GetOrCreateValue(); }
+ const T& get() const { return *pointer(); }
+ void set(const T& value) { *pointer() = value; }
+
+ private:
+ // Holds a value of type T.
+ class ValueHolder : public ThreadLocalValueHolderBase {
+ public:
+ explicit ValueHolder(const T& value) : value_(value) {}
+
+ T* pointer() { return &value_; }
+
+ private:
+ T value_;
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder);
+ };
+
+ static pthread_key_t CreateKey() {
+ pthread_key_t key;
+ // When a thread exits, DeleteThreadLocalValue() will be called on
+ // the object managed for that thread.
+ GTEST_CHECK_POSIX_SUCCESS_(
+ pthread_key_create(&key, &DeleteThreadLocalValue));
+ return key;
+ }
+
+ T* GetOrCreateValue() const {
+ ThreadLocalValueHolderBase* const holder =
+ static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_));
+ if (holder != NULL) {
+ return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();
+ }
+
+ ValueHolder* const new_holder = new ValueHolder(default_);
+ ThreadLocalValueHolderBase* const holder_base = new_holder;
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));
+ return new_holder->pointer();
+ }
+
+ // A key pthreads uses for looking up per-thread values.
+ const pthread_key_t key_;
+ const T default_; // The default value for each thread.
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
+};
+
+#define GTEST_IS_THREADSAFE 1
+
+#else // GTEST_HAS_PTHREAD
+
// A dummy implementation of synchronization primitives (mutex, lock,
// and thread-local variable). Necessary for compiling Google Test where
// mutex is not supported - using Google Test in multiple threads is not
@@ -748,14 +1173,14 @@ const ::std::vector<String>& GetArgvs();
class Mutex {
public:
Mutex() {}
- explicit Mutex(int /*unused*/) {}
void AssertHeld() const {}
- enum { NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX = 0 };
};
-// We cannot call it MutexLock directly as the ctor declaration would
-// conflict with a macro named MutexLock, which is defined on some
-// platforms. Hence the typedef trick below.
+#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
+ extern ::testing::internal::Mutex mutex
+
+#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex
+
class GTestMutexLock {
public:
explicit GTestMutexLock(Mutex*) {} // NOLINT
@@ -776,30 +1201,37 @@ class ThreadLocal {
T value_;
};
-// Returns the number of threads running in the process, or 0 to indicate that
-// we cannot detect it.
-size_t GetThreadCount();
-
// The above synchronization primitives have dummy implementations.
// Therefore Google Test is not thread-safe.
#define GTEST_IS_THREADSAFE 0
-#if defined(__SYMBIAN32__) || defined(__IBMCPP__)
+#endif // GTEST_HAS_PTHREAD
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+GTEST_API_ size_t GetThreadCount();
// Passing non-POD classes through ellipsis (...) crashes the ARM
-// compiler. The Nokia Symbian and the IBM XL C/C++ compiler try to
-// instantiate a copy constructor for objects passed through ellipsis
-// (...), failing for uncopyable objects. We define this to indicate
-// the fact.
-#define GTEST_ELLIPSIS_NEEDS_COPY_ 1
+// compiler and generates a warning in Sun Studio. The Nokia Symbian
+// and the IBM XL C/C++ compiler try to instantiate a copy constructor
+// for objects passed through ellipsis (...), failing for uncopyable
+// objects. We define this to ensure that only POD is passed through
+// ellipsis on these systems.
+#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC)
+// We lose support for NULL detection where the compiler doesn't like
+// passing non-POD classes through ellipsis (...).
+#define GTEST_ELLIPSIS_NEEDS_POD_ 1
+#else
+#define GTEST_CAN_COMPARE_NULL 1
+#endif
// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between
// const T& and const T* in a function template. These compilers
// _can_ decide between class template specializations for T and T*,
// so a tr1::type_traits-like is_pointer works.
+#if defined(__SYMBIAN32__) || defined(__IBMCPP__)
#define GTEST_NEEDS_IS_POINTER_ 1
-
-#endif // defined(__SYMBIAN32__) || defined(__IBMCPP__)
+#endif
template <bool bool_value>
struct bool_constant {
@@ -819,10 +1251,12 @@ struct is_pointer<T*> : public true_type {};
#if GTEST_OS_WINDOWS
#define GTEST_PATH_SEP_ "\\"
+#define GTEST_HAS_ALT_PATH_SEP_ 1
// The biggest signed integer type the compiler supports.
typedef __int64 BiggestInt;
#else
#define GTEST_PATH_SEP_ "/"
+#define GTEST_HAS_ALT_PATH_SEP_ 0
typedef long long BiggestInt; // NOLINT
#endif // GTEST_OS_WINDOWS
@@ -930,7 +1364,7 @@ inline const char* GetEnv(const char* name) {
#if GTEST_OS_WINDOWS_MOBILE
// We are on Windows CE, which has no environment variables.
return NULL;
-#elif defined(__BORLANDC__)
+#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
// Environment variables which we programmatically clear will be set to the
// empty string rather than unset (NULL). Handle that case.
const char* const env = getenv(name);
@@ -1025,44 +1459,23 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
// Utilities for command line flags and environment variables.
-// INTERNAL IMPLEMENTATION - DO NOT USE.
-//
-// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
-// is not satisfied.
-// Synopsys:
-// GTEST_CHECK_(boolean_condition);
-// or
-// GTEST_CHECK_(boolean_condition) << "Additional message";
-//
-// This checks the condition and if the condition is not satisfied
-// it prints message about the condition violation, including the
-// condition itself, plus additional message streamed into it, if any,
-// and then it aborts the program. It aborts the program irrespective of
-// whether it is built in the debug mode or not.
-#define GTEST_CHECK_(condition) \
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
- if (::testing::internal::IsTrue(condition)) \
- ; \
- else \
- GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
-
// Macro for referencing flags.
#define GTEST_FLAG(name) FLAGS_gtest_##name
// Macros for declaring flags.
-#define GTEST_DECLARE_bool_(name) extern bool GTEST_FLAG(name)
+#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
#define GTEST_DECLARE_int32_(name) \
- extern ::testing::internal::Int32 GTEST_FLAG(name)
+ GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)
#define GTEST_DECLARE_string_(name) \
- extern ::testing::internal::String GTEST_FLAG(name)
+ GTEST_API_ extern ::testing::internal::String GTEST_FLAG(name)
// Macros for defining flags.
#define GTEST_DEFINE_bool_(name, default_val, doc) \
- bool GTEST_FLAG(name) = (default_val)
+ GTEST_API_ bool GTEST_FLAG(name) = (default_val)
#define GTEST_DEFINE_int32_(name, default_val, doc) \
- ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
+ GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
#define GTEST_DEFINE_string_(name, default_val, doc) \
- ::testing::internal::String GTEST_FLAG(name) = (default_val)
+ GTEST_API_ ::testing::internal::String GTEST_FLAG(name) = (default_val)
// Parses 'str' for a 32-bit signed integer. If successful, writes the result
// to *value and returns true; otherwise leaves *value unchanged and returns
@@ -1075,7 +1488,7 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value);
// Parses a bool/Int32/string from the environment variable
// corresponding to the given Google Test flag.
bool BoolFromGTestEnv(const char* flag, bool default_val);
-Int32 Int32FromGTestEnv(const char* flag, Int32 default_val);
+GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val);
const char* StringFromGTestEnv(const char* flag, const char* default_val);
} // namespace internal
diff --git a/gtest/include/gtest/internal/gtest-string.h b/gtest/include/gtest/internal/gtest-string.h
index 4bc8241..aff093d 100644
--- a/gtest/include/gtest/internal/gtest-string.h
+++ b/gtest/include/gtest/internal/gtest-string.h
@@ -41,26 +41,28 @@
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
+#ifdef __BORLANDC__
+// string.h is not guaranteed to provide strcpy on C++ Builder.
+#include <mem.h>
+#endif
+
#include <string.h>
#include <gtest/internal/gtest-port.h>
-#if GTEST_HAS_GLOBAL_STRING || GTEST_HAS_STD_STRING
#include <string>
-#endif // GTEST_HAS_GLOBAL_STRING || GTEST_HAS_STD_STRING
namespace testing {
namespace internal {
// String - a UTF-8 string class.
//
-// We cannot use std::string as Microsoft's STL implementation in
-// Visual C++ 7.1 has problems when exception is disabled. There is a
-// hack to work around this, but we've seen cases where the hack fails
-// to work.
+// For historic reasons, we don't use std::string.
//
-// Also, String is different from std::string in that it can represent
-// both NULL and the empty string, while std::string cannot represent
-// NULL.
+// TODO(wan@google.com): replace this class with std::string or
+// implement it in terms of the latter.
+//
+// Note that String can represent both NULL and the empty string,
+// while std::string cannot represent NULL.
//
// NULL and the empty string are considered different. NULL is less
// than anything (including the empty string) except itself.
@@ -76,7 +78,7 @@ namespace internal {
//
// In order to make the representation efficient, the d'tor of String
// is not virtual. Therefore DO NOT INHERIT FROM String.
-class String {
+class GTEST_API_ String {
public:
// Static utility methods
@@ -190,12 +192,12 @@ class String {
String() : c_str_(NULL), length_(0) {}
// Constructs a String by cloning a 0-terminated C string.
- String(const char* c_str) { // NOLINT
- if (c_str == NULL) {
+ String(const char* a_c_str) { // NOLINT
+ if (a_c_str == NULL) {
c_str_ = NULL;
length_ = 0;
} else {
- ConstructNonNull(c_str, strlen(c_str));
+ ConstructNonNull(a_c_str, strlen(a_c_str));
}
}
@@ -203,8 +205,8 @@ class String {
// buffer. E.g. String("hello", 3) creates the string "hel",
// String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "",
// and String(NULL, 1) results in access violation.
- String(const char* buffer, size_t length) {
- ConstructNonNull(buffer, length);
+ String(const char* buffer, size_t a_length) {
+ ConstructNonNull(buffer, a_length);
}
// The copy c'tor creates a new copy of the string. The two
@@ -221,13 +223,11 @@ class String {
// Converting a ::std::string or ::string containing an embedded NUL
// character to a String will result in the prefix up to the first
// NUL character.
-#if GTEST_HAS_STD_STRING
String(const ::std::string& str) {
ConstructNonNull(str.c_str(), str.length());
}
operator ::std::string() const { return ::std::string(c_str(), length()); }
-#endif // GTEST_HAS_STD_STRING
#if GTEST_HAS_GLOBAL_STRING
String(const ::string& str) {
@@ -247,7 +247,7 @@ class String {
// Returns true iff this String equals the given C string. A NULL
// string and a non-NULL string are considered not equal.
- bool operator==(const char* c_str) const { return Compare(c_str) == 0; }
+ bool operator==(const char* a_c_str) const { return Compare(a_c_str) == 0; }
// Returns true iff this String is less than the given String. A
// NULL string is considered less than "".
@@ -255,7 +255,7 @@ class String {
// Returns true iff this String doesn't equal the given C string. A NULL
// string and a non-NULL string are considered not equal.
- bool operator!=(const char* c_str) const { return !(*this == c_str); }
+ bool operator!=(const char* a_c_str) const { return !(*this == a_c_str); }
// Returns true iff this String ends with the given suffix. *Any*
// String is considered to end with a NULL or empty suffix.
@@ -275,7 +275,9 @@ class String {
const char* c_str() const { return c_str_; }
// Assigns a C string to this object. Self-assignment works.
- const String& operator=(const char* c_str) { return *this = String(c_str); }
+ const String& operator=(const char* a_c_str) {
+ return *this = String(a_c_str);
+ }
// Assigns a String object to this object. Self-assignment works.
const String& operator=(const String& rhs) {
@@ -297,12 +299,12 @@ class String {
// function can only be called when data_ has not been allocated.
// ConstructNonNull(NULL, 0) results in an empty string ("").
// ConstructNonNull(NULL, non_zero) is undefined behavior.
- void ConstructNonNull(const char* buffer, size_t length) {
- char* const str = new char[length + 1];
- memcpy(str, buffer, length);
- str[length] = '\0';
+ void ConstructNonNull(const char* buffer, size_t a_length) {
+ char* const str = new char[a_length + 1];
+ memcpy(str, buffer, a_length);
+ str[a_length] = '\0';
c_str_ = str;
- length_ = length;
+ length_ = a_length;
}
const char* c_str_;
@@ -329,7 +331,7 @@ inline ::std::ostream& operator<<(::std::ostream& os, const String& str) {
// Gets the content of the StrStream's buffer as a String. Each '\0'
// character in the buffer is replaced with "\\0".
-String StrStreamToString(StrStream* stream);
+GTEST_API_ String StrStreamToString(StrStream* stream);
// Converts a streamable value to a String. A NULL pointer is
// converted to "(null)". When the input value is a ::string,
diff --git a/gtest/include/gtest/internal/gtest-tuple.h b/gtest/include/gtest/internal/gtest-tuple.h
index 86b200b..16178fc 100644
--- a/gtest/include/gtest/internal/gtest-tuple.h
+++ b/gtest/include/gtest/internal/gtest-tuple.h
@@ -42,7 +42,8 @@
// tuple template as a friend (it complains that tuple is redefined). This
// hack bypasses the bug by declaring the members that should otherwise be
// private as public.
-#if defined(__SYMBIAN32__)
+// Sun Studio versions < 12 also have the above bug.
+#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
#else
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
@@ -183,7 +184,7 @@ class GTEST_1_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
- tuple() {}
+ tuple() : f0_() {}
explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}
@@ -215,7 +216,7 @@ class GTEST_2_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
- tuple() {}
+ tuple() : f0_(), f1_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),
f1_(f1) {}
@@ -258,7 +259,7 @@ class GTEST_3_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
- tuple() {}
+ tuple() : f0_(), f1_(), f2_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}
@@ -295,7 +296,7 @@ class GTEST_4_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
- tuple() {}
+ tuple() : f0_(), f1_(), f2_(), f3_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),
@@ -336,7 +337,7 @@ class GTEST_5_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
- tuple() {}
+ tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,
@@ -380,7 +381,7 @@ class GTEST_6_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
- tuple() {}
+ tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
@@ -427,7 +428,7 @@ class GTEST_7_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
- tuple() {}
+ tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
@@ -476,7 +477,7 @@ class GTEST_8_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
- tuple() {}
+ tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
@@ -528,7 +529,7 @@ class GTEST_9_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
- tuple() {}
+ tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
@@ -582,7 +583,8 @@ class tuple {
public:
template <int k> friend class gtest_internal::Get;
- tuple() {}
+ tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(),
+ f9_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
diff --git a/gtest/include/gtest/internal/gtest-tuple.h.pump b/gtest/include/gtest/internal/gtest-tuple.h.pump
index 12821d8..85ebc80 100644
--- a/gtest/include/gtest/internal/gtest-tuple.h.pump
+++ b/gtest/include/gtest/internal/gtest-tuple.h.pump
@@ -39,11 +39,12 @@ $$ This meta comment fixes auto-indentation in Emacs. }}
#include <utility> // For ::std::pair.
-// The compiler used in Symbian 5th Edition (__S60_50__) has a bug
-// that prevents us from declaring the tuple template as a friend (it
-// complains that tuple is redefined). This hack bypasses the bug by
-// declaring the members that should otherwise be private as public.
-#if defined(__SYMBIAN32__) && __S60_50__
+// The compiler used in Symbian has a bug that prevents us from declaring the
+// tuple template as a friend (it complains that tuple is redefined). This
+// hack bypasses the bug by declaring the members that should otherwise be
+// private as public.
+// Sun Studio versions < 12 also have the above bug.
+#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
#else
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
@@ -140,7 +141,7 @@ class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
public:
template <int k> friend class gtest_internal::Get;
- tuple() {}
+ tuple() : $for m, [[f$(m)_()]] {}
explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
$for m, [[f$(m)_(f$m)]] {}
diff --git a/gtest/include/gtest/internal/gtest-type-util.h b/gtest/include/gtest/internal/gtest-type-util.h
index f1b1bed..093eee6 100644
--- a/gtest/include/gtest/internal/gtest-type-util.h
+++ b/gtest/include/gtest/internal/gtest-type-util.h
@@ -1,4 +1,6 @@
-// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
+// This file was GENERATED by command:
+// pump.py gtest-type-util.h.pump
+// DO NOT EDIT BY HAND!!!
// Copyright 2008 Google Inc.
// All Rights Reserved.
@@ -53,8 +55,6 @@
#include <cxxabi.h>
#endif // __GLIBCXX__
-#include <typeinfo>
-
namespace testing {
namespace internal {
diff --git a/gtest/include/gtest/internal/gtest-type-util.h.pump b/gtest/include/gtest/internal/gtest-type-util.h.pump
index 3eb5dce..5aed1e5 100644
--- a/gtest/include/gtest/internal/gtest-type-util.h.pump
+++ b/gtest/include/gtest/internal/gtest-type-util.h.pump
@@ -53,8 +53,6 @@ $var n = 50 $$ Maximum length of type lists we want to support.
#include <cxxabi.h>
#endif // __GLIBCXX__
-#include <typeinfo>
-
namespace testing {
namespace internal {
diff --git a/gtest/make/Makefile b/gtest/make/Makefile
index 2d8806e..5b27b6a 100644
--- a/gtest/make/Makefile
+++ b/gtest/make/Makefile
@@ -20,7 +20,7 @@ GTEST_DIR = ..
USER_DIR = ../samples
# Flags passed to the preprocessor.
-CPPFLAGS += -I$(GTEST_DIR) -I$(GTEST_DIR)/include
+CPPFLAGS += -I$(GTEST_DIR)/include
# Flags passed to the C++ compiler.
CXXFLAGS += -g -Wall -Wextra
@@ -52,10 +52,12 @@ GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
# conservative and not optimized. This is fine as Google Test
# compiles fast and for ordinary users its source rarely changes.
gtest-all.o : $(GTEST_SRCS_)
- $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest-all.cc
+ $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
+ $(GTEST_DIR)/src/gtest-all.cc
gtest_main.o : $(GTEST_SRCS_)
- $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest_main.cc
+ $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
+ $(GTEST_DIR)/src/gtest_main.cc
gtest.a : gtest-all.o
$(AR) $(ARFLAGS) $@ $^
@@ -75,4 +77,4 @@ sample1_unittest.o : $(USER_DIR)/sample1_unittest.cc \
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1_unittest.cc
sample1_unittest : sample1.o sample1_unittest.o gtest_main.a
- $(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
diff --git a/gtest/msvc/gtest-md.sln b/gtest/msvc/gtest-md.sln
index f7908da..f7908da 100644..100755
--- a/gtest/msvc/gtest-md.sln
+++ b/gtest/msvc/gtest-md.sln
diff --git a/gtest/msvc/gtest-md.vcproj b/gtest/msvc/gtest-md.vcproj
index c78a4a4..c78a4a4 100644..100755
--- a/gtest/msvc/gtest-md.vcproj
+++ b/gtest/msvc/gtest-md.vcproj
diff --git a/gtest/msvc/gtest.sln b/gtest/msvc/gtest.sln
index ef4b057..ef4b057 100644..100755
--- a/gtest/msvc/gtest.sln
+++ b/gtest/msvc/gtest.sln
diff --git a/gtest/msvc/gtest.vcproj b/gtest/msvc/gtest.vcproj
index 09d5b93..09d5b93 100644..100755
--- a/gtest/msvc/gtest.vcproj
+++ b/gtest/msvc/gtest.vcproj
diff --git a/gtest/msvc/gtest_main-md.vcproj b/gtest/msvc/gtest_main-md.vcproj
index 321667f..321667f 100644..100755
--- a/gtest/msvc/gtest_main-md.vcproj
+++ b/gtest/msvc/gtest_main-md.vcproj
diff --git a/gtest/msvc/gtest_main.vcproj b/gtest/msvc/gtest_main.vcproj
index 1c8c58e..1c8c58e 100644..100755
--- a/gtest/msvc/gtest_main.vcproj
+++ b/gtest/msvc/gtest_main.vcproj
diff --git a/gtest/msvc/gtest_prod_test-md.vcproj b/gtest/msvc/gtest_prod_test-md.vcproj
index 05b05d9..05b05d9 100644..100755
--- a/gtest/msvc/gtest_prod_test-md.vcproj
+++ b/gtest/msvc/gtest_prod_test-md.vcproj
diff --git a/gtest/msvc/gtest_prod_test.vcproj b/gtest/msvc/gtest_prod_test.vcproj
index d1f6345..d1f6345 100644..100755
--- a/gtest/msvc/gtest_prod_test.vcproj
+++ b/gtest/msvc/gtest_prod_test.vcproj
diff --git a/gtest/msvc/gtest_unittest-md.vcproj b/gtest/msvc/gtest_unittest-md.vcproj
index 38a5e56..38a5e56 100644..100755
--- a/gtest/msvc/gtest_unittest-md.vcproj
+++ b/gtest/msvc/gtest_unittest-md.vcproj
diff --git a/gtest/msvc/gtest_unittest.vcproj b/gtest/msvc/gtest_unittest.vcproj
index 3c8769e..3c8769e 100644..100755
--- a/gtest/msvc/gtest_unittest.vcproj
+++ b/gtest/msvc/gtest_unittest.vcproj
diff --git a/gtest/samples/prime_tables.h b/gtest/samples/prime_tables.h
index 236e84c..92ce16a 100644
--- a/gtest/samples/prime_tables.h
+++ b/gtest/samples/prime_tables.h
@@ -115,6 +115,9 @@ class PreCalculatedPrimeTable : public PrimeTable {
const int is_prime_size_;
bool* const is_prime_;
+
+ // Disables compiler warning "assignment operator could not be generated."
+ void operator=(const PreCalculatedPrimeTable& rhs);
};
#endif // GTEST_SAMPLES_PRIME_TABLES_H_
diff --git a/gtest/samples/sample10_unittest.cc b/gtest/samples/sample10_unittest.cc
index 703ec6e..3ad6fd6 100644
--- a/gtest/samples/sample10_unittest.cc
+++ b/gtest/samples/sample10_unittest.cc
@@ -58,7 +58,7 @@ class Water {
return malloc(allocation_size);
}
- void operator delete(void* block, size_t allocation_size) {
+ void operator delete(void* block, size_t /* allocation_size */) {
allocated_--;
free(block);
}
@@ -78,12 +78,12 @@ int Water::allocated_ = 0;
class LeakChecker : public EmptyTestEventListener {
private:
// Called before a test starts.
- virtual void OnTestStart(const TestInfo& test_info) {
+ virtual void OnTestStart(const TestInfo& /* test_info */) {
initially_allocated_ = Water::allocated();
}
// Called after a test ends.
- virtual void OnTestEnd(const TestInfo& test_info) {
+ virtual void OnTestEnd(const TestInfo& /* test_info */) {
int difference = Water::allocated() - initially_allocated_;
// You can generate a failure in any event handler except
diff --git a/gtest/samples/sample2.cc b/gtest/samples/sample2.cc
index 53857c0..5f763b9 100644
--- a/gtest/samples/sample2.cc
+++ b/gtest/samples/sample2.cc
@@ -36,21 +36,21 @@
#include <string.h>
// Clones a 0-terminated C string, allocating memory using new.
-const char * MyString::CloneCString(const char * c_string) {
- if (c_string == NULL) return NULL;
+const char* MyString::CloneCString(const char* a_c_string) {
+ if (a_c_string == NULL) return NULL;
- const size_t len = strlen(c_string);
- char * const clone = new char[ len + 1 ];
- memcpy(clone, c_string, len + 1);
+ const size_t len = strlen(a_c_string);
+ char* const clone = new char[ len + 1 ];
+ memcpy(clone, a_c_string, len + 1);
return clone;
}
// Sets the 0-terminated C string this MyString object
// represents.
-void MyString::Set(const char * c_string) {
+void MyString::Set(const char* a_c_string) {
// Makes sure this works when c_string == c_string_
- const char * const temp = MyString::CloneCString(c_string);
+ const char* const temp = MyString::CloneCString(a_c_string);
delete[] c_string_;
c_string_ = temp;
}
diff --git a/gtest/samples/sample2.h b/gtest/samples/sample2.h
index c5f3b8c..5b57e60 100644
--- a/gtest/samples/sample2.h
+++ b/gtest/samples/sample2.h
@@ -40,13 +40,13 @@
// A simple string class.
class MyString {
private:
- const char * c_string_;
+ const char* c_string_;
const MyString& operator=(const MyString& rhs);
public:
// Clones a 0-terminated C string, allocating memory using new.
- static const char * CloneCString(const char * c_string);
+ static const char* CloneCString(const char* a_c_string);
////////////////////////////////////////////////////////////
//
@@ -56,8 +56,8 @@ class MyString {
MyString() : c_string_(NULL) {}
// Constructs a MyString by cloning a 0-terminated C string.
- explicit MyString(const char * c_string) : c_string_(NULL) {
- Set(c_string);
+ explicit MyString(const char* a_c_string) : c_string_(NULL) {
+ Set(a_c_string);
}
// Copy c'tor
@@ -72,14 +72,14 @@ class MyString {
~MyString() { delete[] c_string_; }
// Gets the 0-terminated C string this MyString object represents.
- const char * c_string() const { return c_string_; }
+ const char* c_string() const { return c_string_; }
size_t Length() const {
return c_string_ == NULL ? 0 : strlen(c_string_);
}
// Sets the 0-terminated C string this MyString object represents.
- void Set(const char * c_string);
+ void Set(const char* c_string);
};
diff --git a/gtest/samples/sample2_unittest.cc b/gtest/samples/sample2_unittest.cc
index e1d7910..32232d9 100644
--- a/gtest/samples/sample2_unittest.cc
+++ b/gtest/samples/sample2_unittest.cc
@@ -71,7 +71,7 @@ TEST(MyString, DefaultConstructor) {
// </TechnicalDetails>
EXPECT_STREQ(NULL, s.c_string());
- EXPECT_EQ(0, s.Length());
+ EXPECT_EQ(0u, s.Length());
}
const char kHelloString[] = "Hello, world!";
diff --git a/gtest/samples/sample3-inl.h b/gtest/samples/sample3-inl.h
index 630e950..46369a0 100644
--- a/gtest/samples/sample3-inl.h
+++ b/gtest/samples/sample3-inl.h
@@ -51,23 +51,23 @@ class QueueNode {
public:
// Gets the element in this node.
- const E & element() const { return element_; }
+ const E& element() const { return element_; }
// Gets the next node in the queue.
- QueueNode * next() { return next_; }
- const QueueNode * next() const { return next_; }
+ QueueNode* next() { return next_; }
+ const QueueNode* next() const { return next_; }
private:
// Creates a node with a given element value. The next pointer is
// set to NULL.
- QueueNode(const E & element) : element_(element), next_(NULL) {}
+ QueueNode(const E& an_element) : element_(an_element), next_(NULL) {}
// We disable the default assignment operator and copy c'tor.
- const QueueNode & operator = (const QueueNode &);
- QueueNode(const QueueNode &);
+ const QueueNode& operator = (const QueueNode&);
+ QueueNode(const QueueNode&);
E element_;
- QueueNode * next_;
+ QueueNode* next_;
};
template <typename E> // E is the element type.
@@ -84,8 +84,8 @@ public:
void Clear() {
if (size_ > 0) {
// 1. Deletes every node.
- QueueNode<E> * node = head_;
- QueueNode<E> * next = node->next();
+ QueueNode<E>* node = head_;
+ QueueNode<E>* next = node->next();
for (; ;) {
delete node;
node = next;
@@ -103,19 +103,19 @@ public:
size_t Size() const { return size_; }
// Gets the first element of the queue, or NULL if the queue is empty.
- QueueNode<E> * Head() { return head_; }
- const QueueNode<E> * Head() const { return head_; }
+ QueueNode<E>* Head() { return head_; }
+ const QueueNode<E>* Head() const { return head_; }
// Gets the last element of the queue, or NULL if the queue is empty.
- QueueNode<E> * Last() { return last_; }
- const QueueNode<E> * Last() const { return last_; }
+ QueueNode<E>* Last() { return last_; }
+ const QueueNode<E>* Last() const { return last_; }
// Adds an element to the end of the queue. A copy of the element is
// created using the copy constructor, and then stored in the queue.
// Changes made to the element in the queue doesn't affect the source
// object, and vice versa.
- void Enqueue(const E & element) {
- QueueNode<E> * new_node = new QueueNode<E>(element);
+ void Enqueue(const E& element) {
+ QueueNode<E>* new_node = new QueueNode<E>(element);
if (size_ == 0) {
head_ = last_ = new_node;
@@ -129,19 +129,19 @@ public:
// Removes the head of the queue and returns it. Returns NULL if
// the queue is empty.
- E * Dequeue() {
+ E* Dequeue() {
if (size_ == 0) {
return NULL;
}
- const QueueNode<E> * const old_head = head_;
+ const QueueNode<E>* const old_head = head_;
head_ = head_->next_;
size_--;
if (size_ == 0) {
last_ = NULL;
}
- E * element = new E(old_head->element());
+ E* element = new E(old_head->element());
delete old_head;
return element;
@@ -151,9 +151,9 @@ public:
// returns the result in a new queue. The original queue is not
// affected.
template <typename F>
- Queue * Map(F function) const {
- Queue * new_queue = new Queue();
- for (const QueueNode<E> * node = head_; node != NULL; node = node->next_) {
+ Queue* Map(F function) const {
+ Queue* new_queue = new Queue();
+ for (const QueueNode<E>* node = head_; node != NULL; node = node->next_) {
new_queue->Enqueue(function(node->element()));
}
@@ -161,13 +161,13 @@ public:
}
private:
- QueueNode<E> * head_; // The first node of the queue.
- QueueNode<E> * last_; // The last node of the queue.
+ QueueNode<E>* head_; // The first node of the queue.
+ QueueNode<E>* last_; // The last node of the queue.
size_t size_; // The number of elements in the queue.
// We disallow copying a queue.
- Queue(const Queue &);
- const Queue & operator = (const Queue &);
+ Queue(const Queue&);
+ const Queue& operator = (const Queue&);
};
#endif // GTEST_SAMPLES_SAMPLE3_INL_H_
diff --git a/gtest/samples/sample3_unittest.cc b/gtest/samples/sample3_unittest.cc
index a3d26da..34c1ca8 100644
--- a/gtest/samples/sample3_unittest.cc
+++ b/gtest/samples/sample3_unittest.cc
@@ -122,7 +122,7 @@ class QueueTest : public testing::Test {
// Tests the default c'tor.
TEST_F(QueueTest, DefaultConstructor) {
// You can access data in the test fixture here.
- EXPECT_EQ(0, q0_.Size());
+ EXPECT_EQ(0u, q0_.Size());
}
// Tests Dequeue().
@@ -133,13 +133,13 @@ TEST_F(QueueTest, Dequeue) {
n = q1_.Dequeue();
ASSERT_TRUE(n != NULL);
EXPECT_EQ(1, *n);
- EXPECT_EQ(0, q1_.Size());
+ EXPECT_EQ(0u, q1_.Size());
delete n;
n = q2_.Dequeue();
ASSERT_TRUE(n != NULL);
EXPECT_EQ(2, *n);
- EXPECT_EQ(1, q2_.Size());
+ EXPECT_EQ(1u, q2_.Size());
delete n;
}
diff --git a/gtest/samples/sample5_unittest.cc b/gtest/samples/sample5_unittest.cc
index be5df90..49dae7c 100644
--- a/gtest/samples/sample5_unittest.cc
+++ b/gtest/samples/sample5_unittest.cc
@@ -171,24 +171,24 @@ class QueueTest : public QuickTest {
// Tests the default constructor.
TEST_F(QueueTest, DefaultConstructor) {
- EXPECT_EQ(0, q0_.Size());
+ EXPECT_EQ(0u, q0_.Size());
}
// Tests Dequeue().
TEST_F(QueueTest, Dequeue) {
- int * n = q0_.Dequeue();
+ int* n = q0_.Dequeue();
EXPECT_TRUE(n == NULL);
n = q1_.Dequeue();
EXPECT_TRUE(n != NULL);
EXPECT_EQ(1, *n);
- EXPECT_EQ(0, q1_.Size());
+ EXPECT_EQ(0u, q1_.Size());
delete n;
n = q2_.Dequeue();
EXPECT_TRUE(n != NULL);
EXPECT_EQ(2, *n);
- EXPECT_EQ(1, q2_.Size());
+ EXPECT_EQ(1u, q2_.Size());
delete n;
}
diff --git a/gtest/samples/sample7_unittest.cc b/gtest/samples/sample7_unittest.cc
index b5d507a..f455282 100644
--- a/gtest/samples/sample7_unittest.cc
+++ b/gtest/samples/sample7_unittest.cc
@@ -121,12 +121,12 @@ INSTANTIATE_TEST_CASE_P(
#else
-// Google Test doesn't support value-parameterized tests on some platforms
-// and compilers, such as MSVC 7.1. If we use conditional compilation to
-// compile out all code referring to the gtest_main library, MSVC linker
-// will not link that library at all and consequently complain about
-// missing entry point defined in that library (fatal error LNK1561:
-// entry point must be defined). This dummy test keeps gtest_main linked in.
+// Google Test may not support value-parameterized tests with some
+// compilers. If we use conditional compilation to compile out all
+// code referring to the gtest_main library, MSVC linker will not link
+// that library at all and consequently complain about missing entry
+// point defined in that library (fatal error LNK1561: entry point
+// must be defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}
#endif // GTEST_HAS_PARAM_TEST
diff --git a/gtest/samples/sample8_unittest.cc b/gtest/samples/sample8_unittest.cc
index d76136a..ccf61d9 100644
--- a/gtest/samples/sample8_unittest.cc
+++ b/gtest/samples/sample8_unittest.cc
@@ -162,12 +162,12 @@ INSTANTIATE_TEST_CASE_P(MeaningfulTestParameters,
#else
-// Google Test doesn't support Combine() on some platforms and compilers,
-// such as MSVC 7.1. If we use conditional compilation to compile out
-// all code referring to the gtest_main library, MSVC linker will not
-// link that library at all and consequently complain about missing entry
-// point defined in that library (fatal error LNK1561: entry point must
-// be defined). This dummy test keeps gtest_main linked in.
+// Google Test may not support Combine() with some compilers. If we
+// use conditional compilation to compile out all code referring to
+// the gtest_main library, MSVC linker will not link that library at
+// all and consequently complain about missing entry point defined in
+// that library (fatal error LNK1561: entry point must be
+// defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, CombineIsNotSupportedOnThisPlatform) {}
#endif // GTEST_HAS_COMBINE
diff --git a/gtest/samples/sample9_unittest.cc b/gtest/samples/sample9_unittest.cc
index 8944c47..d828ef4 100644
--- a/gtest/samples/sample9_unittest.cc
+++ b/gtest/samples/sample9_unittest.cc
@@ -52,7 +52,7 @@ namespace {
class TersePrinter : public EmptyTestEventListener {
private:
// Called before any test activity starts.
- virtual void OnTestProgramStart(const UnitTest& unit_test) {}
+ virtual void OnTestProgramStart(const UnitTest& /* unit_test */) {}
// Called after all test activities have ended.
virtual void OnTestProgramEnd(const UnitTest& unit_test) {
diff --git a/gtest/scons/SConscript b/gtest/scons/SConscript
deleted file mode 100644
index 26fa5fb..0000000
--- a/gtest/scons/SConscript
+++ /dev/null
@@ -1,325 +0,0 @@
-# -*- Python -*-
-# Copyright 2008 Google Inc. All Rights Reserved.
-#
-# 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.
-
-
-"""Builds the Google Test (gtest) lib. This has been tested on Windows,
-Linux, Mac OS X, and Cygwin. The compilation settings from your project
-will be used, with some specific flags required for gtest added.
-
-You should be able to call this file from more or less any SConscript
-file.
-
-You can optionally set a variable on the construction environment to
-have the unit test executables copied to your output directory. The
-variable should be env['EXE_OUTPUT'].
-
-Another optional variable is env['LIB_OUTPUT']. If set, the generated
-libraries are copied to the folder indicated by the variable.
-
-If you place the gtest sources within your own project's source
-directory, you should be able to call this SConscript file simply as
-follows:
-
-# -- cut here --
-# Build gtest library; first tell it where to copy executables.
-env['EXE_OUTPUT'] = '#/mybuilddir/mybuildmode' # example, optional
-env['LIB_OUTPUT'] = '#/mybuilddir/mybuildmode/lib'
-env.SConscript('whateverpath/gtest/scons/SConscript')
-# -- cut here --
-
-If on the other hand you place the gtest sources in a directory
-outside of your project's source tree, you would use a snippet similar
-to the following:
-
-# -- cut here --
-
-# The following assumes that $BUILD_DIR refers to the root of the
-# directory for your current build mode, e.g. "#/mybuilddir/mybuildmode"
-
-# Build gtest library; as it is outside of our source root, we need to
-# tell SCons that the directory it will refer to as
-# e.g. $BUILD_DIR/gtest is actually on disk in original form as
-# ../../gtest (relative to your project root directory). Recall that
-# SCons by default copies all source files into the build directory
-# before building.
-gtest_dir = env.Dir('$BUILD_DIR/gtest')
-
-# Modify this part to point to gtest relative to the current
-# SConscript or SConstruct file's directory. The ../.. path would
-# be different per project, to locate the base directory for gtest.
-gtest_dir.addRepository(env.Dir('../../gtest'))
-
-# Tell the gtest SCons file where to copy executables.
-env['EXE_OUTPUT'] = '$BUILD_DIR' # example, optional
-
-# Call the gtest SConscript to build gtest.lib and unit tests. The
-# location of the library should end up as
-# '$BUILD_DIR/gtest/scons/gtest.lib'
-env.SConscript(env.File('scons/SConscript', gtest_dir))
-
-# -- cut here --
-"""
-
-
-__author__ = 'joi@google.com (Joi Sigurdsson)'
-
-
-import os
-
-############################################################
-# Environments for building the targets, sorted by name.
-
-Import('env', 'EnvCreator')
-
-env = EnvCreator.Create(env)
-
-# Note: The relative paths in SConscript files are relative to the location
-# of the SConscript file itself. To make a path relative to the location of
-# the main SConstruct file, prepend the path with the # sign.
-#
-# But if a project uses variant builds without source duplication, the above
-# rule gets muddied a bit. In that case the paths must be counted from the
-# location of the copy of the SConscript file in scons/build/<config>/scons.
-#
-# Include paths to gtest headers are relative to either the gtest
-# directory or the 'include' subdirectory of it, and this SConscript
-# file is one directory deeper than the gtest directory.
-env.Prepend(CPPPATH = ['..', '../include'])
-
-env_use_own_tuple = EnvCreator.Create(env, EnvCreator.UseOwnTuple)
-env_less_optimized = EnvCreator.Create(env, EnvCreator.LessOptimized)
-env_with_threads = EnvCreator.Create(env, EnvCreator.WithThreads)
-# The following environments are used to compile gtest_unittest.cc, which
-# triggers a warning in all but the most recent GCC versions when compiling
-# the EXPECT_EQ(NULL, ptr) statement.
-env_warning_ok = EnvCreator.Create(env, EnvCreator.WarningOk)
-env_with_exceptions = EnvCreator.Create(env_warning_ok,
- EnvCreator.WithExceptions)
-env_without_rtti = EnvCreator.Create(env_warning_ok, EnvCreator.NoRtti)
-
-############################################################
-# Helpers for creating build targets.
-
-# Caches object file targets built by GtestObject to allow passing the
-# same source file with the same environment twice into the function as a
-# convenience.
-_all_objects = {}
-
-def GtestObject(build_env, source):
- """Returns a target to build an object file from the given .cc source file."""
-
- object_name = os.path.basename(source).rstrip('.cc') + build_env['OBJ_SUFFIX']
- if object_name not in _all_objects:
- _all_objects[object_name] = build_env.Object(target=object_name,
- source=source)
- return _all_objects[object_name]
-
-
-def GtestStaticLibraries(build_env):
- """Builds static libraries for gtest and gtest_main in build_env.
-
- Args:
- build_env: An environment in which to build libraries.
-
- Returns:
- A pair (gtest library, gtest_main library) built in the given environment.
- """
-
- gtest_object = GtestObject(build_env, '../src/gtest-all.cc')
- gtest_main_object = GtestObject(build_env, '../src/gtest_main.cc')
-
- return (build_env.StaticLibrary(target='gtest' + build_env['OBJ_SUFFIX'],
- source=[gtest_object]),
- build_env.StaticLibrary(target='gtest_main' + build_env['OBJ_SUFFIX'],
- source=[gtest_object, gtest_main_object]))
-
-
-def GtestBinary(build_env, target, gtest_libs, sources):
- """Creates a target to build a binary (either test or sample).
-
- Args:
- build_env: The SCons construction environment to use to build.
- target: The basename of the target's main source file, also used as the
- target name.
- gtest_libs: The gtest library or the list of libraries to link.
- sources: A list of source files in the target.
- """
- srcs = [] # The object targets corresponding to sources.
- for src in sources:
- if type(src) is str:
- srcs.append(GtestObject(build_env, src))
- else:
- srcs.append(src)
-
- if not gtest_libs:
- gtest_libs = []
- elif type(gtest_libs) != type(list()):
- gtest_libs = [gtest_libs]
- binary = build_env.Program(target=target, source=srcs, LIBS=gtest_libs)
- if 'EXE_OUTPUT' in build_env.Dictionary():
- build_env.Install('$EXE_OUTPUT', source=[binary])
-
-
-def GtestTest(build_env, target, gtest_libs, additional_sources=None):
- """Creates a target to build the given test.
-
- Args:
- build_env: The SCons construction environment to use to build.
- target: The basename of the target test .cc file.
- gtest_libs: The gtest library or the list of libraries to use.
- additional_sources: A list of additional source files in the target.
- """
-
- GtestBinary(build_env, target, gtest_libs,
- ['../test/%s.cc' % target] + (additional_sources or []))
-
-
-def GtestSample(build_env, target, additional_sources=None):
- """Creates a target to build the given sample.
-
- Args:
- build_env: The SCons construction environment to use to build.
- target: The basename of the target sample .cc file.
- gtest_libs: The gtest library or the list of libraries to use.
- additional_sources: A list of additional source files in the target.
- """
- GtestBinary(build_env, target, gtest_main,
- ['../samples/%s.cc' % target] + (additional_sources or []))
-
-
-############################################################
-# Object and library targets.
-
-# gtest.lib to be used by most apps (if you have your own main function).
-# gtest_main.lib can be used if you just want a basic main function; it is also
-# used by some tests for Google Test itself.
-gtest, gtest_main = GtestStaticLibraries(env)
-gtest_ex, gtest_main_ex = GtestStaticLibraries(env_with_exceptions)
-gtest_no_rtti, gtest_main_no_rtti = GtestStaticLibraries(env_without_rtti)
-gtest_use_own_tuple, gtest_use_own_tuple_main = GtestStaticLibraries(
- env_use_own_tuple)
-
-# Install the libraries if needed.
-if 'LIB_OUTPUT' in env.Dictionary():
- env.Install('$LIB_OUTPUT', source=[gtest, gtest_main,
- gtest_ex, gtest_main_ex,
- gtest_no_rtti, gtest_main_no_rtti,
- gtest_use_own_tuple,
- gtest_use_own_tuple_main])
-
-############################################################
-# Test targets using the standard environment.
-
-GtestTest(env, 'gtest-filepath_test', gtest_main)
-GtestTest(env, 'gtest-message_test', gtest_main)
-GtestTest(env, 'gtest-options_test', gtest_main)
-GtestTest(env, 'gtest_environment_test', gtest)
-GtestTest(env, 'gtest_main_unittest', gtest_main)
-GtestTest(env, 'gtest_no_test_unittest', gtest)
-GtestTest(env, 'gtest_pred_impl_unittest', gtest_main)
-GtestTest(env, 'gtest_prod_test', gtest_main,
- additional_sources=['../test/production.cc'])
-GtestTest(env, 'gtest_repeat_test', gtest)
-GtestTest(env, 'gtest_sole_header_test', gtest_main)
-GtestTest(env, 'gtest-test-part_test', gtest_main)
-GtestTest(env, 'gtest-typed-test_test', gtest_main,
- additional_sources=['../test/gtest-typed-test2_test.cc'])
-GtestTest(env, 'gtest-param-test_test', gtest,
- additional_sources=['../test/gtest-param-test2_test.cc'])
-GtestTest(env, 'gtest_color_test_', gtest)
-GtestTest(env, 'gtest-linked_ptr_test', gtest_main)
-GtestTest(env, 'gtest-port_test', gtest_main)
-GtestTest(env, 'gtest_break_on_failure_unittest_', gtest)
-GtestTest(env, 'gtest_filter_unittest_', gtest)
-GtestTest(env, 'gtest_help_test_', gtest_main)
-GtestTest(env, 'gtest_list_tests_unittest_', gtest)
-GtestTest(env, 'gtest_throw_on_failure_test_', gtest)
-GtestTest(env, 'gtest_xml_outfile1_test_', gtest_main)
-GtestTest(env, 'gtest_xml_outfile2_test_', gtest_main)
-GtestTest(env, 'gtest_xml_output_unittest_', gtest)
-GtestTest(env, 'gtest-unittest-api_test', gtest)
-GtestTest(env, 'gtest-listener_test', gtest)
-GtestTest(env, 'gtest_shuffle_test_', gtest)
-
-############################################################
-# Tests targets using custom environments.
-
-GtestTest(env_warning_ok, 'gtest_unittest', gtest_main)
-GtestTest(env_with_exceptions, 'gtest_output_test_', gtest_ex)
-GtestTest(env_with_exceptions, 'gtest_throw_on_failure_ex_test', gtest_ex)
-GtestTest(env_with_threads, 'gtest-death-test_test', gtest_main)
-GtestTest(env_less_optimized, 'gtest_env_var_test_', gtest)
-GtestTest(env_less_optimized, 'gtest_uninitialized_test_', gtest)
-GtestTest(env_use_own_tuple, 'gtest-tuple_test', gtest_use_own_tuple_main)
-GtestBinary(env_use_own_tuple,
- 'gtest_use_own_tuple_test',
- gtest_use_own_tuple_main,
- ['../test/gtest-param-test_test.cc',
- '../test/gtest-param-test2_test.cc'])
-GtestBinary(env_with_exceptions, 'gtest_ex_unittest', gtest_main_ex,
- ['../test/gtest_unittest.cc'])
-GtestBinary(env_without_rtti, 'gtest_no_rtti_test', gtest_main_no_rtti,
- ['../test/gtest_unittest.cc'])
-
-############################################################
-# Sample targets.
-
-# Use the GTEST_BUILD_SAMPLES build variable to control building of samples.
-# In your SConstruct file, add
-# vars = Variables()
-# vars.Add(BoolVariable('GTEST_BUILD_SAMPLES', 'Build samples', False))
-# my_environment = Environment(variables = vars, ...)
-# Then, in the command line use GTEST_BUILD_SAMPLES=true to enable them.
-if env.get('GTEST_BUILD_SAMPLES', False):
- GtestSample(env, 'sample1_unittest',
- additional_sources=['../samples/sample1.cc'])
- GtestSample(env, 'sample2_unittest',
- additional_sources=['../samples/sample2.cc'])
- GtestSample(env, 'sample3_unittest')
- GtestSample(env, 'sample4_unittest',
- additional_sources=['../samples/sample4.cc'])
- GtestSample(env, 'sample5_unittest',
- additional_sources=['../samples/sample1.cc'])
- GtestSample(env, 'sample6_unittest')
- GtestSample(env, 'sample7_unittest')
- GtestSample(env, 'sample8_unittest')
- GtestSample(env, 'sample9_unittest')
- GtestSample(env, 'sample10_unittest')
-
-# These exports are used by Google Mock.
-gtest_exports = {'gtest': gtest,
- 'gtest_ex': gtest_ex,
- 'gtest_no_rtti': gtest_no_rtti,
- 'gtest_use_own_tuple': gtest_use_own_tuple,
- 'EnvCreator': EnvCreator,
- 'GtestObject': GtestObject,
- 'GtestBinary': GtestBinary,
- 'GtestTest': GtestTest}
-# Makes the gtest_exports dictionary available to the invoking SConstruct.
-Return('gtest_exports')
diff --git a/gtest/scons/SConstruct.common b/gtest/scons/SConstruct.common
deleted file mode 100644
index 2445beb..0000000
--- a/gtest/scons/SConstruct.common
+++ /dev/null
@@ -1,356 +0,0 @@
-# -*- Python -*-
-# Copyright 2008 Google Inc. All Rights Reserved.
-#
-# 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: joi@google.com (Joi Sigurdsson)
-# Author: vladl@google.com (Vlad Losev)
-#
-# Shared SCons utilities for building Google Test inside and outside of
-# Google's environment.
-#
-
-EnsurePythonVersion(2, 3)
-
-
-BUILD_DIR_PREFIX = 'build'
-
-
-class SConstructHelper:
- def __init__(self):
- # A dictionary to look up an environment by its name.
- self.env_dict = {}
-
- def Initialize(self, build_root_path, support_multiple_win_builds=False):
- test_env = Environment()
- platform = test_env['PLATFORM']
- if platform == 'win32':
- if support_multiple_win_builds:
- available_build_types = ['win-dbg8', 'win-opt8', 'win-dbg', 'win-opt']
- else:
- available_build_types = ['win-dbg', 'win-opt']
- elif platform == 'darwin': # MacOSX
- available_build_types = ['mac-dbg', 'mac-opt']
- else:
- available_build_types = ['dbg', 'opt'] # Assuming POSIX-like environment
- # with GCC by default.
-
- vars = Variables()
- vars.Add(ListVariable('BUILD', 'Build type', available_build_types[0],
- available_build_types))
- vars.Add(BoolVariable('GTEST_BUILD_SAMPLES', 'Build samples', False))
-
- # Create base environment.
- self.env_base = Environment(variables=vars,
- BUILD_MODE={'BUILD' : '"${BUILD}"'})
-
- # Leave around a variable pointing at the build root so that SConscript
- # files from outside our project root can find their bearings. Trick
- # borrowed from Hammer in Software Construction Toolkit
- # (http://code.google.com/p/swtoolkit/); if/when we switch to using the
- # Hammer idioms instead of just Hammer's version of SCons, we should be
- # able to remove this line.
- self.env_base['SOURCE_ROOT'] = self.env_base.Dir(build_root_path)
-
- # And another that definitely always points to the project root.
- self.env_base['PROJECT_ROOT'] = self.env_base.Dir('.').abspath
-
- # Enable scons -h
- Help(vars.GenerateHelpText(self.env_base))
-
- class EnvCreator:
- """Creates new customized environments from a base one."""
-
- def _Remove(cls, env, attribute, value):
- """Removes the given attribute value from the environment."""
-
- attribute_values = env[attribute]
- if value in attribute_values:
- attribute_values.remove(value)
- _Remove = classmethod(_Remove)
-
- def Create(cls, base_env, modifier=None):
- # User should NOT create more than one environment with the same
- # modifier (including None).
- env = base_env.Clone()
- if modifier:
- modifier(env)
- else:
- env['OBJ_SUFFIX'] = '' # Default suffix for unchanged environment.
- return env;
- Create = classmethod(Create)
-
- # Each of the following methods modifies the environment for a particular
- # purpose and can be used by clients for creating new environments. Each
- # one needs to set the OBJ_SUFFIX variable to a unique suffix to
- # differentiate targets built with that environment. Otherwise, SCons may
- # complain about same target built with different settings.
-
- def UseOwnTuple(cls, env):
- """Instructs Google Test to use its internal implementation of tuple."""
-
- env['OBJ_SUFFIX'] = '_use_own_tuple'
- env.Append(CPPDEFINES = 'GTEST_USE_OWN_TR1_TUPLE=1')
- UseOwnTuple = classmethod(UseOwnTuple)
-
- def WarningOk(cls, env):
- """Does not treat warnings as errors.
-
- Necessary for compiling gtest_unittest.cc, which triggers a gcc
- warning when testing EXPECT_EQ(NULL, ptr)."""
-
- env['OBJ_SUFFIX'] = '_warning_ok'
- if env['PLATFORM'] == 'win32':
- cls._Remove(env, 'CCFLAGS', '-WX')
- else:
- cls._Remove(env, 'CCFLAGS', '-Werror')
- WarningOk = classmethod(WarningOk)
-
- def WithExceptions(cls, env):
- """Re-enables exceptions."""
-
- env['OBJ_SUFFIX'] = '_ex'
- if env['PLATFORM'] == 'win32':
- env.Append(CCFLAGS=['/EHsc'])
- env.Append(CPPDEFINES='_HAS_EXCEPTIONS=1')
- # Undoes the _TYPEINFO_ hack, which is unnecessary and only creates
- # trouble when exceptions are enabled.
- cls._Remove(env, 'CPPDEFINES', '_TYPEINFO_')
- cls._Remove(env, 'CPPDEFINES', '_HAS_EXCEPTIONS=0')
- else:
- env.Append(CCFLAGS='-fexceptions')
- cls._Remove(env, 'CCFLAGS', '-fno-exceptions')
- WithExceptions = classmethod(WithExceptions)
-
- def LessOptimized(cls, env):
- """Disables certain optimizations on Windows.
-
- We need to disable some optimization flags for some tests on
- Windows; otherwise the redirection of stdout does not work
- (apparently because of a compiler bug)."""
-
- env['OBJ_SUFFIX'] = '_less_optimized'
- if env['PLATFORM'] == 'win32':
- for flag in ['/O1', '/Os', '/Og', '/Oy']:
- cls._Remove(env, 'LINKFLAGS', flag)
- LessOptimized = classmethod(LessOptimized)
-
- def WithThreads(cls, env):
- """Allows use of threads.
-
- Currently only enables pthreads under GCC."""
-
- env['OBJ_SUFFIX'] = '_with_threads'
- if env['PLATFORM'] != 'win32':
- # Assuming POSIX-like environment with GCC.
- # TODO(vladl@google.com): sniff presence of pthread_atfork instead of
- # selecting on a platform.
- env.Append(CCFLAGS=['-pthread'])
- env.Append(LINKFLAGS=['-pthread'])
- WithThreads = classmethod(WithThreads)
-
- def NoRtti(cls, env):
- """Disables RTTI support."""
-
- env['OBJ_SUFFIX'] = '_no_rtti'
- if env['PLATFORM'] == 'win32':
- env.Append(CCFLAGS=['/GR-'])
- else:
- env.Append(CCFLAGS=['-fno-rtti'])
- env.Append(CPPDEFINES='GTEST_HAS_RTTI=0')
- NoRtti = classmethod(NoRtti)
-
- def AllowVc71StlWithoutExceptions(self, env):
- env.Append(
- CPPDEFINES = [# needed for using some parts of STL with exception
- # disabled. The scoop is given here, with comments
- # from P.J. Plauger at
- # http://groups.google.com/group/microsoft.public.vc.stl/browse_thread/thread/5e719833c6bdb177?q=_HAS_EXCEPTIONS+using+namespace+std&pli=1
- '_TYPEINFO_'])
-
- def MakeWinBaseEnvironment(self):
- win_base = self.env_base.Clone(
- platform='win32',
- CCFLAGS=['-GS', # Enable buffer security check
- '-W4', # Warning level
-
- # Disables warnings that are either uninteresting or
- # hard to fix.
-
- '-WX', # Treat warning as errors
- #'-GR-', # Disable runtime type information
- '-RTCs', # Enable stack-frame run-time error checks
- '-RTCu', # Report when variable used without init.
- #'-EHs', # enable C++ EH (no SEH exceptions)
- '-nologo', # Suppress logo line
- '-J', # All chars unsigned
- #'-Wp64', # Detect 64-bit portability issues. This
- # flag has been deprecated by VS 2008.
- '-Zi', # Produce debug information in PDB files.
- ],
- CCPDBFLAGS='',
- CPPDEFINES=['_UNICODE', 'UNICODE',
- 'WIN32', '_WIN32',
- 'STRICT',
- 'WIN32_LEAN_AND_MEAN',
- '_HAS_EXCEPTIONS=0',
- ],
- LIBPATH=['#/$MAIN_DIR/lib'],
- LINKFLAGS=['-MACHINE:x86', # Enable safe SEH (not supp. on x64)
- '-DEBUG', # Generate debug info
- '-NOLOGO', # Suppress logo line
- ],
- # All strings in string tables zero terminated.
- RCFLAGS=['-n'])
-
- return win_base
-
- def SetBuildNameAndDir(self, env, name):
- env['BUILD_NAME'] = name;
- env['BUILD_DIR'] = '%s/%s' % (BUILD_DIR_PREFIX, name)
- self.env_dict[name] = env
-
- def MakeWinDebugEnvironment(self, base_environment, name):
- """Takes a VC71 or VC80 base environment and adds debug settings."""
- debug_env = base_environment.Clone()
- self.SetBuildNameAndDir(debug_env, name)
- debug_env.Append(
- CCFLAGS = ['-Od', # Disable optimizations
- '-MTd', # Multithreaded, static link (debug)
- # Path for PDB files
- '-Fd%s\\' % debug_env.Dir(debug_env['BUILD_DIR']),
- ],
- CPPDEFINES = ['DEBUG',
- '_DEBUG',
- ],
- LIBPATH = [],
- LINKFLAGS = ['-INCREMENTAL:yes',
- '/OPT:NOICF',
- ]
- )
- return debug_env
-
- def MakeWinOptimizedEnvironment(self, base_environment, name):
- """Takes a VC71 or VC80 base environment and adds release settings."""
- optimized_env = base_environment.Clone()
- self.SetBuildNameAndDir(optimized_env, name)
- optimized_env.Append(
- CCFLAGS = ['-GL', # Enable link-time code generation (/GL)
- '-GF', # Enable String Pooling (/GF)
- '-MT', # Multithreaded, static link
- # Path for PDB files
- '-Fd%s\\' % optimized_env.Dir(optimized_env['BUILD_DIR']),
-
- # Favor small code (this is /O1 minus /Og)
- '-Os',
- '-Oy',
- '-Ob2',
- '-Gs',
- '-GF',
- '-Gy',
- ],
- CPPDEFINES = ['NDEBUG',
- '_NDEBUG',
- ],
- LIBPATH = [],
- ARFLAGS = ['-LTCG'], # Link-time Code Generation
- LINKFLAGS = ['-LTCG', # Link-time Code Generation
- '-OPT:REF', # Optimize by reference.
- '-OPT:ICF=32', # Optimize by identical COMDAT folding
- '-OPT:NOWIN98', # Optimize by not aligning section for
- # Win98
- '-INCREMENTAL:NO', # No incremental linking as we don't
- # want padding bytes in release build.
- ],
- )
- return optimized_env
-
- def AddGccFlagsTo(self, env, optimized):
- env.Append(CCFLAGS=['-fno-exceptions',
- '-Wall',
- '-Werror',
- ])
- if optimized:
- env.Append(CCFLAGS=['-O2'], CPPDEFINES=['NDEBUG', '_NDEBUG'])
- else:
- env.Append(CCFLAGS=['-g'], CPPDEFINES=['DEBUG', '_DEBUG'])
-
- def ConfigureGccEnvironments(self):
- # Mac environments.
- mac_base = self.env_base.Clone(platform='darwin')
-
- mac_dbg = mac_base.Clone()
- self.AddGccFlagsTo(mac_dbg, optimized=False)
- self.SetBuildNameAndDir(mac_dbg, 'mac-dbg')
-
- mac_opt = mac_base.Clone()
- self.AddGccFlagsTo(mac_opt, optimized=True)
- self.SetBuildNameAndDir(mac_opt, 'mac-opt')
-
- # Generic GCC environments.
- gcc_dbg = self.env_base.Clone()
- self.AddGccFlagsTo(gcc_dbg, optimized=False)
- self.SetBuildNameAndDir(gcc_dbg, 'dbg')
-
- gcc_opt = self.env_base.Clone()
- self.AddGccFlagsTo(gcc_opt, optimized=True)
- self.SetBuildNameAndDir(gcc_opt, 'opt')
-
- def BuildSelectedEnvironments(self):
- EnvCreator = SConstructHelper.EnvCreator
- Export('EnvCreator')
- # Build using whichever environments the 'BUILD' option selected
- for build_name in self.env_base['BUILD']:
- print 'BUILDING %s' % build_name
- env = self.env_dict[build_name]
-
- # Make sure SConscript files can refer to base build dir
- env['MAIN_DIR'] = env.Dir(env['BUILD_DIR'])
-
- #print 'CCFLAGS: %s' % env.subst('$CCFLAGS')
- #print 'LINK: %s' % env.subst('$LINK')
- #print 'AR: %s' % env.subst('$AR')
- #print 'CC: %s' % env.subst('$CC')
- #print 'CXX: %s' % env.subst('$CXX')
- #print 'LIBPATH: %s' % env.subst('$LIBPATH')
- #print 'ENV:PATH: %s' % env['ENV']['PATH']
- #print 'ENV:INCLUDE: %s' % env['ENV']['INCLUDE']
- #print 'ENV:LIB: %s' % env['ENV']['LIB']
- #print 'ENV:TEMP: %s' % env['ENV']['TEMP']
-
- Export('env')
- # Invokes SConscript with variant_dir being build/<config name>.
- # Counter-intuitively, src_dir is relative to the build dir and has
- # to be '..' to point to the scons directory.
- SConscript('SConscript',
- src_dir='..',
- variant_dir=env['BUILD_DIR'],
- duplicate=0)
-
-
-sconstruct_helper = SConstructHelper()
-Return('sconstruct_helper')
diff --git a/gtest/scripts/gtest-config.in b/gtest/scripts/gtest-config.in
index b82d5a1..9c72638 100755
--- a/gtest/scripts/gtest-config.in
+++ b/gtest/scripts/gtest-config.in
@@ -214,7 +214,7 @@ if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
# TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we
# should work to remove it, and/or remove libtool altogether, replacing it
# with direct references to the library and a link path.
- gtest_libs="${build_dir}/lib/libgtest.la"
+ gtest_libs="${build_dir}/lib/libgtest.la @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
gtest_ldflags=""
# We provide hooks to include from either the source or build dir, where the
@@ -222,15 +222,15 @@ if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
# build rules for generated headers and have them automatically be preferred
# over provided versions.
gtest_cppflags="-I${build_dir}/include -I${src_dir}/include"
- gtest_cxxflags=""
+ gtest_cxxflags="@PTHREAD_CFLAGS@"
else
# We're using an installed gtest, although it may be staged under some
# prefix. Assume (as our own libraries do) that we can resolve the prefix,
# and are present in the dynamic link paths.
gtest_ldflags="-L${libdir}"
- gtest_libs="-l${name}"
+ gtest_libs="-l${name} @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
gtest_cppflags="-I${includedir}"
- gtest_cxxflags=""
+ gtest_cxxflags="@PTHREAD_CFLAGS@"
fi
# Do an installation query if requested.
diff --git a/gtest/scripts/pump.py b/gtest/scripts/pump.py
new file mode 100755
index 0000000..f15c1b6
--- /dev/null
+++ b/gtest/scripts/pump.py
@@ -0,0 +1,835 @@
+#!/usr/bin/env python
+#
+# Copyright 2008, Google Inc.
+# All rights reserved.
+#
+# 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.
+
+"""pump v0.1 - Pretty Useful for Meta Programming.
+
+A tool for preprocessor meta programming. Useful for generating
+repetitive boilerplate code. Especially useful for writing C++
+classes, functions, macros, and templates that need to work with
+various number of arguments.
+
+USAGE:
+ pump.py SOURCE_FILE
+
+EXAMPLES:
+ pump.py foo.cc.pump
+ Converts foo.cc.pump to foo.cc.
+
+GRAMMAR:
+ CODE ::= ATOMIC_CODE*
+ ATOMIC_CODE ::= $var ID = EXPRESSION
+ | $var ID = [[ CODE ]]
+ | $range ID EXPRESSION..EXPRESSION
+ | $for ID SEPARATOR [[ CODE ]]
+ | $($)
+ | $ID
+ | $(EXPRESSION)
+ | $if EXPRESSION [[ CODE ]] ELSE_BRANCH
+ | [[ CODE ]]
+ | RAW_CODE
+ SEPARATOR ::= RAW_CODE | EMPTY
+ ELSE_BRANCH ::= $else [[ CODE ]]
+ | $elif EXPRESSION [[ CODE ]] ELSE_BRANCH
+ | EMPTY
+ EXPRESSION has Python syntax.
+"""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import os
+import re
+import sys
+
+
+TOKEN_TABLE = [
+ (re.compile(r'\$var\s+'), '$var'),
+ (re.compile(r'\$elif\s+'), '$elif'),
+ (re.compile(r'\$else\s+'), '$else'),
+ (re.compile(r'\$for\s+'), '$for'),
+ (re.compile(r'\$if\s+'), '$if'),
+ (re.compile(r'\$range\s+'), '$range'),
+ (re.compile(r'\$[_A-Za-z]\w*'), '$id'),
+ (re.compile(r'\$\(\$\)'), '$($)'),
+ (re.compile(r'\$\$.*'), '$$'),
+ (re.compile(r'\$'), '$'),
+ (re.compile(r'\[\[\n?'), '[['),
+ (re.compile(r'\]\]\n?'), ']]'),
+ ]
+
+
+class Cursor:
+ """Represents a position (line and column) in a text file."""
+
+ def __init__(self, line=-1, column=-1):
+ self.line = line
+ self.column = column
+
+ def __eq__(self, rhs):
+ return self.line == rhs.line and self.column == rhs.column
+
+ def __ne__(self, rhs):
+ return not self == rhs
+
+ def __lt__(self, rhs):
+ return self.line < rhs.line or (
+ self.line == rhs.line and self.column < rhs.column)
+
+ def __le__(self, rhs):
+ return self < rhs or self == rhs
+
+ def __gt__(self, rhs):
+ return rhs < self
+
+ def __ge__(self, rhs):
+ return rhs <= self
+
+ def __str__(self):
+ if self == Eof():
+ return 'EOF'
+ else:
+ return '%s(%s)' % (self.line + 1, self.column)
+
+ def __add__(self, offset):
+ return Cursor(self.line, self.column + offset)
+
+ def __sub__(self, offset):
+ return Cursor(self.line, self.column - offset)
+
+ def Clone(self):
+ """Returns a copy of self."""
+
+ return Cursor(self.line, self.column)
+
+
+# Special cursor to indicate the end-of-file.
+def Eof():
+ """Returns the special cursor to denote the end-of-file."""
+ return Cursor(-1, -1)
+
+
+class Token:
+ """Represents a token in a Pump source file."""
+
+ def __init__(self, start=None, end=None, value=None, token_type=None):
+ if start is None:
+ self.start = Eof()
+ else:
+ self.start = start
+ if end is None:
+ self.end = Eof()
+ else:
+ self.end = end
+ self.value = value
+ self.token_type = token_type
+
+ def __str__(self):
+ return 'Token @%s: \'%s\' type=%s' % (
+ self.start, self.value, self.token_type)
+
+ def Clone(self):
+ """Returns a copy of self."""
+
+ return Token(self.start.Clone(), self.end.Clone(), self.value,
+ self.token_type)
+
+
+def StartsWith(lines, pos, string):
+ """Returns True iff the given position in lines starts with 'string'."""
+
+ return lines[pos.line][pos.column:].startswith(string)
+
+
+def FindFirstInLine(line, token_table):
+ best_match_start = -1
+ for (regex, token_type) in token_table:
+ m = regex.search(line)
+ if m:
+ # We found regex in lines
+ if best_match_start < 0 or m.start() < best_match_start:
+ best_match_start = m.start()
+ best_match_length = m.end() - m.start()
+ best_match_token_type = token_type
+
+ if best_match_start < 0:
+ return None
+
+ return (best_match_start, best_match_length, best_match_token_type)
+
+
+def FindFirst(lines, token_table, cursor):
+ """Finds the first occurrence of any string in strings in lines."""
+
+ start = cursor.Clone()
+ cur_line_number = cursor.line
+ for line in lines[start.line:]:
+ if cur_line_number == start.line:
+ line = line[start.column:]
+ m = FindFirstInLine(line, token_table)
+ if m:
+ # We found a regex in line.
+ (start_column, length, token_type) = m
+ if cur_line_number == start.line:
+ start_column += start.column
+ found_start = Cursor(cur_line_number, start_column)
+ found_end = found_start + length
+ return MakeToken(lines, found_start, found_end, token_type)
+ cur_line_number += 1
+ # We failed to find str in lines
+ return None
+
+
+def SubString(lines, start, end):
+ """Returns a substring in lines."""
+
+ if end == Eof():
+ end = Cursor(len(lines) - 1, len(lines[-1]))
+
+ if start >= end:
+ return ''
+
+ if start.line == end.line:
+ return lines[start.line][start.column:end.column]
+
+ result_lines = ([lines[start.line][start.column:]] +
+ lines[start.line + 1:end.line] +
+ [lines[end.line][:end.column]])
+ return ''.join(result_lines)
+
+
+def MakeToken(lines, start, end, token_type):
+ """Creates a new instance of Token."""
+
+ return Token(start, end, SubString(lines, start, end), token_type)
+
+
+def ParseToken(lines, pos, regex, token_type):
+ line = lines[pos.line][pos.column:]
+ m = regex.search(line)
+ if m and not m.start():
+ return MakeToken(lines, pos, pos + m.end(), token_type)
+ else:
+ print 'ERROR: %s expected at %s.' % (token_type, pos)
+ sys.exit(1)
+
+
+ID_REGEX = re.compile(r'[_A-Za-z]\w*')
+EQ_REGEX = re.compile(r'=')
+REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)')
+OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*')
+WHITE_SPACE_REGEX = re.compile(r'\s')
+DOT_DOT_REGEX = re.compile(r'\.\.')
+
+
+def Skip(lines, pos, regex):
+ line = lines[pos.line][pos.column:]
+ m = re.search(regex, line)
+ if m and not m.start():
+ return pos + m.end()
+ else:
+ return pos
+
+
+def SkipUntil(lines, pos, regex, token_type):
+ line = lines[pos.line][pos.column:]
+ m = re.search(regex, line)
+ if m:
+ return pos + m.start()
+ else:
+ print ('ERROR: %s expected on line %s after column %s.' %
+ (token_type, pos.line + 1, pos.column))
+ sys.exit(1)
+
+
+def ParseExpTokenInParens(lines, pos):
+ def ParseInParens(pos):
+ pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX)
+ pos = Skip(lines, pos, r'\(')
+ pos = Parse(pos)
+ pos = Skip(lines, pos, r'\)')
+ return pos
+
+ def Parse(pos):
+ pos = SkipUntil(lines, pos, r'\(|\)', ')')
+ if SubString(lines, pos, pos + 1) == '(':
+ pos = Parse(pos + 1)
+ pos = Skip(lines, pos, r'\)')
+ return Parse(pos)
+ else:
+ return pos
+
+ start = pos.Clone()
+ pos = ParseInParens(pos)
+ return MakeToken(lines, start, pos, 'exp')
+
+
+def RStripNewLineFromToken(token):
+ if token.value.endswith('\n'):
+ return Token(token.start, token.end, token.value[:-1], token.token_type)
+ else:
+ return token
+
+
+def TokenizeLines(lines, pos):
+ while True:
+ found = FindFirst(lines, TOKEN_TABLE, pos)
+ if not found:
+ yield MakeToken(lines, pos, Eof(), 'code')
+ return
+
+ if found.start == pos:
+ prev_token = None
+ prev_token_rstripped = None
+ else:
+ prev_token = MakeToken(lines, pos, found.start, 'code')
+ prev_token_rstripped = RStripNewLineFromToken(prev_token)
+
+ if found.token_type == '$$': # A meta comment.
+ if prev_token_rstripped:
+ yield prev_token_rstripped
+ pos = Cursor(found.end.line + 1, 0)
+ elif found.token_type == '$var':
+ if prev_token_rstripped:
+ yield prev_token_rstripped
+ yield found
+ id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
+ yield id_token
+ pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
+
+ eq_token = ParseToken(lines, pos, EQ_REGEX, '=')
+ yield eq_token
+ pos = Skip(lines, eq_token.end, r'\s*')
+
+ if SubString(lines, pos, pos + 2) != '[[':
+ exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp')
+ yield exp_token
+ pos = Cursor(exp_token.end.line + 1, 0)
+ elif found.token_type == '$for':
+ if prev_token_rstripped:
+ yield prev_token_rstripped
+ yield found
+ id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
+ yield id_token
+ pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX)
+ elif found.token_type == '$range':
+ if prev_token_rstripped:
+ yield prev_token_rstripped
+ yield found
+ id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
+ yield id_token
+ pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
+
+ dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..')
+ yield MakeToken(lines, pos, dots_pos, 'exp')
+ yield MakeToken(lines, dots_pos, dots_pos + 2, '..')
+ pos = dots_pos + 2
+ new_pos = Cursor(pos.line + 1, 0)
+ yield MakeToken(lines, pos, new_pos, 'exp')
+ pos = new_pos
+ elif found.token_type == '$':
+ if prev_token:
+ yield prev_token
+ yield found
+ exp_token = ParseExpTokenInParens(lines, found.end)
+ yield exp_token
+ pos = exp_token.end
+ elif (found.token_type == ']]' or found.token_type == '$if' or
+ found.token_type == '$elif' or found.token_type == '$else'):
+ if prev_token_rstripped:
+ yield prev_token_rstripped
+ yield found
+ pos = found.end
+ else:
+ if prev_token:
+ yield prev_token
+ yield found
+ pos = found.end
+
+
+def Tokenize(s):
+ lines = s.splitlines(True)
+ return TokenizeLines(lines, Cursor(0, 0))
+
+
+class CodeNode:
+ def __init__(self, atomic_code_list=None):
+ self.atomic_code = atomic_code_list
+
+
+class VarNode:
+ def __init__(self, identifier=None, atomic_code=None):
+ self.identifier = identifier
+ self.atomic_code = atomic_code
+
+
+class RangeNode:
+ def __init__(self, identifier=None, exp1=None, exp2=None):
+ self.identifier = identifier
+ self.exp1 = exp1
+ self.exp2 = exp2
+
+
+class ForNode:
+ def __init__(self, identifier=None, sep=None, code=None):
+ self.identifier = identifier
+ self.sep = sep
+ self.code = code
+
+
+class ElseNode:
+ def __init__(self, else_branch=None):
+ self.else_branch = else_branch
+
+
+class IfNode:
+ def __init__(self, exp=None, then_branch=None, else_branch=None):
+ self.exp = exp
+ self.then_branch = then_branch
+ self.else_branch = else_branch
+
+
+class RawCodeNode:
+ def __init__(self, token=None):
+ self.raw_code = token
+
+
+class LiteralDollarNode:
+ def __init__(self, token):
+ self.token = token
+
+
+class ExpNode:
+ def __init__(self, token, python_exp):
+ self.token = token
+ self.python_exp = python_exp
+
+
+def PopFront(a_list):
+ head = a_list[0]
+ a_list[:1] = []
+ return head
+
+
+def PushFront(a_list, elem):
+ a_list[:0] = [elem]
+
+
+def PopToken(a_list, token_type=None):
+ token = PopFront(a_list)
+ if token_type is not None and token.token_type != token_type:
+ print 'ERROR: %s expected at %s' % (token_type, token.start)
+ print 'ERROR: %s found instead' % (token,)
+ sys.exit(1)
+
+ return token
+
+
+def PeekToken(a_list):
+ if not a_list:
+ return None
+
+ return a_list[0]
+
+
+def ParseExpNode(token):
+ python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value)
+ return ExpNode(token, python_exp)
+
+
+def ParseElseNode(tokens):
+ def Pop(token_type=None):
+ return PopToken(tokens, token_type)
+
+ next = PeekToken(tokens)
+ if not next:
+ return None
+ if next.token_type == '$else':
+ Pop('$else')
+ Pop('[[')
+ code_node = ParseCodeNode(tokens)
+ Pop(']]')
+ return code_node
+ elif next.token_type == '$elif':
+ Pop('$elif')
+ exp = Pop('code')
+ Pop('[[')
+ code_node = ParseCodeNode(tokens)
+ Pop(']]')
+ inner_else_node = ParseElseNode(tokens)
+ return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)])
+ elif not next.value.strip():
+ Pop('code')
+ return ParseElseNode(tokens)
+ else:
+ return None
+
+
+def ParseAtomicCodeNode(tokens):
+ def Pop(token_type=None):
+ return PopToken(tokens, token_type)
+
+ head = PopFront(tokens)
+ t = head.token_type
+ if t == 'code':
+ return RawCodeNode(head)
+ elif t == '$var':
+ id_token = Pop('id')
+ Pop('=')
+ next = PeekToken(tokens)
+ if next.token_type == 'exp':
+ exp_token = Pop()
+ return VarNode(id_token, ParseExpNode(exp_token))
+ Pop('[[')
+ code_node = ParseCodeNode(tokens)
+ Pop(']]')
+ return VarNode(id_token, code_node)
+ elif t == '$for':
+ id_token = Pop('id')
+ next_token = PeekToken(tokens)
+ if next_token.token_type == 'code':
+ sep_token = next_token
+ Pop('code')
+ else:
+ sep_token = None
+ Pop('[[')
+ code_node = ParseCodeNode(tokens)
+ Pop(']]')
+ return ForNode(id_token, sep_token, code_node)
+ elif t == '$if':
+ exp_token = Pop('code')
+ Pop('[[')
+ code_node = ParseCodeNode(tokens)
+ Pop(']]')
+ else_node = ParseElseNode(tokens)
+ return IfNode(ParseExpNode(exp_token), code_node, else_node)
+ elif t == '$range':
+ id_token = Pop('id')
+ exp1_token = Pop('exp')
+ Pop('..')
+ exp2_token = Pop('exp')
+ return RangeNode(id_token, ParseExpNode(exp1_token),
+ ParseExpNode(exp2_token))
+ elif t == '$id':
+ return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id'))
+ elif t == '$($)':
+ return LiteralDollarNode(head)
+ elif t == '$':
+ exp_token = Pop('exp')
+ return ParseExpNode(exp_token)
+ elif t == '[[':
+ code_node = ParseCodeNode(tokens)
+ Pop(']]')
+ return code_node
+ else:
+ PushFront(tokens, head)
+ return None
+
+
+def ParseCodeNode(tokens):
+ atomic_code_list = []
+ while True:
+ if not tokens:
+ break
+ atomic_code_node = ParseAtomicCodeNode(tokens)
+ if atomic_code_node:
+ atomic_code_list.append(atomic_code_node)
+ else:
+ break
+ return CodeNode(atomic_code_list)
+
+
+def Convert(file_path):
+ s = file(file_path, 'r').read()
+ tokens = []
+ for token in Tokenize(s):
+ tokens.append(token)
+ code_node = ParseCodeNode(tokens)
+ return code_node
+
+
+class Env:
+ def __init__(self):
+ self.variables = []
+ self.ranges = []
+
+ def Clone(self):
+ clone = Env()
+ clone.variables = self.variables[:]
+ clone.ranges = self.ranges[:]
+ return clone
+
+ def PushVariable(self, var, value):
+ # If value looks like an int, store it as an int.
+ try:
+ int_value = int(value)
+ if ('%s' % int_value) == value:
+ value = int_value
+ except Exception:
+ pass
+ self.variables[:0] = [(var, value)]
+
+ def PopVariable(self):
+ self.variables[:1] = []
+
+ def PushRange(self, var, lower, upper):
+ self.ranges[:0] = [(var, lower, upper)]
+
+ def PopRange(self):
+ self.ranges[:1] = []
+
+ def GetValue(self, identifier):
+ for (var, value) in self.variables:
+ if identifier == var:
+ return value
+
+ print 'ERROR: meta variable %s is undefined.' % (identifier,)
+ sys.exit(1)
+
+ def EvalExp(self, exp):
+ try:
+ result = eval(exp.python_exp)
+ except Exception, e:
+ print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e)
+ print ('ERROR: failed to evaluate meta expression %s at %s' %
+ (exp.python_exp, exp.token.start))
+ sys.exit(1)
+ return result
+
+ def GetRange(self, identifier):
+ for (var, lower, upper) in self.ranges:
+ if identifier == var:
+ return (lower, upper)
+
+ print 'ERROR: range %s is undefined.' % (identifier,)
+ sys.exit(1)
+
+
+class Output:
+ def __init__(self):
+ self.string = ''
+
+ def GetLastLine(self):
+ index = self.string.rfind('\n')
+ if index < 0:
+ return ''
+
+ return self.string[index + 1:]
+
+ def Append(self, s):
+ self.string += s
+
+
+def RunAtomicCode(env, node, output):
+ if isinstance(node, VarNode):
+ identifier = node.identifier.value.strip()
+ result = Output()
+ RunAtomicCode(env.Clone(), node.atomic_code, result)
+ value = result.string
+ env.PushVariable(identifier, value)
+ elif isinstance(node, RangeNode):
+ identifier = node.identifier.value.strip()
+ lower = int(env.EvalExp(node.exp1))
+ upper = int(env.EvalExp(node.exp2))
+ env.PushRange(identifier, lower, upper)
+ elif isinstance(node, ForNode):
+ identifier = node.identifier.value.strip()
+ if node.sep is None:
+ sep = ''
+ else:
+ sep = node.sep.value
+ (lower, upper) = env.GetRange(identifier)
+ for i in range(lower, upper + 1):
+ new_env = env.Clone()
+ new_env.PushVariable(identifier, i)
+ RunCode(new_env, node.code, output)
+ if i != upper:
+ output.Append(sep)
+ elif isinstance(node, RawCodeNode):
+ output.Append(node.raw_code.value)
+ elif isinstance(node, IfNode):
+ cond = env.EvalExp(node.exp)
+ if cond:
+ RunCode(env.Clone(), node.then_branch, output)
+ elif node.else_branch is not None:
+ RunCode(env.Clone(), node.else_branch, output)
+ elif isinstance(node, ExpNode):
+ value = env.EvalExp(node)
+ output.Append('%s' % (value,))
+ elif isinstance(node, LiteralDollarNode):
+ output.Append('$')
+ elif isinstance(node, CodeNode):
+ RunCode(env.Clone(), node, output)
+ else:
+ print 'BAD'
+ print node
+ sys.exit(1)
+
+
+def RunCode(env, code_node, output):
+ for atomic_code in code_node.atomic_code:
+ RunAtomicCode(env, atomic_code, output)
+
+
+def IsComment(cur_line):
+ return '//' in cur_line
+
+
+def IsInPreprocessorDirevative(prev_lines, cur_line):
+ if cur_line.lstrip().startswith('#'):
+ return True
+ return prev_lines != [] and prev_lines[-1].endswith('\\')
+
+
+def WrapComment(line, output):
+ loc = line.find('//')
+ before_comment = line[:loc].rstrip()
+ if before_comment == '':
+ indent = loc
+ else:
+ output.append(before_comment)
+ indent = len(before_comment) - len(before_comment.lstrip())
+ prefix = indent*' ' + '// '
+ max_len = 80 - len(prefix)
+ comment = line[loc + 2:].strip()
+ segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != '']
+ cur_line = ''
+ for seg in segs:
+ if len((cur_line + seg).rstrip()) < max_len:
+ cur_line += seg
+ else:
+ if cur_line.strip() != '':
+ output.append(prefix + cur_line.rstrip())
+ cur_line = seg.lstrip()
+ if cur_line.strip() != '':
+ output.append(prefix + cur_line.strip())
+
+
+def WrapCode(line, line_concat, output):
+ indent = len(line) - len(line.lstrip())
+ prefix = indent*' ' # Prefix of the current line
+ max_len = 80 - indent - len(line_concat) # Maximum length of the current line
+ new_prefix = prefix + 4*' ' # Prefix of a continuation line
+ new_max_len = max_len - 4 # Maximum length of a continuation line
+ # Prefers to wrap a line after a ',' or ';'.
+ segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != '']
+ cur_line = '' # The current line without leading spaces.
+ for seg in segs:
+ # If the line is still too long, wrap at a space.
+ while cur_line == '' and len(seg.strip()) > max_len:
+ seg = seg.lstrip()
+ split_at = seg.rfind(' ', 0, max_len)
+ output.append(prefix + seg[:split_at].strip() + line_concat)
+ seg = seg[split_at + 1:]
+ prefix = new_prefix
+ max_len = new_max_len
+
+ if len((cur_line + seg).rstrip()) < max_len:
+ cur_line = (cur_line + seg).lstrip()
+ else:
+ output.append(prefix + cur_line.rstrip() + line_concat)
+ prefix = new_prefix
+ max_len = new_max_len
+ cur_line = seg.lstrip()
+ if cur_line.strip() != '':
+ output.append(prefix + cur_line.strip())
+
+
+def WrapPreprocessorDirevative(line, output):
+ WrapCode(line, ' \\', output)
+
+
+def WrapPlainCode(line, output):
+ WrapCode(line, '', output)
+
+
+def IsHeaderGuardOrInclude(line):
+ return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or
+ re.match(r'^#include\s', line))
+
+
+def WrapLongLine(line, output):
+ line = line.rstrip()
+ if len(line) <= 80:
+ output.append(line)
+ elif IsComment(line):
+ if IsHeaderGuardOrInclude(line):
+ # The style guide made an exception to allow long header guard lines
+ # and includes.
+ output.append(line)
+ else:
+ WrapComment(line, output)
+ elif IsInPreprocessorDirevative(output, line):
+ if IsHeaderGuardOrInclude(line):
+ # The style guide made an exception to allow long header guard lines
+ # and includes.
+ output.append(line)
+ else:
+ WrapPreprocessorDirevative(line, output)
+ else:
+ WrapPlainCode(line, output)
+
+
+def BeautifyCode(string):
+ lines = string.splitlines()
+ output = []
+ for line in lines:
+ WrapLongLine(line, output)
+ output2 = [line.rstrip() for line in output]
+ return '\n'.join(output2) + '\n'
+
+
+def main(argv):
+ if len(argv) == 1:
+ print __doc__
+ sys.exit(1)
+
+ file_path = argv[-1]
+ ast = Convert(file_path)
+ output = Output()
+ RunCode(Env(), ast, output)
+ output_str = BeautifyCode(output.string)
+ if file_path.endswith('.pump'):
+ output_file_path = file_path[:-5]
+ else:
+ output_file_path = '-'
+ if output_file_path == '-':
+ print output_str,
+ else:
+ output_file = file(output_file_path, 'w')
+ output_file.write('// This file was GENERATED by command:\n')
+ output_file.write('// %s %s\n' %
+ (os.path.basename(__file__), os.path.basename(file_path)))
+ output_file.write('// DO NOT EDIT BY HAND!!!\n\n')
+ output_file.write(output_str)
+ output_file.close()
+
+
+if __name__ == '__main__':
+ main(sys.argv)
diff --git a/gtest/src/gtest-all.cc b/gtest/src/gtest-all.cc
index a67ea0f..fe34765 100644
--- a/gtest/src/gtest-all.cc
+++ b/gtest/src/gtest-all.cc
@@ -33,6 +33,12 @@
//
// Sometimes it's desirable to build Google Test by compiling a single file.
// This file serves this purpose.
+
+// This line ensures that gtest.h can be compiled on its own, even
+// when it's fused.
+#include <gtest/gtest.h>
+
+// The following lines pull in the real gtest *.cc files.
#include "src/gtest.cc"
#include "src/gtest-death-test.cc"
#include "src/gtest-filepath.cc"
diff --git a/gtest/src/gtest-death-test.cc b/gtest/src/gtest-death-test.cc
index 106b01c..3b73b01 100644
--- a/gtest/src/gtest-death-test.cc
+++ b/gtest/src/gtest-death-test.cc
@@ -308,9 +308,9 @@ String DeathTest::last_death_test_message_;
// Provides cross platform implementation for some death functionality.
class DeathTestImpl : public DeathTest {
protected:
- DeathTestImpl(const char* statement, const RE* regex)
- : statement_(statement),
- regex_(regex),
+ DeathTestImpl(const char* a_statement, const RE* a_regex)
+ : statement_(a_statement),
+ regex_(a_regex),
spawned_(false),
status_(-1),
outcome_(IN_PROGRESS),
@@ -326,11 +326,11 @@ class DeathTestImpl : public DeathTest {
const char* statement() const { return statement_; }
const RE* regex() const { return regex_; }
bool spawned() const { return spawned_; }
- void set_spawned(bool spawned) { spawned_ = spawned; }
+ void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
int status() const { return status_; }
- void set_status(int status) { status_ = status; }
+ void set_status(int a_status) { status_ = a_status; }
DeathTestOutcome outcome() const { return outcome_; }
- void set_outcome(DeathTestOutcome outcome) { outcome_ = outcome; }
+ void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; }
int read_fd() const { return read_fd_; }
void set_read_fd(int fd) { read_fd_ = fd; }
int write_fd() const { return write_fd_; }
@@ -705,8 +705,8 @@ class ForkingDeathTest : public DeathTestImpl {
};
// Constructs a ForkingDeathTest.
-ForkingDeathTest::ForkingDeathTest(const char* statement, const RE* regex)
- : DeathTestImpl(statement, regex),
+ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex)
+ : DeathTestImpl(a_statement, a_regex),
child_pid_(-1) {}
// Waits for the child in a death test to exit, returning its exit
@@ -718,18 +718,18 @@ int ForkingDeathTest::Wait() {
ReadAndInterpretStatusByte();
- int status;
- GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status, 0));
- set_status(status);
- return status;
+ int status_value;
+ GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0));
+ set_status(status_value);
+ return status_value;
}
// A concrete death test class that forks, then immediately runs the test
// in the child process.
class NoExecDeathTest : public ForkingDeathTest {
public:
- NoExecDeathTest(const char* statement, const RE* regex) :
- ForkingDeathTest(statement, regex) { }
+ NoExecDeathTest(const char* a_statement, const RE* a_regex) :
+ ForkingDeathTest(a_statement, a_regex) { }
virtual TestRole AssumeRole();
};
@@ -782,9 +782,9 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() {
// only this specific death test to be run.
class ExecDeathTest : public ForkingDeathTest {
public:
- ExecDeathTest(const char* statement, const RE* regex,
+ ExecDeathTest(const char* a_statement, const RE* a_regex,
const char* file, int line) :
- ForkingDeathTest(statement, regex), file_(file), line_(line) { }
+ ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { }
virtual TestRole AssumeRole();
private:
// The name of the file in which the death test is located.
@@ -1037,8 +1037,6 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
// Splits a given string on a given delimiter, populating a given
// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have
// ::std::string, so we can use it here.
-// TODO(vladl@google.com): Get rid of std::vector to be able to build on
-// Visual C++ 7.1 with exceptions disabled.
static void SplitString(const ::std::string& str, char delimiter,
::std::vector< ::std::string>* dest) {
::std::vector< ::std::string> parsed;
diff --git a/gtest/src/gtest-filepath.cc b/gtest/src/gtest-filepath.cc
index 515d61c..c1ef918 100644
--- a/gtest/src/gtest-filepath.cc
+++ b/gtest/src/gtest-filepath.cc
@@ -63,8 +63,14 @@ namespace testing {
namespace internal {
#if GTEST_OS_WINDOWS
+// On Windows, '\\' is the standard path separator, but many tools and the
+// Windows API also accept '/' as an alternate path separator. Unless otherwise
+// noted, a file path can contain either kind of path separators, or a mixture
+// of them.
const char kPathSeparator = '\\';
+const char kAlternatePathSeparator = '/';
const char kPathSeparatorString[] = "\\";
+const char kAlternatePathSeparatorString[] = "/";
#if GTEST_OS_WINDOWS_MOBILE
// Windows CE doesn't have a current directory. You should not use
// the current directory in tests on Windows CE, but this at least
@@ -81,6 +87,15 @@ const char kPathSeparatorString[] = "/";
const char kCurrentDirectoryString[] = "./";
#endif // GTEST_OS_WINDOWS
+// Returns whether the given character is a valid path separator.
+static bool IsPathSeparator(char c) {
+#if GTEST_HAS_ALT_PATH_SEP_
+ return (c == kPathSeparator) || (c == kAlternatePathSeparator);
+#else
+ return c == kPathSeparator;
+#endif
+}
+
// Returns the current working directory, or "" if unsuccessful.
FilePath FilePath::GetCurrentDir() {
#if GTEST_OS_WINDOWS_MOBILE
@@ -108,6 +123,22 @@ FilePath FilePath::RemoveExtension(const char* extension) const {
return *this;
}
+// Returns a pointer to the last occurence of a valid path separator in
+// the FilePath. On Windows, for example, both '/' and '\' are valid path
+// separators. Returns NULL if no path separator was found.
+const char* FilePath::FindLastPathSeparator() const {
+ const char* const last_sep = strrchr(c_str(), kPathSeparator);
+#if GTEST_HAS_ALT_PATH_SEP_
+ const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
+ // Comparing two pointers of which only one is NULL is undefined.
+ if (last_alt_sep != NULL &&
+ (last_sep == NULL || last_alt_sep > last_sep)) {
+ return last_alt_sep;
+ }
+#endif
+ return last_sep;
+}
+
// Returns a copy of the FilePath with the directory part removed.
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
@@ -115,7 +146,7 @@ FilePath FilePath::RemoveExtension(const char* extension) const {
// returns an empty FilePath ("").
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath FilePath::RemoveDirectoryName() const {
- const char* const last_sep = strrchr(c_str(), kPathSeparator);
+ const char* const last_sep = FindLastPathSeparator();
return last_sep ? FilePath(String(last_sep + 1)) : *this;
}
@@ -126,7 +157,7 @@ FilePath FilePath::RemoveDirectoryName() const {
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath FilePath::RemoveFileName() const {
- const char* const last_sep = strrchr(c_str(), kPathSeparator);
+ const char* const last_sep = FindLastPathSeparator();
String dir;
if (last_sep) {
dir = String(c_str(), last_sep + 1 - c_str());
@@ -219,7 +250,7 @@ bool FilePath::IsRootDirectory() const {
// current directory. Handle this properly.
return pathname_.length() == 3 && IsAbsolutePath();
#else
- return pathname_ == kPathSeparatorString;
+ return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
#endif
}
@@ -231,9 +262,9 @@ bool FilePath::IsAbsolutePath() const {
((name[0] >= 'a' && name[0] <= 'z') ||
(name[0] >= 'A' && name[0] <= 'Z')) &&
name[1] == ':' &&
- name[2] == kPathSeparator;
+ IsPathSeparator(name[2]);
#else
- return name[0] == kPathSeparator;
+ return IsPathSeparator(name[0]);
#endif
}
@@ -260,7 +291,8 @@ FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
// it is intended to represent a directory. Returns false otherwise.
// This does NOT check that a directory (or file) actually exists.
bool FilePath::IsDirectory() const {
- return pathname_.EndsWith(kPathSeparatorString);
+ return !pathname_.empty() &&
+ IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
}
// Create directories so that path exists. Returns true if successful or if
@@ -305,14 +337,15 @@ bool FilePath::CreateFolder() const {
// name, otherwise return the name string unmodified.
// On Windows platform, uses \ as the separator, other platforms use /.
FilePath FilePath::RemoveTrailingPathSeparator() const {
- return pathname_.EndsWith(kPathSeparatorString)
+ return IsDirectory()
? FilePath(String(pathname_.c_str(), pathname_.length() - 1))
: *this;
}
-// Normalize removes any redundant separators that might be in the pathname.
+// Removes any redundant separators that might be in the pathname.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..".
+// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
void FilePath::Normalize() {
if (pathname_.c_str() == NULL) {
pathname_ = "";
@@ -324,12 +357,19 @@ void FilePath::Normalize() {
memset(dest_ptr, 0, pathname_.length() + 1);
while (*src != '\0') {
- *dest_ptr++ = *src;
- if (*src != kPathSeparator)
+ *dest_ptr = *src;
+ if (!IsPathSeparator(*src)) {
src++;
- else
- while (*src == kPathSeparator)
+ } else {
+#if GTEST_HAS_ALT_PATH_SEP_
+ if (*dest_ptr == kAlternatePathSeparator) {
+ *dest_ptr = kPathSeparator;
+ }
+#endif
+ while (IsPathSeparator(*src))
src++;
+ }
+ dest_ptr++;
}
*dest_ptr = '\0';
pathname_ = dest;
diff --git a/gtest/src/gtest-internal-inl.h b/gtest/src/gtest-internal-inl.h
index 47aec22..855b215 100644
--- a/gtest/src/gtest-internal-inl.h
+++ b/gtest/src/gtest-internal-inl.h
@@ -52,7 +52,9 @@
#include <stdlib.h> // For strtoll/_strtoul64/malloc/free.
#include <string.h> // For memmove.
+#include <algorithm>
#include <string>
+#include <vector>
#include <gtest/internal/gtest-port.h>
@@ -60,7 +62,7 @@
#include <windows.h> // For DWORD.
#endif // GTEST_OS_WINDOWS
-#include <gtest/gtest.h>
+#include <gtest/gtest.h> // NOLINT
#include <gtest/gtest-spi.h>
namespace testing {
@@ -76,7 +78,7 @@ namespace internal {
// The value of GetTestTypeId() as seen from within the Google Test
// library. This is solely for testing GetTestTypeId().
-extern const TypeId kTestTypeIdInGoogleTest;
+GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;
// Names of the flags (needed for parsing Google Test flags).
const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
@@ -90,13 +92,31 @@ const char kPrintTimeFlag[] = "print_time";
const char kRandomSeedFlag[] = "random_seed";
const char kRepeatFlag[] = "repeat";
const char kShuffleFlag[] = "shuffle";
+const char kStackTraceDepthFlag[] = "stack_trace_depth";
const char kThrowOnFailureFlag[] = "throw_on_failure";
// A valid random seed must be in [1, kMaxRandomSeed].
const int kMaxRandomSeed = 99999;
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+GTEST_API_ extern bool g_help_flag;
+
// Returns the current time in milliseconds.
-TimeInMillis GetTimeInMillis();
+GTEST_API_ TimeInMillis GetTimeInMillis();
+
+// Returns true iff Google Test should use colors in the output.
+GTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
+
+// Formats the given time in milliseconds as seconds.
+GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
+
+// Parses a string for an Int32 flag, in the form of "--flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true. On failure, returns false without changing *value.
+GTEST_API_ bool ParseInt32Flag(
+ const char* str, const char* flag, Int32* value);
// Returns a random seed in range [1, kMaxRandomSeed] based on the
// given --gtest_random_seed flag value.
@@ -144,6 +164,7 @@ class GTestFlagSaver {
random_seed_ = GTEST_FLAG(random_seed);
repeat_ = GTEST_FLAG(repeat);
shuffle_ = GTEST_FLAG(shuffle);
+ stack_trace_depth_ = GTEST_FLAG(stack_trace_depth);
throw_on_failure_ = GTEST_FLAG(throw_on_failure);
}
@@ -163,6 +184,7 @@ class GTestFlagSaver {
GTEST_FLAG(random_seed) = random_seed_;
GTEST_FLAG(repeat) = repeat_;
GTEST_FLAG(shuffle) = shuffle_;
+ GTEST_FLAG(stack_trace_depth) = stack_trace_depth_;
GTEST_FLAG(throw_on_failure) = throw_on_failure_;
}
private:
@@ -182,6 +204,7 @@ class GTestFlagSaver {
internal::Int32 random_seed_;
internal::Int32 repeat_;
bool shuffle_;
+ internal::Int32 stack_trace_depth_;
bool throw_on_failure_;
} GTEST_ATTRIBUTE_UNUSED_;
@@ -193,7 +216,7 @@ class GTestFlagSaver {
// If the code_point is not a valid Unicode code point
// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output
// as '(Invalid Unicode 0xXXXXXXXX)'.
-char* CodePointToUtf8(UInt32 code_point, char* str);
+GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str);
// Converts a wide string to a narrow string in UTF-8 encoding.
// The wide string is assumed to have the following encoding:
@@ -208,10 +231,7 @@ char* CodePointToUtf8(UInt32 code_point, char* str);
// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
// and contains invalid UTF-16 surrogate pairs, values in those pairs
// will be encoded as individual Unicode characters from Basic Normal Plane.
-String WideStringToUtf8(const wchar_t* str, int num_chars);
-
-// Returns the number of active threads, or 0 when there is an error.
-size_t GetThreadCount();
+GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars);
// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
// if the variable is present. If a file already exists at this location, this
@@ -225,269 +245,78 @@ void WriteToShardStatusFileIfNeeded();
// an error and exits. If in_subprocess_for_death_test, sharding is
// disabled because it must only be applied to the original test
// process. Otherwise, we could filter out death tests we intended to execute.
-bool ShouldShard(const char* total_shards_str, const char* shard_index_str,
- bool in_subprocess_for_death_test);
+GTEST_API_ bool ShouldShard(const char* total_shards_str,
+ const char* shard_index_str,
+ bool in_subprocess_for_death_test);
// Parses the environment variable var as an Int32. If it is unset,
// returns default_val. If it is not an Int32, prints an error and
// and aborts.
-Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);
+GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);
// Given the total number of shards, the shard index, and the test id,
// returns true iff the test should be run on this shard. The test id is
// some arbitrary but unique non-negative integer assigned to each test
// method. Assumes that 0 <= shard_index < total_shards.
-bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id);
-
-// Vector is an ordered container that supports random access to the
-// elements.
-//
-// We cannot use std::vector, as Visual C++ 7.1's implementation of
-// STL has problems compiling when exceptions are disabled. There is
-// a hack to work around the problems, but we've seen cases where the
-// hack fails to work.
-//
-// The element type must support copy constructor and operator=.
-template <typename E> // E is the element type.
-class Vector {
- public:
- // Creates an empty Vector.
- Vector() : elements_(NULL), capacity_(0), size_(0) {}
-
- // D'tor.
- virtual ~Vector() { Clear(); }
-
- // Clears the Vector.
- void Clear() {
- if (elements_ != NULL) {
- for (int i = 0; i < size_; i++) {
- delete elements_[i];
- }
-
- free(elements_);
- elements_ = NULL;
- capacity_ = size_ = 0;
- }
- }
-
- // Gets the number of elements.
- int size() const { return size_; }
-
- // Adds an element to the end of the Vector. A copy of the element
- // is created using the copy constructor, and then stored in the
- // Vector. Changes made to the element in the Vector doesn't affect
- // the source object, and vice versa.
- void PushBack(const E& element) { Insert(element, size_); }
-
- // Adds an element to the beginning of this Vector.
- void PushFront(const E& element) { Insert(element, 0); }
-
- // Removes an element from the beginning of this Vector. If the
- // result argument is not NULL, the removed element is stored in the
- // memory it points to. Otherwise the element is thrown away.
- // Returns true iff the vector wasn't empty before the operation.
- bool PopFront(E* result) {
- if (size_ == 0)
- return false;
-
- if (result != NULL)
- *result = GetElement(0);
-
- Erase(0);
- return true;
- }
-
- // Inserts an element at the given index. It's the caller's
- // responsibility to ensure that the given index is in the range [0,
- // size()].
- void Insert(const E& element, int index) {
- GrowIfNeeded();
- MoveElements(index, size_ - index, index + 1);
- elements_[index] = new E(element);
- size_++;
- }
-
- // Erases the element at the specified index, or aborts the program if the
- // index is not in range [0, size()).
- void Erase(int index) {
- GTEST_CHECK_(0 <= index && index < size_)
- << "Invalid Vector index " << index << ": must be in range [0, "
- << (size_ - 1) << "].";
-
- delete elements_[index];
- MoveElements(index + 1, size_ - index - 1, index);
- size_--;
- }
-
- // Returns the number of elements that satisfy a given predicate.
- // The parameter 'predicate' is a Boolean function or functor that
- // accepts a 'const E &', where E is the element type.
- template <typename P> // P is the type of the predicate function/functor
- int CountIf(P predicate) const {
- int count = 0;
- for (int i = 0; i < size_; i++) {
- if (predicate(*(elements_[i]))) {
- count++;
- }
- }
-
- return count;
- }
-
- // Applies a function/functor to each element in the Vector. The
- // parameter 'functor' is a function/functor that accepts a 'const
- // E &', where E is the element type. This method does not change
- // the elements.
- template <typename F> // F is the type of the function/functor
- void ForEach(F functor) const {
- for (int i = 0; i < size_; i++) {
- functor(*(elements_[i]));
- }
- }
-
- // Returns the first node whose element satisfies a given predicate,
- // or NULL if none is found. The parameter 'predicate' is a
- // function/functor that accepts a 'const E &', where E is the
- // element type. This method does not change the elements.
- template <typename P> // P is the type of the predicate function/functor.
- const E* FindIf(P predicate) const {
- for (int i = 0; i < size_; i++) {
- if (predicate(*elements_[i])) {
- return elements_[i];
- }
- }
- return NULL;
- }
-
- template <typename P>
- E* FindIf(P predicate) {
- for (int i = 0; i < size_; i++) {
- if (predicate(*elements_[i])) {
- return elements_[i];
- }
- }
- return NULL;
- }
-
- // Returns the i-th element of the Vector, or aborts the program if i
- // is not in range [0, size()).
- const E& GetElement(int i) const {
- GTEST_CHECK_(0 <= i && i < size_)
- << "Invalid Vector index " << i << ": must be in range [0, "
- << (size_ - 1) << "].";
-
- return *(elements_[i]);
- }
-
- // Returns a mutable reference to the i-th element of the Vector, or
- // aborts the program if i is not in range [0, size()).
- E& GetMutableElement(int i) {
- GTEST_CHECK_(0 <= i && i < size_)
- << "Invalid Vector index " << i << ": must be in range [0, "
- << (size_ - 1) << "].";
+GTEST_API_ bool ShouldRunTestOnShard(
+ int total_shards, int shard_index, int test_id);
- return *(elements_[i]);
- }
-
- // Returns the i-th element of the Vector, or default_value if i is not
- // in range [0, size()).
- E GetElementOr(int i, E default_value) const {
- return (i < 0 || i >= size_) ? default_value : *(elements_[i]);
- }
-
- // Swaps the i-th and j-th elements of the Vector. Crashes if i or
- // j is invalid.
- void Swap(int i, int j) {
- GTEST_CHECK_(0 <= i && i < size_)
- << "Invalid first swap element " << i << ": must be in range [0, "
- << (size_ - 1) << "].";
- GTEST_CHECK_(0 <= j && j < size_)
- << "Invalid second swap element " << j << ": must be in range [0, "
- << (size_ - 1) << "].";
-
- E* const temp = elements_[i];
- elements_[i] = elements_[j];
- elements_[j] = temp;
- }
-
- // Performs an in-place shuffle of a range of this Vector's nodes.
- // 'begin' and 'end' are element indices as an STL-style range;
- // i.e. [begin, end) are shuffled, where 'end' == size() means to
- // shuffle to the end of the Vector.
- void ShuffleRange(internal::Random* random, int begin, int end) {
- GTEST_CHECK_(0 <= begin && begin <= size_)
- << "Invalid shuffle range start " << begin << ": must be in range [0, "
- << size_ << "].";
- GTEST_CHECK_(begin <= end && end <= size_)
- << "Invalid shuffle range finish " << end << ": must be in range ["
- << begin << ", " << size_ << "].";
-
- // Fisher-Yates shuffle, from
- // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
- for (int range_width = end - begin; range_width >= 2; range_width--) {
- const int last_in_range = begin + range_width - 1;
- const int selected = begin + random->Generate(range_width);
- Swap(selected, last_in_range);
- }
- }
+// STL container utilities.
- // Performs an in-place shuffle of this Vector's nodes.
- void Shuffle(internal::Random* random) {
- ShuffleRange(random, 0, size());
- }
-
- // Returns a copy of this Vector.
- Vector* Clone() const {
- Vector* const clone = new Vector;
- clone->Reserve(size_);
- for (int i = 0; i < size_; i++) {
- clone->PushBack(GetElement(i));
- }
- return clone;
- }
+// Returns the number of elements in the given container that satisfy
+// the given predicate.
+template <class Container, typename Predicate>
+inline int CountIf(const Container& c, Predicate predicate) {
+ return static_cast<int>(std::count_if(c.begin(), c.end(), predicate));
+}
- private:
- // Makes sure this Vector's capacity is at least the given value.
- void Reserve(int new_capacity) {
- if (new_capacity <= capacity_)
- return;
-
- capacity_ = new_capacity;
- elements_ = static_cast<E**>(
- realloc(elements_, capacity_*sizeof(elements_[0])));
- }
+// Applies a function/functor to each element in the container.
+template <class Container, typename Functor>
+void ForEach(const Container& c, Functor functor) {
+ std::for_each(c.begin(), c.end(), functor);
+}
- // Grows the buffer if it is not big enough to hold one more element.
- void GrowIfNeeded() {
- if (size_ < capacity_)
- return;
-
- // Exponential bump-up is necessary to ensure that inserting N
- // elements is O(N) instead of O(N^2). The factor 3/2 means that
- // no more than 1/3 of the slots are wasted.
- const int new_capacity = 3*(capacity_/2 + 1);
- GTEST_CHECK_(new_capacity > capacity_) // Does the new capacity overflow?
- << "Cannot grow a Vector with " << capacity_ << " elements already.";
- Reserve(new_capacity);
- }
+// Returns the i-th element of the vector, or default_value if i is not
+// in range [0, v.size()).
+template <typename E>
+inline E GetElementOr(const std::vector<E>& v, int i, E default_value) {
+ return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i];
+}
- // Moves the give consecutive elements to a new index in the Vector.
- void MoveElements(int source, int count, int dest) {
- memmove(elements_ + dest, elements_ + source, count*sizeof(elements_[0]));
+// Performs an in-place shuffle of a range of the vector's elements.
+// 'begin' and 'end' are element indices as an STL-style range;
+// i.e. [begin, end) are shuffled, where 'end' == size() means to
+// shuffle to the end of the vector.
+template <typename E>
+void ShuffleRange(internal::Random* random, int begin, int end,
+ std::vector<E>* v) {
+ const int size = static_cast<int>(v->size());
+ GTEST_CHECK_(0 <= begin && begin <= size)
+ << "Invalid shuffle range start " << begin << ": must be in range [0, "
+ << size << "].";
+ GTEST_CHECK_(begin <= end && end <= size)
+ << "Invalid shuffle range finish " << end << ": must be in range ["
+ << begin << ", " << size << "].";
+
+ // Fisher-Yates shuffle, from
+ // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
+ for (int range_width = end - begin; range_width >= 2; range_width--) {
+ const int last_in_range = begin + range_width - 1;
+ const int selected = begin + random->Generate(range_width);
+ std::swap((*v)[selected], (*v)[last_in_range]);
}
+}
- E** elements_;
- int capacity_; // The number of elements allocated for elements_.
- int size_; // The number of elements; in the range [0, capacity_].
-
- // We disallow copying Vector.
- GTEST_DISALLOW_COPY_AND_ASSIGN_(Vector);
-}; // class Vector
+// Performs an in-place shuffle of the vector's elements.
+template <typename E>
+inline void Shuffle(internal::Random* random, std::vector<E>* v) {
+ ShuffleRange(random, 0, static_cast<int>(v->size()), v);
+}
// A function for deleting an object. Handy for being used as a
// functor.
template <typename T>
-static void Delete(T * x) {
+static void Delete(T* x) {
delete x;
}
@@ -600,7 +429,7 @@ class TestInfoImpl {
// test filter using either GTEST_FILTER or --gtest_filter. If both
// the variable and the flag are present, the latter overrides the
// former.
-class UnitTestOptions {
+class GTEST_API_ UnitTestOptions {
public:
// Functions for processing the gtest_output flag.
@@ -642,7 +471,7 @@ class UnitTestOptions {
// Returns the current application's name, removing directory path if that
// is present. Used by UnitTestOptions::GetOutputFile.
-FilePath GetCurrentExecutableName();
+GTEST_API_ FilePath GetCurrentExecutableName();
// The role interface for getting the OS stack trace as a string.
class OsStackTraceGetterInterface {
@@ -733,7 +562,7 @@ class DefaultPerThreadTestPartResultReporter
// the methods under a mutex, as this class is not accessible by a
// user and the UnitTest class that delegates work to this class does
// proper locking.
-class UnitTestImpl {
+class GTEST_API_ UnitTestImpl {
public:
explicit UnitTestImpl(UnitTest* parent);
virtual ~UnitTestImpl();
@@ -802,15 +631,15 @@ class UnitTestImpl {
// Gets the i-th test case among all the test cases. i can range from 0 to
// total_test_case_count() - 1. If i is not in that range, returns NULL.
const TestCase* GetTestCase(int i) const {
- const int index = test_case_indices_.GetElementOr(i, -1);
- return index < 0 ? NULL : test_cases_.GetElement(i);
+ const int index = GetElementOr(test_case_indices_, i, -1);
+ return index < 0 ? NULL : test_cases_[i];
}
// Gets the i-th test case among all the test cases. i can range from 0 to
// total_test_case_count() - 1. If i is not in that range, returns NULL.
TestCase* GetMutableTestCase(int i) {
- const int index = test_case_indices_.GetElementOr(i, -1);
- return index < 0 ? NULL : test_cases_.GetElement(index);
+ const int index = GetElementOr(test_case_indices_, i, -1);
+ return index < 0 ? NULL : test_cases_[index];
}
// Provides access to the event listener list.
@@ -898,15 +727,15 @@ class UnitTestImpl {
#endif // GTEST_HAS_PARAM_TEST
// Sets the TestCase object for the test that's currently running.
- void set_current_test_case(TestCase* current_test_case) {
- current_test_case_ = current_test_case;
+ void set_current_test_case(TestCase* a_current_test_case) {
+ current_test_case_ = a_current_test_case;
}
// Sets the TestInfo object for the test that's currently running. If
// current_test_info is NULL, the assertion results will be stored in
// ad_hoc_test_result_.
- void set_current_test_info(TestInfo* current_test_info) {
- current_test_info_ = current_test_info;
+ void set_current_test_info(TestInfo* a_current_test_info) {
+ current_test_info_ = a_current_test_info;
}
// Registers all parameterized tests defined using TEST_P and
@@ -927,7 +756,7 @@ class UnitTestImpl {
// Clears the results of all tests, including the ad hoc test.
void ClearResult() {
- test_cases_.ForEach(TestCase::ClearTestCaseResult);
+ ForEach(test_cases_, TestCase::ClearTestCaseResult);
ad_hoc_test_result_.Clear();
}
@@ -953,17 +782,14 @@ class UnitTestImpl {
// Returns the vector of environments that need to be set-up/torn-down
// before/after the tests are run.
- internal::Vector<Environment*>* environments() { return &environments_; }
- internal::Vector<Environment*>* environments_in_reverse_order() {
- return &environments_in_reverse_order_;
- }
+ std::vector<Environment*>& environments() { return environments_; }
// Getters for the per-thread Google Test trace stack.
- internal::Vector<TraceInfo>* gtest_trace_stack() {
- return gtest_trace_stack_.pointer();
+ std::vector<TraceInfo>& gtest_trace_stack() {
+ return *(gtest_trace_stack_.pointer());
}
- const internal::Vector<TraceInfo>* gtest_trace_stack() const {
- return gtest_trace_stack_.pointer();
+ const std::vector<TraceInfo>& gtest_trace_stack() const {
+ return gtest_trace_stack_.get();
}
#if GTEST_HAS_DEATH_TEST
@@ -1038,20 +864,18 @@ class UnitTestImpl {
per_thread_test_part_result_reporter_;
// The vector of environments that need to be set-up/torn-down
- // before/after the tests are run. environments_in_reverse_order_
- // simply mirrors environments_ in reverse order.
- internal::Vector<Environment*> environments_;
- internal::Vector<Environment*> environments_in_reverse_order_;
+ // before/after the tests are run.
+ std::vector<Environment*> environments_;
// The vector of TestCases in their original order. It owns the
// elements in the vector.
- internal::Vector<TestCase*> test_cases_;
+ std::vector<TestCase*> test_cases_;
// Provides a level of indirection for the test case list to allow
// easy shuffling and restoring the test case order. The i-th
// element of this vector is the index of the i-th test case in the
// shuffled order.
- internal::Vector<int> test_case_indices_;
+ std::vector<int> test_case_indices_;
#if GTEST_HAS_PARAM_TEST
// ParameterizedTestRegistry object used to register value-parameterized
@@ -1117,7 +941,7 @@ class UnitTestImpl {
#endif // GTEST_HAS_DEATH_TEST
// A per-thread stack of traces created by the SCOPED_TRACE() macro.
- internal::ThreadLocal<internal::Vector<TraceInfo> > gtest_trace_stack_;
+ internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl);
}; // class UnitTestImpl
@@ -1130,24 +954,24 @@ inline UnitTestImpl* GetUnitTestImpl() {
// Internal helper functions for implementing the simple regular
// expression matcher.
-bool IsInSet(char ch, const char* str);
-bool IsDigit(char ch);
-bool IsPunct(char ch);
-bool IsRepeat(char ch);
-bool IsWhiteSpace(char ch);
-bool IsWordChar(char ch);
-bool IsValidEscape(char ch);
-bool AtomMatchesChar(bool escaped, char pattern, char ch);
-bool ValidateRegex(const char* regex);
-bool MatchRegexAtHead(const char* regex, const char* str);
-bool MatchRepetitionAndRegexAtHead(
+GTEST_API_ bool IsInSet(char ch, const char* str);
+GTEST_API_ bool IsDigit(char ch);
+GTEST_API_ bool IsPunct(char ch);
+GTEST_API_ bool IsRepeat(char ch);
+GTEST_API_ bool IsWhiteSpace(char ch);
+GTEST_API_ bool IsWordChar(char ch);
+GTEST_API_ bool IsValidEscape(char ch);
+GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);
+GTEST_API_ bool ValidateRegex(const char* regex);
+GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);
+GTEST_API_ bool MatchRepetitionAndRegexAtHead(
bool escaped, char ch, char repeat, const char* regex, const char* str);
-bool MatchRegexAnywhere(const char* regex, const char* str);
+GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
// Parses the command line for Google Test flags, without initializing
// other parts of Google Test.
-void ParseGoogleTestFlagsOnly(int* argc, char** argv);
-void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
#if GTEST_HAS_DEATH_TEST
@@ -1224,6 +1048,9 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
// TestResult contains some private methods that should be hidden from
// Google Test user but are required for testing. This class allow our tests
// to access them.
+//
+// This class is supplied only for the purpose of testing Google Test's own
+// constructs. Do not use it in user tests, either directly or indirectly.
class TestResultAccessor {
public:
static void RecordProperty(TestResult* test_result,
@@ -1235,7 +1062,7 @@ class TestResultAccessor {
test_result->ClearTestPartResults();
}
- static const Vector<testing::TestPartResult>& test_part_results(
+ static const std::vector<testing::TestPartResult>& test_part_results(
const TestResult& test_result) {
return test_result.test_part_results();
}
diff --git a/gtest/src/gtest-port.cc b/gtest/src/gtest-port.cc
index de169e2..b9504f5 100644
--- a/gtest/src/gtest-port.cc
+++ b/gtest/src/gtest-port.cc
@@ -68,8 +68,10 @@ namespace internal {
#if defined(_MSC_VER) || defined(__BORLANDC__)
// MSVC and C++Builder do not provide a definition of STDERR_FILENO.
+const int kStdOutFileno = 1;
const int kStdErrFileno = 2;
#else
+const int kStdOutFileno = STDOUT_FILENO;
const int kStdErrFileno = STDERR_FILENO;
#endif // _MSC_VER
@@ -109,8 +111,14 @@ size_t GetThreadCount() {
// Implements RE. Currently only needed for death tests.
RE::~RE() {
- regfree(&partial_regex_);
- regfree(&full_regex_);
+ if (is_valid_) {
+ // regfree'ing an invalid regex might crash because the content
+ // of the regex is undefined. Since the regex's are essentially
+ // the same, one cannot be valid (or invalid) without the other
+ // being so too.
+ regfree(&partial_regex_);
+ regfree(&full_regex_);
+ }
free(const_cast<char*>(pattern_));
}
@@ -150,9 +158,10 @@ void RE::Init(const char* regex) {
// Some implementation of POSIX regex (e.g. on at least some
// versions of Cygwin) doesn't accept the empty string as a valid
// regex. We change it to an equivalent form "()" to be safe.
- const char* const partial_regex = (*regex == '\0') ? "()" : regex;
- is_valid_ = (regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0)
- && is_valid_;
+ if (is_valid_) {
+ const char* const partial_regex = (*regex == '\0') ? "()" : regex;
+ is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
+ }
EXPECT_TRUE(is_valid_)
<< "Regular expression \"" << regex
<< "\" is not a valid POSIX Extended regular expression.";
@@ -439,81 +448,83 @@ GTestLog::~GTestLog() {
#pragma warning(disable: 4996)
#endif // _MSC_VER
-// Defines the stderr capturer.
+#if GTEST_HAS_STREAM_REDIRECTION_
-class CapturedStderr {
+// Object that captures an output stream (stdout/stderr).
+class CapturedStream {
public:
- // The ctor redirects stderr to a temporary file.
- CapturedStderr() {
-#if GTEST_OS_WINDOWS_MOBILE
- // Not supported on Windows CE.
- posix::Abort();
-#else
- uncaptured_fd_ = dup(kStdErrFileno);
-
+ // The ctor redirects the stream to a temporary file.
+ CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
#if GTEST_OS_WINDOWS
char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT
char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT
::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
- ::GetTempFileNameA(temp_dir_path, "gtest_redir", 0, temp_file_path);
+ const UINT success = ::GetTempFileNameA(temp_dir_path,
+ "gtest_redir",
+ 0, // Generate unique file name.
+ temp_file_path);
+ GTEST_CHECK_(success != 0)
+ << "Unable to create a temporary file in " << temp_dir_path;
const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
+ GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
+ << temp_file_path;
filename_ = temp_file_path;
#else
// There's no guarantee that a test has write access to the
// current directory, so we create the temporary file in the /tmp
// directory instead.
- char name_template[] = "/tmp/captured_stderr.XXXXXX";
+ char name_template[] = "/tmp/captured_stream.XXXXXX";
const int captured_fd = mkstemp(name_template);
filename_ = name_template;
#endif // GTEST_OS_WINDOWS
fflush(NULL);
- dup2(captured_fd, kStdErrFileno);
+ dup2(captured_fd, fd_);
close(captured_fd);
-#endif // GTEST_OS_WINDOWS_MOBILE
}
- ~CapturedStderr() {
-#if !GTEST_OS_WINDOWS_MOBILE
+ ~CapturedStream() {
remove(filename_.c_str());
-#endif // !GTEST_OS_WINDOWS_MOBILE
}
- // Stops redirecting stderr.
- void StopCapture() {
-#if !GTEST_OS_WINDOWS_MOBILE
- // Restores the original stream.
- fflush(NULL);
- dup2(uncaptured_fd_, kStdErrFileno);
- close(uncaptured_fd_);
- uncaptured_fd_ = -1;
-#endif // !GTEST_OS_WINDOWS_MOBILE
- }
+ String GetCapturedString() {
+ if (uncaptured_fd_ != -1) {
+ // Restores the original stream.
+ fflush(NULL);
+ dup2(uncaptured_fd_, fd_);
+ close(uncaptured_fd_);
+ uncaptured_fd_ = -1;
+ }
- // Returns the name of the temporary file holding the stderr output.
- // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
- // can use it here.
- ::std::string filename() const { return filename_; }
+ FILE* const file = posix::FOpen(filename_.c_str(), "r");
+ const String content = ReadEntireFile(file);
+ posix::FClose(file);
+ return content;
+ }
private:
+ // Reads the entire content of a file as a String.
+ static String ReadEntireFile(FILE* file);
+
+ // Returns the size (in bytes) of a file.
+ static size_t GetFileSize(FILE* file);
+
+ const int fd_; // A stream to capture.
int uncaptured_fd_;
+ // Name of the temporary file holding the stderr output.
::std::string filename_;
-};
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif // _MSC_VER
-
-static CapturedStderr* g_captured_stderr = NULL;
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
+};
// Returns the size (in bytes) of a file.
-static size_t GetFileSize(FILE * file) {
+size_t CapturedStream::GetFileSize(FILE* file) {
fseek(file, 0, SEEK_END);
return static_cast<size_t>(ftell(file));
}
// Reads the entire content of a file as a string.
-static String ReadEntireFile(FILE * file) {
+String CapturedStream::ReadEntireFile(FILE* file) {
const size_t file_size = GetFileSize(file);
char* const buffer = new char[file_size];
@@ -535,30 +546,50 @@ static String ReadEntireFile(FILE * file) {
return content;
}
-// Starts capturing stderr.
-void CaptureStderr() {
- if (g_captured_stderr != NULL) {
- GTEST_LOG_(FATAL) << "Only one stderr capturer can exist at one time.";
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif // _MSC_VER
+
+static CapturedStream* g_captured_stderr = NULL;
+static CapturedStream* g_captured_stdout = NULL;
+
+// Starts capturing an output stream (stdout/stderr).
+void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
+ if (*stream != NULL) {
+ GTEST_LOG_(FATAL) << "Only one " << stream_name
+ << " capturer can exist at a time.";
}
- g_captured_stderr = new CapturedStderr;
+ *stream = new CapturedStream(fd);
}
-// Stops capturing stderr and returns the captured string.
-// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can
-// use it here.
-String GetCapturedStderr() {
- g_captured_stderr->StopCapture();
+// Stops capturing the output stream and returns the captured string.
+String GetCapturedStream(CapturedStream** captured_stream) {
+ const String content = (*captured_stream)->GetCapturedString();
- FILE* const file = posix::FOpen(g_captured_stderr->filename().c_str(), "r");
- const String content = ReadEntireFile(file);
- posix::FClose(file);
-
- delete g_captured_stderr;
- g_captured_stderr = NULL;
+ delete *captured_stream;
+ *captured_stream = NULL;
return content;
}
+// Starts capturing stdout.
+void CaptureStdout() {
+ CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
+}
+
+// Starts capturing stderr.
+void CaptureStderr() {
+ CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
+}
+
+// Stops capturing stdout and returns the captured string.
+String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); }
+
+// Stops capturing stderr and returns the captured string.
+String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); }
+
+#endif // GTEST_HAS_STREAM_REDIRECTION_
+
#if GTEST_HAS_DEATH_TEST
// A copy of all command line arguments. Set by InitGoogleTest().
diff --git a/gtest/src/gtest-test-part.cc b/gtest/src/gtest-test-part.cc
index 4f36df6..5d183a4 100644
--- a/gtest/src/gtest-test-part.cc
+++ b/gtest/src/gtest-test-part.cc
@@ -64,19 +64,9 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
<< result.message() << std::endl;
}
-// Constructs an empty TestPartResultArray.
-TestPartResultArray::TestPartResultArray()
- : array_(new internal::Vector<TestPartResult>) {
-}
-
-// Destructs a TestPartResultArray.
-TestPartResultArray::~TestPartResultArray() {
- delete array_;
-}
-
// Appends a TestPartResult to the array.
void TestPartResultArray::Append(const TestPartResult& result) {
- array_->PushBack(result);
+ array_.push_back(result);
}
// Returns the TestPartResult at the given index (0-based).
@@ -86,12 +76,12 @@ const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
internal::posix::Abort();
}
- return array_->GetElement(index);
+ return array_[index];
}
// Returns the number of TestPartResult objects in the array.
int TestPartResultArray::size() const {
- return array_->size();
+ return static_cast<int>(array_.size());
}
namespace internal {
diff --git a/gtest/src/gtest-typed-test.cc b/gtest/src/gtest-typed-test.cc
index 4a0f657..3cc4b5d 100644
--- a/gtest/src/gtest-typed-test.cc
+++ b/gtest/src/gtest-typed-test.cc
@@ -37,6 +37,14 @@ namespace internal {
#if GTEST_HAS_TYPED_TEST_P
+// Skips to the first non-space char in str. Returns an empty string if str
+// contains only whitespace characters.
+static const char* SkipSpaces(const char* str) {
+ while (isspace(*str))
+ str++;
+ return str;
+}
+
// Verifies that registered_tests match the test names in
// defined_test_names_; returns registered_tests if successful, or
// aborts the program otherwise.
@@ -45,6 +53,10 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames(
typedef ::std::set<const char*>::const_iterator DefinedTestIter;
registered_ = true;
+ // Skip initial whitespace in registered_tests since some
+ // preprocessors prefix stringizied literals with whitespace.
+ registered_tests = SkipSpaces(registered_tests);
+
Message errors;
::std::set<String> tests;
for (const char* names = registered_tests; names != NULL;
diff --git a/gtest/src/gtest.cc b/gtest/src/gtest.cc
index 9340724..342d458 100644
--- a/gtest/src/gtest.cc
+++ b/gtest/src/gtest.cc
@@ -42,7 +42,10 @@
#include <wchar.h>
#include <wctype.h>
+#include <algorithm>
#include <ostream>
+#include <sstream>
+#include <vector>
#if GTEST_OS_LINUX
@@ -131,6 +134,11 @@
namespace testing {
+using internal::CountIf;
+using internal::ForEach;
+using internal::GetElementOr;
+using internal::Shuffle;
+
// Constants.
// A test whose test case name or test name matches this filter is
@@ -161,6 +169,10 @@ namespace internal {
// stack trace.
const char kStackTraceMarker[] = "\nStack trace:\n";
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+bool g_help_flag = false;
+
} // namespace internal
GTEST_DEFINE_bool_(
@@ -242,7 +254,7 @@ GTEST_DEFINE_bool_(
GTEST_DEFINE_int32_(
stack_trace_depth,
- internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth),
+ internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth),
"The maximum number of stack frames to print when an "
"assertion fails. The valid range is 0 through 100, inclusive.");
@@ -274,10 +286,6 @@ UInt32 Random::Generate(UInt32 range) {
return state_ % range;
}
-// g_help_flag is true iff the --help flag or an equivalent form is
-// specified on the command line.
-static bool g_help_flag = false;
-
// GTestIsInitialized() returns true iff the user has initialized
// Google Test. Useful for catching the user mistake of not initializing
// Google Test before calling RUN_ALL_TESTS().
@@ -292,11 +300,11 @@ static bool GTestIsInitialized() { return g_init_gtest_count != 0; }
// Iterates over a vector of TestCases, keeping a running sum of the
// results of calling a given int-returning method on each.
// Returns the sum.
-static int SumOverTestCaseList(const internal::Vector<TestCase*>& case_list,
+static int SumOverTestCaseList(const std::vector<TestCase*>& case_list,
int (TestCase::*method)() const) {
int sum = 0;
- for (int i = 0; i < case_list.size(); i++) {
- sum += (case_list.GetElement(i)->*method)();
+ for (size_t i = 0; i < case_list.size(); i++) {
+ sum += (case_list[i]->*method)();
}
return sum;
}
@@ -341,7 +349,7 @@ void AssertHelper::operator=(const Message& message) const {
}
// Mutex for linked pointers.
-Mutex g_linked_ptr_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX);
+GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
// Application pathname gotten in InitGoogleTest.
String g_executable_path;
@@ -672,23 +680,23 @@ void UnitTestImpl::SetTestPartResultReporterForCurrentThread(
// Gets the number of successful test cases.
int UnitTestImpl::successful_test_case_count() const {
- return test_cases_.CountIf(TestCasePassed);
+ return CountIf(test_cases_, TestCasePassed);
}
// Gets the number of failed test cases.
int UnitTestImpl::failed_test_case_count() const {
- return test_cases_.CountIf(TestCaseFailed);
+ return CountIf(test_cases_, TestCaseFailed);
}
// Gets the number of all test cases.
int UnitTestImpl::total_test_case_count() const {
- return test_cases_.size();
+ return static_cast<int>(test_cases_.size());
}
// Gets the number of all test cases that contain at least one test
// that should run.
int UnitTestImpl::test_case_to_run_count() const {
- return test_cases_.CountIf(ShouldRunTestCase);
+ return CountIf(test_cases_, ShouldRunTestCase);
}
// Gets the number of successful tests.
@@ -952,21 +960,37 @@ String FormatForFailureMessage(wchar_t wchar) {
} // namespace internal
-// AssertionResult constructor.
-AssertionResult::AssertionResult(const internal::String& failure_message)
- : failure_message_(failure_message) {
+// AssertionResult constructors.
+// Used in EXPECT_TRUE/FALSE(assertion_result).
+AssertionResult::AssertionResult(const AssertionResult& other)
+ : success_(other.success_),
+ message_(other.message_.get() != NULL ?
+ new internal::String(*other.message_) :
+ static_cast<internal::String*>(NULL)) {
}
+// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
+AssertionResult AssertionResult::operator!() const {
+ AssertionResult negation(!success_);
+ if (message_.get() != NULL)
+ negation << *message_;
+ return negation;
+}
// Makes a successful assertion result.
AssertionResult AssertionSuccess() {
- return AssertionResult();
+ return AssertionResult(true);
}
+// Makes a failed assertion result.
+AssertionResult AssertionFailure() {
+ return AssertionResult(false);
+}
// Makes a failed assertion result with the given failure message.
+// Deprecated; use AssertionFailure() << message.
AssertionResult AssertionFailure(const Message& message) {
- return AssertionResult(message.GetString());
+ return AssertionFailure() << message;
}
namespace internal {
@@ -1008,6 +1032,20 @@ AssertionResult EqFailure(const char* expected_expression,
return AssertionFailure(msg);
}
+// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
+String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result,
+ const char* expression_text,
+ const char* actual_predicate_value,
+ const char* expected_predicate_value) {
+ const char* actual_message = assertion_result.message();
+ Message msg;
+ msg << "Value of: " << expression_text
+ << "\n Actual: " << actual_predicate_value;
+ if (actual_message[0] != '\0')
+ msg << " (" << actual_message << ")";
+ msg << "\nExpected: " << expected_predicate_value;
+ return msg.GetString();
+}
// Helper function for implementing ASSERT_NEAR.
AssertionResult DoubleNearPredFormat(const char* expr1,
@@ -1286,7 +1324,6 @@ AssertionResult IsNotSubstring(
return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
}
-#if GTEST_HAS_STD_STRING
AssertionResult IsSubstring(
const char* needle_expr, const char* haystack_expr,
const ::std::string& needle, const ::std::string& haystack) {
@@ -1298,7 +1335,6 @@ AssertionResult IsNotSubstring(
const ::std::string& needle, const ::std::string& haystack) {
return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
}
-#endif // GTEST_HAS_STD_STRING
#if GTEST_HAS_STD_WSTRING
AssertionResult IsSubstring(
@@ -1718,14 +1754,9 @@ String String::Format(const char * format, ...) {
// Converts the buffer in a StrStream to a String, converting NUL
// bytes to "\\0" along the way.
String StrStreamToString(StrStream* ss) {
-#if GTEST_HAS_STD_STRING
const ::std::string& str = ss->str();
const char* const start = str.c_str();
const char* const end = start + str.length();
-#else
- const char* const start = ss->str();
- const char* const end = start + ss->pcount();
-#endif // GTEST_HAS_STD_STRING
// We need to use a helper StrStream to do this transformation
// because String doesn't support push_back().
@@ -1738,14 +1769,7 @@ String StrStreamToString(StrStream* ss) {
}
}
-#if GTEST_HAS_STD_STRING
return String(helper.str().c_str());
-#else
- const String str(helper.str(), helper.pcount());
- helper.freeze(false);
- ss->freeze(false);
- return str;
-#endif // GTEST_HAS_STD_STRING
}
// Appends the user-supplied message to the Google-Test-generated message.
@@ -1769,9 +1793,7 @@ String AppendUserMessage(const String& gtest_msg,
// Creates an empty TestResult.
TestResult::TestResult()
- : test_part_results_(new internal::Vector<TestPartResult>),
- test_properties_(new internal::Vector<TestProperty>),
- death_test_count_(0),
+ : death_test_count_(0),
elapsed_time_(0) {
}
@@ -1783,24 +1805,28 @@ TestResult::~TestResult() {
// range from 0 to total_part_count() - 1. If i is not in that range,
// aborts the program.
const TestPartResult& TestResult::GetTestPartResult(int i) const {
- return test_part_results_->GetElement(i);
+ if (i < 0 || i >= total_part_count())
+ internal::posix::Abort();
+ return test_part_results_.at(i);
}
// Returns the i-th test property. i can range from 0 to
// test_property_count() - 1. If i is not in that range, aborts the
// program.
const TestProperty& TestResult::GetTestProperty(int i) const {
- return test_properties_->GetElement(i);
+ if (i < 0 || i >= test_property_count())
+ internal::posix::Abort();
+ return test_properties_.at(i);
}
// Clears the test part results.
void TestResult::ClearTestPartResults() {
- test_part_results_->Clear();
+ test_part_results_.clear();
}
// Adds a test part result to the list.
void TestResult::AddTestPartResult(const TestPartResult& test_part_result) {
- test_part_results_->PushBack(test_part_result);
+ test_part_results_.push_back(test_part_result);
}
// Adds a test property to the list. If a property with the same key as the
@@ -1811,11 +1837,11 @@ void TestResult::RecordProperty(const TestProperty& test_property) {
return;
}
internal::MutexLock lock(&test_properites_mutex_);
- TestProperty* const property_with_matching_key =
- test_properties_->FindIf(
- internal::TestPropertyKeyIs(test_property.key()));
- if (property_with_matching_key == NULL) {
- test_properties_->PushBack(test_property);
+ const std::vector<TestProperty>::iterator property_with_matching_key =
+ std::find_if(test_properties_.begin(), test_properties_.end(),
+ internal::TestPropertyKeyIs(test_property.key()));
+ if (property_with_matching_key == test_properties_.end()) {
+ test_properties_.push_back(test_property);
return;
}
property_with_matching_key->SetValue(test_property.value());
@@ -1838,8 +1864,8 @@ bool TestResult::ValidateTestProperty(const TestProperty& test_property) {
// Clears the object.
void TestResult::Clear() {
- test_part_results_->Clear();
- test_properties_->Clear();
+ test_part_results_.clear();
+ test_properties_.clear();
death_test_count_ = 0;
elapsed_time_ = 0;
}
@@ -1860,7 +1886,7 @@ static bool TestPartFatallyFailed(const TestPartResult& result) {
// Returns true iff the test fatally failed.
bool TestResult::HasFatalFailure() const {
- return test_part_results_->CountIf(TestPartFatallyFailed) > 0;
+ return CountIf(test_part_results_, TestPartFatallyFailed) > 0;
}
// Returns true iff the test part non-fatally failed.
@@ -1870,18 +1896,18 @@ static bool TestPartNonfatallyFailed(const TestPartResult& result) {
// Returns true iff the test has a non-fatal failure.
bool TestResult::HasNonfatalFailure() const {
- return test_part_results_->CountIf(TestPartNonfatallyFailed) > 0;
+ return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0;
}
// Gets the number of all test parts. This is the sum of the number
// of successful test parts and the number of failed test parts.
int TestResult::total_part_count() const {
- return test_part_results_->size();
+ return static_cast<int>(test_part_results_.size());
}
// Returns the number of the test properties.
int TestResult::test_property_count() const {
- return test_properties_->size();
+ return static_cast<int>(test_properties_.size());
}
// class Test
@@ -1965,7 +1991,7 @@ bool Test::HasSameFixtureClass() {
// Info about the first test in the current test case.
const internal::TestInfoImpl* const first_test_info =
- test_case->test_info_list().GetElement(0)->impl();
+ test_case->test_info_list()[0]->impl();
const internal::TypeId first_fixture_id = first_test_info->fixture_class_id();
const char* const first_test_name = first_test_info->name();
@@ -2093,14 +2119,14 @@ bool Test::HasNonfatalFailure() {
// Constructs a TestInfo object. It assumes ownership of the test factory
// object via impl_.
-TestInfo::TestInfo(const char* test_case_name,
- const char* name,
- const char* test_case_comment,
- const char* comment,
+TestInfo::TestInfo(const char* a_test_case_name,
+ const char* a_name,
+ const char* a_test_case_comment,
+ const char* a_comment,
internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory) {
- impl_ = new internal::TestInfoImpl(this, test_case_name, name,
- test_case_comment, comment,
+ impl_ = new internal::TestInfoImpl(this, a_test_case_name, a_name,
+ a_test_case_comment, a_comment,
fixture_class_id, factory);
}
@@ -2309,26 +2335,26 @@ void TestInfoImpl::Run() {
// Gets the number of successful tests in this test case.
int TestCase::successful_test_count() const {
- return test_info_list_->CountIf(TestPassed);
+ return CountIf(test_info_list_, TestPassed);
}
// Gets the number of failed tests in this test case.
int TestCase::failed_test_count() const {
- return test_info_list_->CountIf(TestFailed);
+ return CountIf(test_info_list_, TestFailed);
}
int TestCase::disabled_test_count() const {
- return test_info_list_->CountIf(TestDisabled);
+ return CountIf(test_info_list_, TestDisabled);
}
// Get the number of tests in this test case that should run.
int TestCase::test_to_run_count() const {
- return test_info_list_->CountIf(ShouldRunTest);
+ return CountIf(test_info_list_, ShouldRunTest);
}
// Gets the number of all tests.
int TestCase::total_test_count() const {
- return test_info_list_->size();
+ return static_cast<int>(test_info_list_.size());
}
// Creates a TestCase with the given name.
@@ -2338,13 +2364,11 @@ int TestCase::total_test_count() const {
// name: name of the test case
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
-TestCase::TestCase(const char* name, const char* comment,
+TestCase::TestCase(const char* a_name, const char* a_comment,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc)
- : name_(name),
- comment_(comment),
- test_info_list_(new internal::Vector<TestInfo*>),
- test_indices_(new internal::Vector<int>),
+ : name_(a_name),
+ comment_(a_comment),
set_up_tc_(set_up_tc),
tear_down_tc_(tear_down_tc),
should_run_(false),
@@ -2354,28 +2378,28 @@ TestCase::TestCase(const char* name, const char* comment,
// Destructor of TestCase.
TestCase::~TestCase() {
// Deletes every Test in the collection.
- test_info_list_->ForEach(internal::Delete<TestInfo>);
+ ForEach(test_info_list_, internal::Delete<TestInfo>);
}
// Returns the i-th test among all the tests. i can range from 0 to
// total_test_count() - 1. If i is not in that range, returns NULL.
const TestInfo* TestCase::GetTestInfo(int i) const {
- const int index = test_indices_->GetElementOr(i, -1);
- return index < 0 ? NULL : test_info_list_->GetElement(index);
+ const int index = GetElementOr(test_indices_, i, -1);
+ return index < 0 ? NULL : test_info_list_[index];
}
// Returns the i-th test among all the tests. i can range from 0 to
// total_test_count() - 1. If i is not in that range, returns NULL.
TestInfo* TestCase::GetMutableTestInfo(int i) {
- const int index = test_indices_->GetElementOr(i, -1);
- return index < 0 ? NULL : test_info_list_->GetElement(index);
+ const int index = GetElementOr(test_indices_, i, -1);
+ return index < 0 ? NULL : test_info_list_[index];
}
// Adds a test to this test case. Will delete the test upon
// destruction of the TestCase object.
void TestCase::AddTestInfo(TestInfo * test_info) {
- test_info_list_->PushBack(test_info);
- test_indices_->PushBack(test_indices_->size());
+ test_info_list_.push_back(test_info);
+ test_indices_.push_back(static_cast<int>(test_indices_.size()));
}
// Runs every test in this TestCase.
@@ -2405,7 +2429,7 @@ void TestCase::Run() {
// Clears the results of all tests in this test case.
void TestCase::ClearResult() {
- test_info_list_->ForEach(internal::TestInfoImpl::ClearTestResult);
+ ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult);
}
// Returns true iff test passed.
@@ -2432,13 +2456,13 @@ bool TestCase::ShouldRunTest(const TestInfo *test_info) {
// Shuffles the tests in this test case.
void TestCase::ShuffleTests(internal::Random* random) {
- test_indices_->Shuffle(random);
+ Shuffle(random, &test_indices_);
}
// Restores the test order to before the first shuffle.
void TestCase::UnshuffleTests() {
- for (int i = 0; i < test_indices_->size(); i++) {
- test_indices_->GetMutableElement(i) = i;
+ for (size_t i = 0; i < test_indices_.size(); i++) {
+ test_indices_[i] = static_cast<int>(i);
}
}
@@ -2614,10 +2638,15 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
const WORD old_color_attrs = buffer_info.wAttributes;
+ // We need to flush the stream buffers into the console before each
+ // SetConsoleTextAttribute call lest it affect the text that is already
+ // printed but has not yet reached the console.
+ fflush(stdout);
SetConsoleTextAttribute(stdout_handle,
GetColorAttribute(color) | FOREGROUND_INTENSITY);
vprintf(fmt, args);
+ fflush(stdout);
// Restores the text color.
SetConsoleTextAttribute(stdout_handle, old_color_attrs);
#else
@@ -2880,26 +2909,24 @@ class TestEventRepeater : public TestEventListener {
// in death test child processes.
bool forwarding_enabled_;
// The list of listeners that receive events.
- Vector<TestEventListener*> listeners_;
+ std::vector<TestEventListener*> listeners_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater);
};
TestEventRepeater::~TestEventRepeater() {
- for (int i = 0; i < listeners_.size(); i++) {
- delete listeners_.GetElement(i);
- }
+ ForEach(listeners_, Delete<TestEventListener>);
}
void TestEventRepeater::Append(TestEventListener *listener) {
- listeners_.PushBack(listener);
+ listeners_.push_back(listener);
}
// TODO(vladl@google.com): Factor the search functionality into Vector::Find.
TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
- for (int i = 0; i < listeners_.size(); ++i) {
- if (listeners_.GetElement(i) == listener) {
- listeners_.Erase(i);
+ for (size_t i = 0; i < listeners_.size(); ++i) {
+ if (listeners_[i] == listener) {
+ listeners_.erase(listeners_.begin() + i);
return listener;
}
}
@@ -2912,8 +2939,8 @@ TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
#define GTEST_REPEATER_METHOD_(Name, Type) \
void TestEventRepeater::Name(const Type& parameter) { \
if (forwarding_enabled_) { \
- for (int i = 0; i < listeners_.size(); i++) { \
- listeners_.GetElement(i)->Name(parameter); \
+ for (size_t i = 0; i < listeners_.size(); i++) { \
+ listeners_[i]->Name(parameter); \
} \
} \
}
@@ -2923,7 +2950,7 @@ void TestEventRepeater::Name(const Type& parameter) { \
void TestEventRepeater::Name(const Type& parameter) { \
if (forwarding_enabled_) { \
for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \
- listeners_.GetElement(i)->Name(parameter); \
+ listeners_[i]->Name(parameter); \
} \
} \
}
@@ -2946,8 +2973,8 @@ GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)
void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,
int iteration) {
if (forwarding_enabled_) {
- for (int i = 0; i < listeners_.size(); i++) {
- listeners_.GetElement(i)->OnTestIterationStart(unit_test, iteration);
+ for (size_t i = 0; i < listeners_.size(); i++) {
+ listeners_[i]->OnTestIterationStart(unit_test, iteration);
}
}
}
@@ -2956,7 +2983,7 @@ void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,
int iteration) {
if (forwarding_enabled_) {
for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) {
- listeners_.GetElement(i)->OnTestIterationEnd(unit_test, iteration);
+ listeners_[i]->OnTestIterationEnd(unit_test, iteration);
}
}
}
@@ -3152,14 +3179,11 @@ String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) {
// </testsuite>
// </testsuites>
-// Formats the given time in milliseconds as seconds. The returned
-// C-string is owned by this function and cannot be released by the
-// caller. Calling the function again invalidates the previous
-// result.
-const char* FormatTimeInMillisAsSeconds(TimeInMillis ms) {
- static String str;
- str = (Message() << (ms/1000.0)).GetString();
- return str.c_str();
+// Formats the given time in milliseconds as seconds.
+std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
+ ::std::stringstream ss;
+ ss << ms/1000.0;
+ return ss.str();
}
// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
@@ -3170,7 +3194,8 @@ void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,
for (;;) {
const char* const next_segment = strstr(segment, "]]>");
if (next_segment != NULL) {
- stream->write(segment, next_segment - segment);
+ stream->write(
+ segment, static_cast<std::streamsize>(next_segment - segment));
*stream << "]]>]]&gt;<![CDATA[";
segment = next_segment + strlen("]]>");
} else {
@@ -3232,7 +3257,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,
test_case.disabled_test_count());
fprintf(out,
"errors=\"0\" time=\"%s\">\n",
- FormatTimeInMillisAsSeconds(test_case.elapsed_time()));
+ FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str());
for (int i = 0; i < test_case.total_test_count(); ++i) {
StrStream stream;
OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i));
@@ -3251,7 +3276,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
unit_test.total_test_count(),
unit_test.failed_test_count(),
unit_test.disabled_test_count(),
- FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
+ FormatTimeInMillisAsSeconds(unit_test.elapsed_time()).c_str());
if (GTEST_FLAG(shuffle)) {
fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed());
}
@@ -3512,8 +3537,7 @@ Environment* UnitTest::AddEnvironment(Environment* env) {
return NULL;
}
- impl_->environments()->PushBack(env);
- impl_->environments_in_reverse_order()->PushFront(env);
+ impl_->environments().push_back(env);
return env;
}
@@ -3544,12 +3568,12 @@ void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
msg << message;
internal::MutexLock lock(&mutex_);
- if (impl_->gtest_trace_stack()->size() > 0) {
+ if (impl_->gtest_trace_stack().size() > 0) {
msg << "\n" << GTEST_NAME_ << " trace:";
- for (int i = 0; i < impl_->gtest_trace_stack()->size(); i++) {
- const internal::TraceInfo& trace =
- impl_->gtest_trace_stack()->GetElement(i);
+ for (int i = static_cast<int>(impl_->gtest_trace_stack().size());
+ i > 0; --i) {
+ const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];
msg << "\n" << internal::FormatFileLocation(trace.file, trace.line)
<< " " << trace.message;
}
@@ -3714,14 +3738,14 @@ UnitTest::~UnitTest() {
// L < mutex_
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) {
internal::MutexLock lock(&mutex_);
- impl_->gtest_trace_stack()->PushFront(trace);
+ impl_->gtest_trace_stack().push_back(trace);
}
// Pops a trace from the per-thread Google Test trace stack.
// L < mutex_
void UnitTest::PopGTestTrace() {
internal::MutexLock lock(&mutex_);
- impl_->gtest_trace_stack()->PopFront(NULL);
+ impl_->gtest_trace_stack().pop_back();
}
namespace internal {
@@ -3767,10 +3791,10 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
UnitTestImpl::~UnitTestImpl() {
// Deletes every TestCase.
- test_cases_.ForEach(internal::Delete<TestCase>);
+ ForEach(test_cases_, internal::Delete<TestCase>);
// Deletes every Environment.
- environments_.ForEach(internal::Delete<Environment>);
+ ForEach(environments_, internal::Delete<Environment>);
delete os_stack_trace_getter_;
}
@@ -3862,9 +3886,11 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc) {
// Can we find a TestCase with the given name?
- TestCase** test_case = test_cases_.FindIf(TestCaseNameIs(test_case_name));
+ const std::vector<TestCase*>::const_iterator test_case =
+ std::find_if(test_cases_.begin(), test_cases_.end(),
+ TestCaseNameIs(test_case_name));
- if (test_case != NULL)
+ if (test_case != test_cases_.end())
return *test_case;
// No. Let's create one.
@@ -3878,18 +3904,20 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
// defined so far. This only works when the test cases haven't
// been shuffled. Otherwise we may end up running a death test
// after a non-death test.
- test_cases_.Insert(new_test_case, ++last_death_test_case_);
+ ++last_death_test_case_;
+ test_cases_.insert(test_cases_.begin() + last_death_test_case_,
+ new_test_case);
} else {
// No. Appends to the end of the list.
- test_cases_.PushBack(new_test_case);
+ test_cases_.push_back(new_test_case);
}
- test_case_indices_.PushBack(test_case_indices_.size());
+ test_case_indices_.push_back(static_cast<int>(test_case_indices_.size()));
return new_test_case;
}
// Helpers for setting up / tearing down the given environment. They
-// are for use in the Vector::ForEach() method.
+// are for use in the ForEach() function.
static void SetUpEnvironment(Environment* env) { env->SetUp(); }
static void TearDownEnvironment(Environment* env) { env->TearDown(); }
@@ -3985,20 +4013,22 @@ int UnitTestImpl::RunAllTests() {
if (has_tests_to_run) {
// Sets up all environments beforehand.
repeater->OnEnvironmentsSetUpStart(*parent_);
- environments_.ForEach(SetUpEnvironment);
+ ForEach(environments_, SetUpEnvironment);
repeater->OnEnvironmentsSetUpEnd(*parent_);
// Runs the tests only if there was no fatal failure during global
// set-up.
if (!Test::HasFatalFailure()) {
- for (int i = 0; i < total_test_case_count(); i++) {
- GetMutableTestCase(i)->Run();
+ for (int test_index = 0; test_index < total_test_case_count();
+ test_index++) {
+ GetMutableTestCase(test_index)->Run();
}
}
// Tears down all environments in reverse order afterwards.
repeater->OnEnvironmentsTearDownStart(*parent_);
- environments_in_reverse_order_.ForEach(TearDownEnvironment);
+ std::for_each(environments_.rbegin(), environments_.rend(),
+ TearDownEnvironment);
repeater->OnEnvironmentsTearDownEnd(*parent_);
}
@@ -4144,13 +4174,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
// this shard.
int num_runnable_tests = 0;
int num_selected_tests = 0;
- for (int i = 0; i < test_cases_.size(); i++) {
- TestCase* const test_case = test_cases_.GetElement(i);
+ for (size_t i = 0; i < test_cases_.size(); i++) {
+ TestCase* const test_case = test_cases_[i];
const String &test_case_name = test_case->name();
test_case->set_should_run(false);
- for (int j = 0; j < test_case->test_info_list().size(); j++) {
- TestInfo* const test_info = test_case->test_info_list().GetElement(j);
+ for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
+ TestInfo* const test_info = test_case->test_info_list()[j];
const String test_name(test_info->name());
// A test is disabled if test case name or test name matches
// kDisableTestFilter.
@@ -4187,13 +4217,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
// Prints the names of the tests matching the user-specified filter flag.
void UnitTestImpl::ListTestsMatchingFilter() {
- for (int i = 0; i < test_cases_.size(); i++) {
- const TestCase* const test_case = test_cases_.GetElement(i);
+ for (size_t i = 0; i < test_cases_.size(); i++) {
+ const TestCase* const test_case = test_cases_[i];
bool printed_test_case_name = false;
- for (int j = 0; j < test_case->test_info_list().size(); j++) {
+ for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
const TestInfo* const test_info =
- test_case->test_info_list().GetElement(j);
+ test_case->test_info_list()[j];
if (test_info->matches_filter()) {
if (!printed_test_case_name) {
printed_test_case_name = true;
@@ -4241,43 +4271,43 @@ TestResult* UnitTestImpl::current_test_result() {
// making sure that death tests are still run first.
void UnitTestImpl::ShuffleTests() {
// Shuffles the death test cases.
- test_case_indices_.ShuffleRange(random(), 0, last_death_test_case_ + 1);
+ ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_);
// Shuffles the non-death test cases.
- test_case_indices_.ShuffleRange(random(), last_death_test_case_ + 1,
- test_cases_.size());
+ ShuffleRange(random(), last_death_test_case_ + 1,
+ static_cast<int>(test_cases_.size()), &test_case_indices_);
// Shuffles the tests inside each test case.
- for (int i = 0; i < test_cases_.size(); i++) {
- test_cases_.GetElement(i)->ShuffleTests(random());
+ for (size_t i = 0; i < test_cases_.size(); i++) {
+ test_cases_[i]->ShuffleTests(random());
}
}
// Restores the test cases and tests to their order before the first shuffle.
void UnitTestImpl::UnshuffleTests() {
- for (int i = 0; i < test_cases_.size(); i++) {
+ for (size_t i = 0; i < test_cases_.size(); i++) {
// Unshuffles the tests in each test case.
- test_cases_.GetElement(i)->UnshuffleTests();
+ test_cases_[i]->UnshuffleTests();
// Resets the index of each test case.
- test_case_indices_.GetMutableElement(i) = i;
+ test_case_indices_[i] = static_cast<int>(i);
}
}
// TestInfoImpl constructor. The new instance assumes ownership of the test
// factory object.
TestInfoImpl::TestInfoImpl(TestInfo* parent,
- const char* test_case_name,
- const char* name,
- const char* test_case_comment,
- const char* comment,
- TypeId fixture_class_id,
+ const char* a_test_case_name,
+ const char* a_name,
+ const char* a_test_case_comment,
+ const char* a_comment,
+ TypeId a_fixture_class_id,
internal::TestFactoryBase* factory) :
parent_(parent),
- test_case_name_(String(test_case_name)),
- name_(String(name)),
- test_case_comment_(String(test_case_comment)),
- comment_(String(comment)),
- fixture_class_id_(fixture_class_id),
+ test_case_name_(String(a_test_case_name)),
+ name_(String(a_name)),
+ test_case_comment_(String(a_test_case_comment)),
+ comment_(String(a_comment)),
+ fixture_class_id_(a_fixture_class_id),
should_run_(false),
is_disabled_(false),
matches_filter_(false),
@@ -4324,6 +4354,18 @@ bool AlwaysTrue() {
return true;
}
+// If *pstr starts with the given prefix, modifies *pstr to be right
+// past the prefix and returns true; otherwise leaves *pstr unchanged
+// and returns false. None of pstr, *pstr, and prefix can be NULL.
+bool SkipPrefix(const char* prefix, const char** pstr) {
+ const size_t prefix_len = strlen(prefix);
+ if (strncmp(*pstr, prefix, prefix_len) == 0) {
+ *pstr += prefix_len;
+ return true;
+ }
+ return false;
+}
+
// Parses a string as a command line flag. The string should have
// the format "--flag=value". When def_optional is true, the "=value"
// part can be omitted.
@@ -4413,6 +4455,21 @@ bool ParseStringFlag(const char* str, const char* flag, String* value) {
return true;
}
+// Determines whether a string has a prefix that Google Test uses for its
+// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_.
+// If Google Test detects that a command line flag has its prefix but is not
+// recognized, it will print its help message. Flags starting with
+// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test
+// internal flags and do not trigger the help message.
+static bool HasGoogleTestFlagPrefix(const char* str) {
+ return (SkipPrefix("--", &str) ||
+ SkipPrefix("-", &str) ||
+ SkipPrefix("/", &str)) &&
+ !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) &&
+ (SkipPrefix(GTEST_FLAG_PREFIX_, &str) ||
+ SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str));
+}
+
// Prints a string containing code-encoded text. The following escape
// sequences can be used in the string to control the text color:
//
@@ -4553,6 +4610,8 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) ||
ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||
ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||
+ ParseInt32Flag(arg, kStackTraceDepthFlag,
+ &GTEST_FLAG(stack_trace_depth)) ||
ParseBoolFlag(arg, kThrowOnFailureFlag, &GTEST_FLAG(throw_on_failure))
) {
// Yes. Shift the remainder of the argv list left by one. Note
@@ -4570,7 +4629,10 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
// an element.
i--;
} else if (arg_string == "--help" || arg_string == "-h" ||
- arg_string == "-?" || arg_string == "/?") {
+ arg_string == "-?" || arg_string == "/?" ||
+ HasGoogleTestFlagPrefix(arg)) {
+ // Both help flag and unrecognized Google Test flags (excluding
+ // internal ones) trigger help display.
g_help_flag = true;
}
}
diff --git a/gtest/test/gtest-death-test_test.cc b/gtest/test/gtest-death-test_test.cc
index 288c70a..ed5b53b 100644
--- a/gtest/test/gtest-death-test_test.cc
+++ b/gtest/test/gtest-death-test_test.cc
@@ -103,6 +103,21 @@ class ReplaceDeathTestFactory {
} // namespace internal
} // namespace testing
+void DieInside(const char* function) {
+ fprintf(stderr, "death inside %s().", function);
+ fflush(stderr);
+ // We call _exit() instead of exit(), as the former is a direct
+ // system call and thus safer in the presence of threads. exit()
+ // will invoke user-defined exit-hooks, which may do dangerous
+ // things that conflict with death tests.
+ //
+ // Some compilers can recognize that _exit() never returns and issue the
+ // 'unreachable code' warning for code following this function, unless
+ // fooled by a fake condition.
+ if (AlwaysTrue())
+ _exit(1);
+}
+
// Tests that death tests work.
class TestForDeathTest : public testing::Test {
@@ -114,23 +129,12 @@ class TestForDeathTest : public testing::Test {
}
// A static member function that's expected to die.
- static void StaticMemberFunction() {
- fprintf(stderr, "%s", "death inside StaticMemberFunction().");
- fflush(stderr);
- // We call _exit() instead of exit(), as the former is a direct
- // system call and thus safer in the presence of threads. exit()
- // will invoke user-defined exit-hooks, which may do dangerous
- // things that conflict with death tests.
- _exit(1);
- }
+ static void StaticMemberFunction() { DieInside("StaticMemberFunction"); }
// A method of the test fixture that may die.
void MemberFunction() {
- if (should_die_) {
- fprintf(stderr, "%s", "death inside MemberFunction().");
- fflush(stderr);
- _exit(1);
- }
+ if (should_die_)
+ DieInside("MemberFunction");
}
// True iff MemberFunction() should die.
@@ -145,9 +149,8 @@ class MayDie {
// A member function that may die.
void MemberFunction() const {
- if (should_die_) {
- GTEST_LOG_(FATAL) << "death inside MayDie::MemberFunction().";
- }
+ if (should_die_)
+ DieInside("MayDie::MemberFunction");
}
private:
@@ -156,27 +159,24 @@ class MayDie {
};
// A global function that's expected to die.
-void GlobalFunction() {
- GTEST_LOG_(FATAL) << "death inside GlobalFunction().";
-}
+void GlobalFunction() { DieInside("GlobalFunction"); }
// A non-void function that's expected to die.
int NonVoidFunction() {
- GTEST_LOG_(FATAL) << "death inside NonVoidFunction().";
+ DieInside("NonVoidFunction");
return 1;
}
// A unary function that may die.
void DieIf(bool should_die) {
- if (should_die) {
- GTEST_LOG_(FATAL) << "death inside DieIf().";
- }
+ if (should_die)
+ DieInside("DieIf");
}
// A binary function that may die.
bool DieIfLessThan(int x, int y) {
if (x < y) {
- GTEST_LOG_(FATAL) << "death inside DieIfLessThan().";
+ DieInside("DieIfLessThan");
}
return true;
}
@@ -191,7 +191,7 @@ void DeathTestSubroutine() {
int DieInDebugElse12(int* sideeffect) {
if (sideeffect) *sideeffect = 12;
#ifndef NDEBUG
- GTEST_LOG_(FATAL) << "debug death inside DieInDebugElse12()";
+ DieInside("DieInDebugElse12");
#endif // NDEBUG
return 12;
}
@@ -410,7 +410,7 @@ void SetPthreadFlag() {
} // namespace
-#if GTEST_HAS_CLONE
+#if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD
TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
if (!testing::GTEST_FLAG(death_test_use_fork)) {
@@ -422,7 +422,7 @@ TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
}
}
-#endif // GTEST_HAS_CLONE
+#endif // GTEST_HAS_CLONE && GTEST_HAS_PTHREAD
// Tests that a method of another class can be used in a death test.
TEST_F(TestForDeathTest, MethodOfAnotherClass) {
@@ -449,10 +449,8 @@ TEST_F(TestForDeathTest, AcceptsAnythingConvertibleToRE) {
EXPECT_DEATH(GlobalFunction(), regex_str);
#endif // GTEST_HAS_GLOBAL_STRING
-#if GTEST_HAS_STD_STRING
const ::std::string regex_std_str(regex_c_str);
EXPECT_DEATH(GlobalFunction(), regex_std_str);
-#endif // GTEST_HAS_STD_STRING
}
// Tests that a non-void function can be used in a death test.
@@ -659,24 +657,6 @@ static void TestExitMacros() {
EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), "");
ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), "");
-#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
- // MinGW (as of MinGW 5.1.6 and MSYS 1.0.11) does not tag crashed
- // processes with non-zero exit code and does not honor calls to
- // SetErrorMode(SEM_NOGPFAULTERRORBOX) that are supposed to suppress
- // error pop-ups.
- EXPECT_EXIT({
- testing::GTEST_FLAG(catch_exceptions) = false;
- *static_cast<int*>(NULL) = 1;
- }, testing::ExitedWithCode(0xC0000005), "") << "foo";
-
- EXPECT_NONFATAL_FAILURE({ // NOLINT
- EXPECT_EXIT({
- testing::GTEST_FLAG(catch_exceptions) = false;
- *static_cast<int*>(NULL) = 1;
- }, testing::ExitedWithCode(0), "") << "This failure is expected.";
- }, "This failure is expected.");
-#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
-
#if GTEST_OS_WINDOWS
// Of all signals effects on the process exit code, only those of SIGABRT
// are documented on Windows.
@@ -1131,8 +1111,10 @@ TEST(EnvironmentTest, HandleFitsIntoSizeT) {
// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED trigger
// failures when death tests are available on the system.
TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) {
- EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(false) << "failure", "false.*failure");
- ASSERT_DEATH_IF_SUPPORTED(GTEST_CHECK_(false) << "failure", "false.*failure");
+ EXPECT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestExpectMacro"),
+ "death inside CondDeathTestExpectMacro");
+ ASSERT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestAssertMacro"),
+ "death inside CondDeathTestAssertMacro");
// Empty statement will not crash, which must trigger a failure.
EXPECT_NONFATAL_FAILURE(EXPECT_DEATH_IF_SUPPORTED(;, ""), "");
diff --git a/gtest/test/gtest-filepath_test.cc b/gtest/test/gtest-filepath_test.cc
index 5bc4daf..6250282 100644
--- a/gtest/test/gtest-filepath_test.cc
+++ b/gtest/test/gtest-filepath_test.cc
@@ -151,6 +151,36 @@ TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) {
.RemoveDirectoryName().c_str());
}
+#if GTEST_HAS_ALT_PATH_SEP_
+
+// Tests that RemoveDirectoryName() works with the alternate separator
+// on Windows.
+
+// RemoveDirectoryName("/afile") -> "afile"
+TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) {
+ EXPECT_STREQ("afile",
+ FilePath("/afile").RemoveDirectoryName().c_str());
+}
+
+// RemoveDirectoryName("adir/") -> ""
+TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) {
+ EXPECT_STREQ("",
+ FilePath("adir/").RemoveDirectoryName().c_str());
+}
+
+// RemoveDirectoryName("adir/afile") -> "afile"
+TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) {
+ EXPECT_STREQ("afile",
+ FilePath("adir/afile").RemoveDirectoryName().c_str());
+}
+
+// RemoveDirectoryName("adir/subdir/afile") -> "afile"
+TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) {
+ EXPECT_STREQ("afile",
+ FilePath("adir/subdir/afile").RemoveDirectoryName().c_str());
+}
+
+#endif
// RemoveFileName "" -> "./"
TEST(RemoveFileNameTest, EmptyName) {
@@ -190,6 +220,36 @@ TEST(RemoveFileNameTest, GivesRootDir) {
FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().c_str());
}
+#if GTEST_HAS_ALT_PATH_SEP_
+
+// Tests that RemoveFileName() works with the alternate separator on
+// Windows.
+
+// RemoveFileName("adir/") -> "adir/"
+TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) {
+ EXPECT_STREQ("adir" GTEST_PATH_SEP_,
+ FilePath("adir/").RemoveFileName().c_str());
+}
+
+// RemoveFileName("adir/afile") -> "adir/"
+TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) {
+ EXPECT_STREQ("adir" GTEST_PATH_SEP_,
+ FilePath("adir/afile").RemoveFileName().c_str());
+}
+
+// RemoveFileName("adir/subdir/afile") -> "adir/subdir/"
+TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) {
+ EXPECT_STREQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_,
+ FilePath("adir/subdir/afile").RemoveFileName().c_str());
+}
+
+// RemoveFileName("/afile") -> "\"
+TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) {
+ EXPECT_STREQ(GTEST_PATH_SEP_,
+ FilePath("/afile").RemoveFileName().c_str());
+}
+
+#endif
TEST(MakeFileNameTest, GenerateWhenNumberIsZero) {
FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"),
@@ -295,6 +355,10 @@ TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) {
EXPECT_STREQ(
"foo",
FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().c_str());
+#if GTEST_HAS_ALT_PATH_SEP_
+ EXPECT_STREQ("foo",
+ FilePath("foo/").RemoveTrailingPathSeparator().c_str());
+#endif
}
// RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/"
@@ -397,6 +461,22 @@ TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) {
FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).c_str());
}
+#if GTEST_HAS_ALT_PATH_SEP_
+
+// Tests that separators at the end of the string are normalized
+// regardless of their combination (e.g. "foo\" =="foo/\" ==
+// "foo\\/").
+TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) {
+ EXPECT_STREQ("foo" GTEST_PATH_SEP_,
+ FilePath("foo/").c_str());
+ EXPECT_STREQ("foo" GTEST_PATH_SEP_,
+ FilePath("foo" GTEST_PATH_SEP_ "/").c_str());
+ EXPECT_STREQ("foo" GTEST_PATH_SEP_,
+ FilePath("foo//" GTEST_PATH_SEP_).c_str());
+}
+
+#endif
+
TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) {
FilePath default_path;
FilePath non_default_path("path");
@@ -566,6 +646,9 @@ TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) {
TEST(FilePathTest, IsDirectory) {
EXPECT_FALSE(FilePath("cola").IsDirectory());
EXPECT_TRUE(FilePath("koala" GTEST_PATH_SEP_).IsDirectory());
+#if GTEST_HAS_ALT_PATH_SEP_
+ EXPECT_TRUE(FilePath("koala/").IsDirectory());
+#endif
}
TEST(FilePathTest, IsAbsolutePath) {
@@ -575,14 +658,33 @@ TEST(FilePathTest, IsAbsolutePath) {
EXPECT_TRUE(FilePath("c:\\" GTEST_PATH_SEP_ "is_not"
GTEST_PATH_SEP_ "relative").IsAbsolutePath());
EXPECT_FALSE(FilePath("c:foo" GTEST_PATH_SEP_ "bar").IsAbsolutePath());
+ EXPECT_TRUE(FilePath("c:/" GTEST_PATH_SEP_ "is_not"
+ GTEST_PATH_SEP_ "relative").IsAbsolutePath());
#else
EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative")
.IsAbsolutePath());
#endif // GTEST_OS_WINDOWS
}
+TEST(FilePathTest, IsRootDirectory) {
+#if GTEST_OS_WINDOWS
+ EXPECT_TRUE(FilePath("a:\\").IsRootDirectory());
+ EXPECT_TRUE(FilePath("Z:/").IsRootDirectory());
+ EXPECT_TRUE(FilePath("e://").IsRootDirectory());
+ EXPECT_FALSE(FilePath("").IsRootDirectory());
+ EXPECT_FALSE(FilePath("b:").IsRootDirectory());
+ EXPECT_FALSE(FilePath("b:a").IsRootDirectory());
+ EXPECT_FALSE(FilePath("8:/").IsRootDirectory());
+ EXPECT_FALSE(FilePath("c|/").IsRootDirectory());
+#else
+ EXPECT_TRUE(FilePath("/").IsRootDirectory());
+ EXPECT_TRUE(FilePath("//").IsRootDirectory());
+ EXPECT_FALSE(FilePath("").IsRootDirectory());
+ EXPECT_FALSE(FilePath("\\").IsRootDirectory());
+ EXPECT_FALSE(FilePath("/x").IsRootDirectory());
+#endif
+}
+
} // namespace
} // namespace internal
} // namespace testing
-
-#undef GTEST_PATH_SEP_
diff --git a/gtest/test/gtest-listener_test.cc b/gtest/test/gtest-listener_test.cc
index f12f518..c9be39a 100644
--- a/gtest/test/gtest-listener_test.cc
+++ b/gtest/test/gtest-listener_test.cc
@@ -34,15 +34,7 @@
// right times.
#include <gtest/gtest.h>
-
-// Indicates that this translation unit is part of Google Test's
-// implementation. It must come before gtest-internal-inl.h is
-// included, or there will be a compiler error. This trick is to
-// prevent a user from accidentally including gtest-internal-inl.h in
-// his code.
-#define GTEST_IMPLEMENTATION_ 1
-#include "src/gtest-internal-inl.h" // For Vector.
-#undef GTEST_IMPLEMENTATION_
+#include <vector>
using ::testing::AddGlobalTestEnvironment;
using ::testing::Environment;
@@ -54,10 +46,9 @@ using ::testing::TestInfo;
using ::testing::TestPartResult;
using ::testing::UnitTest;
using ::testing::internal::String;
-using ::testing::internal::Vector;
// Used by tests to register their events.
-Vector<String>* g_events = NULL;
+std::vector<String>* g_events = NULL;
namespace testing {
namespace internal {
@@ -68,7 +59,7 @@ class EventRecordingListener : public TestEventListener {
protected:
virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {
- g_events->PushBack(GetFullMethodName("OnTestProgramStart"));
+ g_events->push_back(GetFullMethodName("OnTestProgramStart"));
}
virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
@@ -76,43 +67,43 @@ class EventRecordingListener : public TestEventListener {
Message message;
message << GetFullMethodName("OnTestIterationStart")
<< "(" << iteration << ")";
- g_events->PushBack(message.GetString());
+ g_events->push_back(message.GetString());
}
virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {
- g_events->PushBack(GetFullMethodName("OnEnvironmentsSetUpStart"));
+ g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpStart"));
}
virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {
- g_events->PushBack(GetFullMethodName("OnEnvironmentsSetUpEnd"));
+ g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpEnd"));
}
virtual void OnTestCaseStart(const TestCase& /*test_case*/) {
- g_events->PushBack(GetFullMethodName("OnTestCaseStart"));
+ g_events->push_back(GetFullMethodName("OnTestCaseStart"));
}
virtual void OnTestStart(const TestInfo& /*test_info*/) {
- g_events->PushBack(GetFullMethodName("OnTestStart"));
+ g_events->push_back(GetFullMethodName("OnTestStart"));
}
virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {
- g_events->PushBack(GetFullMethodName("OnTestPartResult"));
+ g_events->push_back(GetFullMethodName("OnTestPartResult"));
}
virtual void OnTestEnd(const TestInfo& /*test_info*/) {
- g_events->PushBack(GetFullMethodName("OnTestEnd"));
+ g_events->push_back(GetFullMethodName("OnTestEnd"));
}
virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {
- g_events->PushBack(GetFullMethodName("OnTestCaseEnd"));
+ g_events->push_back(GetFullMethodName("OnTestCaseEnd"));
}
virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {
- g_events->PushBack(GetFullMethodName("OnEnvironmentsTearDownStart"));
+ g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownStart"));
}
virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {
- g_events->PushBack(GetFullMethodName("OnEnvironmentsTearDownEnd"));
+ g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownEnd"));
}
virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
@@ -120,11 +111,11 @@ class EventRecordingListener : public TestEventListener {
Message message;
message << GetFullMethodName("OnTestIterationEnd")
<< "(" << iteration << ")";
- g_events->PushBack(message.GetString());
+ g_events->push_back(message.GetString());
}
virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {
- g_events->PushBack(GetFullMethodName("OnTestProgramEnd"));
+ g_events->push_back(GetFullMethodName("OnTestProgramEnd"));
}
private:
@@ -140,42 +131,42 @@ class EventRecordingListener : public TestEventListener {
class EnvironmentInvocationCatcher : public Environment {
protected:
virtual void SetUp() {
- g_events->PushBack(String("Environment::SetUp"));
+ g_events->push_back(String("Environment::SetUp"));
}
virtual void TearDown() {
- g_events->PushBack(String("Environment::TearDown"));
+ g_events->push_back(String("Environment::TearDown"));
}
};
class ListenerTest : public Test {
protected:
static void SetUpTestCase() {
- g_events->PushBack(String("ListenerTest::SetUpTestCase"));
+ g_events->push_back(String("ListenerTest::SetUpTestCase"));
}
static void TearDownTestCase() {
- g_events->PushBack(String("ListenerTest::TearDownTestCase"));
+ g_events->push_back(String("ListenerTest::TearDownTestCase"));
}
virtual void SetUp() {
- g_events->PushBack(String("ListenerTest::SetUp"));
+ g_events->push_back(String("ListenerTest::SetUp"));
}
virtual void TearDown() {
- g_events->PushBack(String("ListenerTest::TearDown"));
+ g_events->push_back(String("ListenerTest::TearDown"));
}
};
TEST_F(ListenerTest, DoesFoo) {
// Test execution order within a test case is not guaranteed so we are not
// recording the test name.
- g_events->PushBack(String("ListenerTest::* Test Body"));
+ g_events->push_back(String("ListenerTest::* Test Body"));
SUCCEED(); // Triggers OnTestPartResult.
}
TEST_F(ListenerTest, DoesBar) {
- g_events->PushBack(String("ListenerTest::* Test Body"));
+ g_events->push_back(String("ListenerTest::* Test Body"));
SUCCEED(); // Triggers OnTestPartResult.
}
@@ -186,7 +177,7 @@ TEST_F(ListenerTest, DoesBar) {
using ::testing::internal::EnvironmentInvocationCatcher;
using ::testing::internal::EventRecordingListener;
-void VerifyResults(const Vector<String>& data,
+void VerifyResults(const std::vector<String>& data,
const char* const* expected_data,
int expected_data_size) {
const int actual_size = data.size();
@@ -199,18 +190,18 @@ void VerifyResults(const Vector<String>& data,
expected_data_size : actual_size;
int i = 0;
for (; i < shorter_size; ++i) {
- ASSERT_STREQ(expected_data[i], data.GetElement(i).c_str())
+ ASSERT_STREQ(expected_data[i], data[i].c_str())
<< "at position " << i;
}
// Prints extra elements in the actual data.
for (; i < actual_size; ++i) {
- printf(" Actual event #%d: %s\n", i, data.GetElement(i).c_str());
+ printf(" Actual event #%d: %s\n", i, data[i].c_str());
}
}
int main(int argc, char **argv) {
- Vector<String> events;
+ std::vector<String> events;
g_events = &events;
InitGoogleTest(&argc, argv);
diff --git a/gtest/test/gtest-message_test.cc b/gtest/test/gtest-message_test.cc
index 6c43c33..e42b034 100644
--- a/gtest/test/gtest-message_test.cc
+++ b/gtest/test/gtest-message_test.cc
@@ -68,6 +68,23 @@ TEST(MessageTest, ConstructsFromCString) {
EXPECT_STREQ("Hello", ToCString(msg));
}
+// Tests streaming a float.
+TEST(MessageTest, StreamsFloat) {
+ const char* const s = ToCString(Message() << 1.23456F << " " << 2.34567F);
+ // Both numbers should be printed with enough precision.
+ EXPECT_PRED_FORMAT2(testing::IsSubstring, "1.234560", s);
+ EXPECT_PRED_FORMAT2(testing::IsSubstring, " 2.345669", s);
+}
+
+// Tests streaming a double.
+TEST(MessageTest, StreamsDouble) {
+ const char* const s = ToCString(Message() << 1260570880.4555497 << " "
+ << 1260572265.1954534);
+ // Both numbers should be printed with enough precision.
+ EXPECT_PRED_FORMAT2(testing::IsSubstring, "1260570880.45", s);
+ EXPECT_PRED_FORMAT2(testing::IsSubstring, " 1260572265.19", s);
+}
+
// Tests streaming a non-char pointer.
TEST(MessageTest, StreamsPointer) {
int n = 0;
@@ -92,12 +109,7 @@ TEST(MessageTest, StreamsNullCString) {
EXPECT_STREQ("(null)", ToCString(Message() << p));
}
-#if GTEST_HAS_STD_STRING
-
// Tests streaming std::string.
-//
-// As std::string has problem in MSVC when exception is disabled, we only
-// test this where std::string can be used.
TEST(MessageTest, StreamsString) {
const ::std::string str("Hello");
EXPECT_STREQ("Hello", ToCString(Message() << str));
@@ -113,8 +125,6 @@ TEST(MessageTest, StreamsStringWithEmbeddedNUL) {
ToCString(Message() << string_with_nul));
}
-#endif // GTEST_HAS_STD_STRING
-
// Tests streaming a NUL char.
TEST(MessageTest, StreamsNULChar) {
EXPECT_STREQ("\\0", ToCString(Message() << '\0'));
diff --git a/gtest/test/gtest-options_test.cc b/gtest/test/gtest-options_test.cc
index 31ae327..2e2cbc9 100644
--- a/gtest/test/gtest-options_test.cc
+++ b/gtest/test/gtest-options_test.cc
@@ -89,61 +89,38 @@ TEST(XmlOutputTest, GetOutputFileSingleFile) {
}
TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) {
-#if GTEST_OS_WINDOWS
- GTEST_FLAG(output) = "xml:path\\";
+ GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_;
+ const std::string expected_output_file =
+ GetAbsolutePathOf(
+ FilePath(std::string("path") + GTEST_PATH_SEP_ +
+ GetCurrentExecutableName().c_str() + ".xml")).c_str();
const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile();
- EXPECT_TRUE(
- _strcmpi(output_file.c_str(),
- GetAbsolutePathOf(
- FilePath("path\\gtest-options_test.xml")).c_str()) == 0 ||
- _strcmpi(output_file.c_str(),
- GetAbsolutePathOf(
- FilePath("path\\gtest-options-ex_test.xml")).c_str()) == 0 ||
- _strcmpi(output_file.c_str(),
- GetAbsolutePathOf(
- FilePath("path\\gtest_all_test.xml")).c_str()) == 0)
- << " output_file = " << output_file;
+#if GTEST_OS_WINDOWS
+ EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str());
#else
- GTEST_FLAG(output) = "xml:path/";
- const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile();
- // TODO(wan@google.com): libtool causes the test binary file to be
- // named lt-gtest-options_test. Therefore the output file may be
- // named .../lt-gtest-options_test.xml. We should remove this
- // hard-coded logic when Chandler Carruth's libtool replacement is
- // ready.
- EXPECT_TRUE(output_file ==
- GetAbsolutePathOf(
- FilePath("path/gtest-options_test.xml")).c_str() ||
- output_file ==
- GetAbsolutePathOf(
- FilePath("path/lt-gtest-options_test.xml")).c_str() ||
- output_file ==
- GetAbsolutePathOf(
- FilePath("path/gtest_all_test.xml")).c_str() ||
- output_file ==
- GetAbsolutePathOf(
- FilePath("path/lt-gtest_all_test.xml")).c_str())
- << " output_file = " << output_file;
+ EXPECT_EQ(expected_output_file, output_file.c_str());
#endif
}
TEST(OutputFileHelpersTest, GetCurrentExecutableName) {
- const FilePath executable = GetCurrentExecutableName();
- const char* const exe_str = executable.c_str();
+ const std::string exe_str = GetCurrentExecutableName().c_str();
#if GTEST_OS_WINDOWS
- ASSERT_TRUE(_strcmpi("gtest-options_test", exe_str) == 0 ||
- _strcmpi("gtest-options-ex_test", exe_str) == 0 ||
- _strcmpi("gtest_all_test", exe_str) == 0)
- << "GetCurrentExecutableName() returns " << exe_str;
+ const bool success =
+ _strcmpi("gtest-options_test", exe_str.c_str()) == 0 ||
+ _strcmpi("gtest-options-ex_test", exe_str.c_str()) == 0 ||
+ _strcmpi("gtest_all_test", exe_str.c_str()) == 0 ||
+ _strcmpi("gtest_dll_test", exe_str.c_str()) == 0;
#else
// TODO(wan@google.com): remove the hard-coded "lt-" prefix when
// Chandler Carruth's libtool replacement is ready.
- EXPECT_TRUE(String(exe_str) == "gtest-options_test" ||
- String(exe_str) == "lt-gtest-options_test" ||
- String(exe_str) == "gtest_all_test" ||
- String(exe_str) == "lt-gtest_all_test")
- << "GetCurrentExecutableName() returns " << exe_str;
+ const bool success =
+ exe_str == "gtest-options_test" ||
+ exe_str == "gtest_all_test" ||
+ exe_str == "lt-gtest_all_test" ||
+ exe_str == "gtest_dll_test";
#endif // GTEST_OS_WINDOWS
+ if (!success)
+ FAIL() << "GetCurrentExecutableName() returns " << exe_str;
}
class XmlOutputChangeDirTest : public Test {
@@ -185,40 +162,17 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) {
}
TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) {
-#if GTEST_OS_WINDOWS
- GTEST_FLAG(output) = "xml:path\\";
+ GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_;
+ const std::string expected_output_file =
+ FilePath::ConcatPaths(
+ original_working_dir_,
+ FilePath(std::string("path") + GTEST_PATH_SEP_ +
+ GetCurrentExecutableName().c_str() + ".xml")).c_str();
const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile();
- EXPECT_TRUE(
- _strcmpi(output_file.c_str(),
- FilePath::ConcatPaths(
- original_working_dir_,
- FilePath("path\\gtest-options_test.xml")).c_str()) == 0 ||
- _strcmpi(output_file.c_str(),
- FilePath::ConcatPaths(
- original_working_dir_,
- FilePath("path\\gtest-options-ex_test.xml")).c_str()) == 0 ||
- _strcmpi(output_file.c_str(),
- FilePath::ConcatPaths(
- original_working_dir_,
- FilePath("path\\gtest_all_test.xml")).c_str()) == 0)
- << " output_file = " << output_file;
+#if GTEST_OS_WINDOWS
+ EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str());
#else
- GTEST_FLAG(output) = "xml:path/";
- const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile();
- // TODO(wan@google.com): libtool causes the test binary file to be
- // named lt-gtest-options_test. Therefore the output file may be
- // named .../lt-gtest-options_test.xml. We should remove this
- // hard-coded logic when Chandler Carruth's libtool replacement is
- // ready.
- EXPECT_TRUE(output_file == FilePath::ConcatPaths(original_working_dir_,
- FilePath("path/gtest-options_test.xml")).c_str() ||
- output_file == FilePath::ConcatPaths(original_working_dir_,
- FilePath("path/lt-gtest-options_test.xml")).c_str() ||
- output_file == FilePath::ConcatPaths(original_working_dir_,
- FilePath("path/gtest_all_test.xml")).c_str() ||
- output_file == FilePath::ConcatPaths(original_working_dir_,
- FilePath("path/lt-gtest_all_test.xml")).c_str())
- << " output_file = " << output_file;
+ EXPECT_EQ(expected_output_file, output_file.c_str());
#endif
}
@@ -236,29 +190,20 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) {
TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) {
#if GTEST_OS_WINDOWS
- GTEST_FLAG(output) = "xml:c:\\tmp\\";
- const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile();
- EXPECT_TRUE(
- _strcmpi(output_file.c_str(),
- FilePath("c:\\tmp\\gtest-options_test.xml").c_str()) == 0 ||
- _strcmpi(output_file.c_str(),
- FilePath("c:\\tmp\\gtest-options-ex_test.xml").c_str()) == 0 ||
- _strcmpi(output_file.c_str(),
- FilePath("c:\\tmp\\gtest_all_test.xml").c_str()) == 0)
- << " output_file = " << output_file;
+ const std::string path = "c:\\tmp\\";
#else
- GTEST_FLAG(output) = "xml:/tmp/";
+ const std::string path = "/tmp/";
+#endif
+
+ GTEST_FLAG(output) = "xml:" + path;
+ const std::string expected_output_file =
+ path + GetCurrentExecutableName().c_str() + ".xml";
const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile();
- // TODO(wan@google.com): libtool causes the test binary file to be
- // named lt-gtest-options_test. Therefore the output file may be
- // named .../lt-gtest-options_test.xml. We should remove this
- // hard-coded logic when Chandler Carruth's libtool replacement is
- // ready.
- EXPECT_TRUE(output_file == "/tmp/gtest-options_test.xml" ||
- output_file == "/tmp/lt-gtest-options_test.xml" ||
- output_file == "/tmp/gtest_all_test.xml" ||
- output_file == "/tmp/lt-gtest_all_test.xml")
- << " output_file = " << output_file;
+
+#if GTEST_OS_WINDOWS
+ EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str());
+#else
+ EXPECT_EQ(expected_output_file, output_file.c_str());
#endif
}
diff --git a/gtest/test/gtest-param-test_test.cc b/gtest/test/gtest-param-test_test.cc
index ecb5fdb..d0a0e73 100644
--- a/gtest/test/gtest-param-test_test.cc
+++ b/gtest/test/gtest-param-test_test.cc
@@ -40,6 +40,8 @@
#include <algorithm>
#include <iostream>
#include <list>
+#include <sstream>
+#include <string>
#include <vector>
// To include gtest-internal-inl.h.
@@ -70,6 +72,57 @@ using ::std::tr1::tuple;
using ::testing::internal::ParamGenerator;
using ::testing::internal::UnitTestOptions;
+// Prints a value to a string.
+//
+// TODO(wan@google.com): remove PrintValue() when we move matchers and
+// EXPECT_THAT() from Google Mock to Google Test. At that time, we
+// can write EXPECT_THAT(x, Eq(y)) to compare two tuples x and y, as
+// EXPECT_THAT() and the matchers know how to print tuples.
+template <typename T>
+::std::string PrintValue(const T& value) {
+ ::std::stringstream stream;
+ stream << value;
+ return stream.str();
+}
+
+#if GTEST_HAS_COMBINE
+
+// These overloads allow printing tuples in our tests. We cannot
+// define an operator<< for tuples, as that definition needs to be in
+// the std namespace in order to be picked up by Google Test via
+// Argument-Dependent Lookup, yet defining anything in the std
+// namespace in non-STL code is undefined behavior.
+
+template <typename T1, typename T2>
+::std::string PrintValue(const tuple<T1, T2>& value) {
+ ::std::stringstream stream;
+ stream << "(" << get<0>(value) << ", " << get<1>(value) << ")";
+ return stream.str();
+}
+
+template <typename T1, typename T2, typename T3>
+::std::string PrintValue(const tuple<T1, T2, T3>& value) {
+ ::std::stringstream stream;
+ stream << "(" << get<0>(value) << ", " << get<1>(value)
+ << ", "<< get<2>(value) << ")";
+ return stream.str();
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+::std::string PrintValue(
+ const tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& value) {
+ ::std::stringstream stream;
+ stream << "(" << get<0>(value) << ", " << get<1>(value)
+ << ", "<< get<2>(value) << ", " << get<3>(value)
+ << ", "<< get<4>(value) << ", " << get<5>(value)
+ << ", "<< get<6>(value) << ", " << get<7>(value)
+ << ", "<< get<8>(value) << ", " << get<9>(value) << ")";
+ return stream.str();
+}
+
+#endif // GTEST_HAS_COMBINE
+
// Verifies that a sequence generated by the generator and accessed
// via the iterator object matches the expected one using Google Test
// assertions.
@@ -80,15 +133,19 @@ void VerifyGenerator(const ParamGenerator<T>& generator,
for (size_t i = 0; i < N; ++i) {
ASSERT_FALSE(it == generator.end())
<< "At element " << i << " when accessing via an iterator "
- << "created with the copy constructor." << std::endl;
- EXPECT_EQ(expected_values[i], *it)
- << "At element " << i << " when accessing via an iterator "
- << "created with the copy constructor." << std::endl;
+ << "created with the copy constructor.\n";
+ // We cannot use EXPECT_EQ() here as the values may be tuples,
+ // which don't support <<.
+ EXPECT_TRUE(expected_values[i] == *it)
+ << "where i is " << i
+ << ", expected_values[i] is " << PrintValue(expected_values[i])
+ << ", *it is " << PrintValue(*it)
+ << ", and 'it' is an iterator created with the copy constructor.\n";
it++;
}
EXPECT_TRUE(it == generator.end())
<< "At the presumed end of sequence when accessing via an iterator "
- << "created with the copy constructor." << std::endl;
+ << "created with the copy constructor.\n";
// Test the iterator assignment. The following lines verify that
// the sequence accessed via an iterator initialized via the
@@ -98,15 +155,17 @@ void VerifyGenerator(const ParamGenerator<T>& generator,
for (size_t i = 0; i < N; ++i) {
ASSERT_FALSE(it == generator.end())
<< "At element " << i << " when accessing via an iterator "
- << "created with the assignment operator." << std::endl;
- EXPECT_EQ(expected_values[i], *it)
- << "At element " << i << " when accessing via an iterator "
- << "created with the assignment operator." << std::endl;
+ << "created with the assignment operator.\n";
+ EXPECT_TRUE(expected_values[i] == *it)
+ << "where i is " << i
+ << ", expected_values[i] is " << PrintValue(expected_values[i])
+ << ", *it is " << PrintValue(*it)
+ << ", and 'it' is an iterator created with the copy constructor.\n";
it++;
}
EXPECT_TRUE(it == generator.end())
<< "At the presumed end of sequence when accessing via an iterator "
- << "created with the assignment operator." << std::endl;
+ << "created with the assignment operator.\n";
}
template <typename T>
@@ -205,7 +264,7 @@ TEST(RangeTest, IntRangeWithCustomStepOverUpperBound) {
// copy constructor, operator=(), operator+(), and operator<().
class DogAdder {
public:
- explicit DogAdder(const char* value) : value_(value) {}
+ explicit DogAdder(const char* a_value) : value_(a_value) {}
DogAdder(const DogAdder& other) : value_(other.value_.c_str()) {}
DogAdder operator=(const DogAdder& other) {
@@ -243,7 +302,7 @@ TEST(RangeTest, WorksWithACustomType) {
class IntWrapper {
public:
- explicit IntWrapper(int value) : value_(value) {}
+ explicit IntWrapper(int a_value) : value_(a_value) {}
IntWrapper(const IntWrapper& other) : value_(other.value_) {}
IntWrapper operator=(const IntWrapper& other) {
@@ -400,33 +459,6 @@ TEST(BoolTest, BoolWorks) {
#if GTEST_HAS_COMBINE
-template <typename T1, typename T2>
-::std::ostream& operator<<(::std::ostream& stream, const tuple<T1, T2>& value) {
- stream << "(" << get<0>(value) << ", " << get<1>(value) << ")";
- return stream;
-}
-
-template <typename T1, typename T2, typename T3>
-::std::ostream& operator<<(::std::ostream& stream,
- const tuple<T1, T2, T3>& value) {
- stream << "(" << get<0>(value) << ", " << get<1>(value)
- << ", "<< get<2>(value) << ")";
- return stream;
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10>
-::std::ostream& operator<<(
- ::std::ostream& stream,
- const tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& value) {
- stream << "(" << get<0>(value) << ", " << get<1>(value)
- << ", "<< get<2>(value) << ", " << get<3>(value)
- << ", "<< get<4>(value) << ", " << get<5>(value)
- << ", "<< get<6>(value) << ", " << get<7>(value)
- << ", "<< get<8>(value) << ", " << get<9>(value) << ")";
- return stream;
-}
-
// Tests that Combine() with two parameters generates the expected sequence.
TEST(CombineTest, CombineWithTwoParameters) {
const char* foo = "foo";
@@ -660,13 +692,15 @@ INSTANTIATE_TEST_CASE_P(TestExpansionModule, TestGenerationTest,
ValuesIn(test_generation_params));
// This test verifies that the element sequence (third parameter of
-// INSTANTIATE_TEST_CASE_P) is evaluated in RUN_ALL_TESTS and not at the call
-// site of INSTANTIATE_TEST_CASE_P.
-// For that, we declare param_value_ to be a static member of
-// GeneratorEvaluationTest and initialize it to 0. We set it to 1 in main(),
-// just before invocation of RUN_ALL_TESTS. If the sequence is evaluated
-// before that moment, INSTANTIATE_TEST_CASE_P will create a test with
-// parameter 0, and the test body will fail the assertion.
+// INSTANTIATE_TEST_CASE_P) is evaluated in InitGoogleTest() and neither at
+// the call site of INSTANTIATE_TEST_CASE_P nor in RUN_ALL_TESTS(). For
+// that, we declare param_value_ to be a static member of
+// GeneratorEvaluationTest and initialize it to 0. We set it to 1 in
+// main(), just before invocation of InitGoogleTest(). After calling
+// InitGoogleTest(), we set the value to 2. If the sequence is evaluated
+// before or after InitGoogleTest, INSTANTIATE_TEST_CASE_P will create a
+// test with parameter other than 1, and the test body will fail the
+// assertion.
class GeneratorEvaluationTest : public TestWithParam<int> {
public:
static int param_value() { return param_value_; }
@@ -783,10 +817,19 @@ int main(int argc, char **argv) {
#if GTEST_HAS_PARAM_TEST
// Used in TestGenerationTest test case.
AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance());
- // Used in GeneratorEvaluationTest test case.
+ // Used in GeneratorEvaluationTest test case. Tests that the updated value
+ // will be picked up for instantiating tests in GeneratorEvaluationTest.
GeneratorEvaluationTest::set_param_value(1);
#endif // GTEST_HAS_PARAM_TEST
::testing::InitGoogleTest(&argc, argv);
+
+#if GTEST_HAS_PARAM_TEST
+ // Used in GeneratorEvaluationTest test case. Tests that value updated
+ // here will NOT be used for instantiating tests in
+ // GeneratorEvaluationTest.
+ GeneratorEvaluationTest::set_param_value(2);
+#endif // GTEST_HAS_PARAM_TEST
+
return RUN_ALL_TESTS();
}
diff --git a/gtest/test/gtest-port_test.cc b/gtest/test/gtest-port_test.cc
index df59f9e..3725860 100644
--- a/gtest/test/gtest-port_test.cc
+++ b/gtest/test/gtest-port_test.cc
@@ -33,11 +33,14 @@
#include <gtest/internal/gtest-port.h>
+#include <stdio.h>
+
#if GTEST_OS_MAC
-#include <pthread.h>
#include <time.h>
#endif // GTEST_OS_MAC
+#include <utility> // For std::pair and std::make_pair.
+
#include <gtest/gtest.h>
#include <gtest/gtest-spi.h>
@@ -50,9 +53,20 @@
#include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
+using std::make_pair;
+using std::pair;
+
namespace testing {
namespace internal {
+// Tests that the element_type typedef is available in scoped_ptr and refers
+// to the parameter type.
+TEST(ScopedPtrTest, DefinesElementType) {
+ StaticAssertTypeEq<int, ::testing::internal::scoped_ptr<int>::element_type>();
+}
+
+// TODO(vladl@google.com): Implement THE REST of scoped_ptr tests.
+
TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) {
if (AlwaysFalse())
GTEST_CHECK_(false) << "This should never be executed; "
@@ -84,7 +98,7 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) {
#if GTEST_OS_MAC
void* ThreadFunc(void* data) {
- pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data);
+ pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data);
pthread_mutex_lock(mutex);
pthread_mutex_unlock(mutex);
return NULL;
@@ -119,10 +133,7 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) {
if (GetThreadCount() == 1)
break;
- timespec time;
- time.tv_sec = 0;
- time.tv_nsec = 100L * 1000 * 1000; // .1 seconds.
- nanosleep(&time, NULL);
+ SleepMilliseconds(100);
}
EXPECT_EQ(1U, GetThreadCount());
pthread_mutex_destroy(&mutex);
@@ -161,15 +172,15 @@ TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) {
#if GTEST_USES_POSIX_RE
+#if GTEST_HAS_TYPED_TEST
+
template <typename Str>
class RETest : public ::testing::Test {};
// Defines StringTypes as the list of all string types that class RE
// supports.
typedef testing::Types<
-#if GTEST_HAS_STD_STRING
::std::string,
-#endif // GTEST_HAS_STD_STRING
#if GTEST_HAS_GLOBAL_STRING
::string,
#endif // GTEST_HAS_GLOBAL_STRING
@@ -223,6 +234,8 @@ TYPED_TEST(RETest, PartialMatchWorks) {
EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re));
}
+#endif // GTEST_HAS_TYPED_TEST
+
#elif GTEST_USES_SIMPLE_RE
TEST(IsInSetTest, NulCharIsNotInAnySet) {
@@ -689,11 +702,317 @@ TEST(RETest, PartialMatchWorks) {
#endif // GTEST_USES_POSIX_RE
-TEST(CaptureStderrTest, CapturesStdErr) {
+#if !GTEST_OS_WINDOWS_MOBILE
+
+TEST(CaptureTest, CapturesStdout) {
+ CaptureStdout();
+ fprintf(stdout, "abc");
+ EXPECT_STREQ("abc", GetCapturedStdout().c_str());
+
+ CaptureStdout();
+ fprintf(stdout, "def%cghi", '\0');
+ EXPECT_EQ(::std::string("def\0ghi", 7), ::std::string(GetCapturedStdout()));
+}
+
+TEST(CaptureTest, CapturesStderr) {
+ CaptureStderr();
+ fprintf(stderr, "jkl");
+ EXPECT_STREQ("jkl", GetCapturedStderr().c_str());
+
+ CaptureStderr();
+ fprintf(stderr, "jkl%cmno", '\0');
+ EXPECT_EQ(::std::string("jkl\0mno", 7), ::std::string(GetCapturedStderr()));
+}
+
+// Tests that stdout and stderr capture don't interfere with each other.
+TEST(CaptureTest, CapturesStdoutAndStderr) {
+ CaptureStdout();
CaptureStderr();
- fprintf(stderr, "abc");
- ASSERT_STREQ("abc", GetCapturedStderr().c_str());
+ fprintf(stdout, "pqr");
+ fprintf(stderr, "stu");
+ EXPECT_STREQ("pqr", GetCapturedStdout().c_str());
+ EXPECT_STREQ("stu", GetCapturedStderr().c_str());
+}
+
+TEST(CaptureDeathTest, CannotReenterStdoutCapture) {
+ CaptureStdout();
+ EXPECT_DEATH_IF_SUPPORTED(CaptureStdout();,
+ "Only one stdout capturer can exist at a time");
+ GetCapturedStdout();
+
+ // We cannot test stderr capturing using death tests as they use it
+ // themselves.
+}
+
+#endif // !GTEST_OS_WINDOWS_MOBILE
+
+TEST(ThreadLocalTest, DefaultConstructorInitializesToDefaultValues) {
+ ThreadLocal<int> t1;
+ EXPECT_EQ(0, t1.get());
+
+ ThreadLocal<void*> t2;
+ EXPECT_TRUE(t2.get() == NULL);
+}
+
+TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) {
+ ThreadLocal<int> t1(123);
+ EXPECT_EQ(123, t1.get());
+
+ int i = 0;
+ ThreadLocal<int*> t2(&i);
+ EXPECT_EQ(&i, t2.get());
+}
+
+class NoDefaultContructor {
+ public:
+ explicit NoDefaultContructor(const char*) {}
+ NoDefaultContructor(const NoDefaultContructor&) {}
+};
+
+TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) {
+ ThreadLocal<NoDefaultContructor> bar(NoDefaultContructor("foo"));
+ bar.pointer();
+}
+
+TEST(ThreadLocalTest, GetAndPointerReturnSameValue) {
+ ThreadLocal<String> thread_local;
+
+ EXPECT_EQ(thread_local.pointer(), &(thread_local.get()));
+
+ // Verifies the condition still holds after calling set.
+ thread_local.set("foo");
+ EXPECT_EQ(thread_local.pointer(), &(thread_local.get()));
+}
+
+TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) {
+ ThreadLocal<String> thread_local;
+ const ThreadLocal<String>& const_thread_local = thread_local;
+
+ EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer());
+
+ thread_local.set("foo");
+ EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer());
+}
+
+#if GTEST_IS_THREADSAFE
+
+void AddTwo(int* param) { *param += 2; }
+
+TEST(ThreadWithParamTest, ConstructorExecutesThreadFunc) {
+ int i = 40;
+ ThreadWithParam<int*> thread(&AddTwo, &i, NULL);
+ thread.Join();
+ EXPECT_EQ(42, i);
}
+TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) {
+ // AssertHeld() is flaky only in the presence of multiple threads accessing
+ // the lock. In this case, the test is robust.
+ EXPECT_DEATH_IF_SUPPORTED({
+ Mutex m;
+ { MutexLock lock(&m); }
+ m.AssertHeld();
+ },
+ "thread .*hold");
+}
+
+TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) {
+ Mutex m;
+ MutexLock lock(&m);
+ m.AssertHeld();
+}
+
+class AtomicCounterWithMutex {
+ public:
+ explicit AtomicCounterWithMutex(Mutex* mutex) :
+ value_(0), mutex_(mutex), random_(42) {}
+
+ void Increment() {
+ MutexLock lock(mutex_);
+ int temp = value_;
+ {
+ // Locking a mutex puts up a memory barrier, preventing reads and
+ // writes to value_ rearranged when observed from other threads.
+ //
+ // We cannot use Mutex and MutexLock here or rely on their memory
+ // barrier functionality as we are testing them here.
+ pthread_mutex_t memory_barrier_mutex;
+ GTEST_CHECK_POSIX_SUCCESS_(
+ pthread_mutex_init(&memory_barrier_mutex, NULL));
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&memory_barrier_mutex));
+
+ SleepMilliseconds(random_.Generate(30));
+
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex));
+ }
+ value_ = temp + 1;
+ }
+ int value() const { return value_; }
+
+ private:
+ volatile int value_;
+ Mutex* const mutex_; // Protects value_.
+ Random random_;
+};
+
+void CountingThreadFunc(pair<AtomicCounterWithMutex*, int> param) {
+ for (int i = 0; i < param.second; ++i)
+ param.first->Increment();
+}
+
+// Tests that the mutex only lets one thread at a time to lock it.
+TEST(MutexTest, OnlyOneThreadCanLockAtATime) {
+ Mutex mutex;
+ AtomicCounterWithMutex locked_counter(&mutex);
+
+ typedef ThreadWithParam<pair<AtomicCounterWithMutex*, int> > ThreadType;
+ const int kCycleCount = 20;
+ const int kThreadCount = 7;
+ scoped_ptr<ThreadType> counting_threads[kThreadCount];
+ Notification threads_can_start;
+ // Creates and runs kThreadCount threads that increment locked_counter
+ // kCycleCount times each.
+ for (int i = 0; i < kThreadCount; ++i) {
+ counting_threads[i].reset(new ThreadType(&CountingThreadFunc,
+ make_pair(&locked_counter,
+ kCycleCount),
+ &threads_can_start));
+ }
+ threads_can_start.Notify();
+ for (int i = 0; i < kThreadCount; ++i)
+ counting_threads[i]->Join();
+
+ // If the mutex lets more than one thread to increment the counter at a
+ // time, they are likely to encounter a race condition and have some
+ // increments overwritten, resulting in the lower then expected counter
+ // value.
+ EXPECT_EQ(kCycleCount * kThreadCount, locked_counter.value());
+}
+
+template <typename T>
+void RunFromThread(void (func)(T), T param) {
+ ThreadWithParam<T> thread(func, param, NULL);
+ thread.Join();
+}
+
+void RetrieveThreadLocalValue(pair<ThreadLocal<String>*, String*> param) {
+ *param.second = param.first->get();
+}
+
+TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) {
+ ThreadLocal<String> thread_local("foo");
+ EXPECT_STREQ("foo", thread_local.get().c_str());
+
+ thread_local.set("bar");
+ EXPECT_STREQ("bar", thread_local.get().c_str());
+
+ String result;
+ RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result));
+ EXPECT_STREQ("foo", result.c_str());
+}
+
+// DestructorTracker keeps track of whether its instances have been
+// destroyed.
+static std::vector<bool> g_destroyed;
+
+class DestructorTracker {
+ public:
+ DestructorTracker() : index_(GetNewIndex()) {}
+ DestructorTracker(const DestructorTracker& /* rhs */)
+ : index_(GetNewIndex()) {}
+ ~DestructorTracker() {
+ // We never access g_destroyed concurrently, so we don't need to
+ // protect the write operation under a mutex.
+ g_destroyed[index_] = true;
+ }
+
+ private:
+ static int GetNewIndex() {
+ g_destroyed.push_back(false);
+ return g_destroyed.size() - 1;
+ }
+ const int index_;
+};
+
+typedef ThreadLocal<DestructorTracker>* ThreadParam;
+
+void CallThreadLocalGet(ThreadParam thread_local) {
+ thread_local->get();
+}
+
+// Tests that when a ThreadLocal object dies in a thread, it destroys
+// the managed object for that thread.
+TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) {
+ g_destroyed.clear();
+
+ {
+ // The next line default constructs a DestructorTracker object as
+ // the default value of objects managed by thread_local.
+ ThreadLocal<DestructorTracker> thread_local;
+ ASSERT_EQ(1U, g_destroyed.size());
+ ASSERT_FALSE(g_destroyed[0]);
+
+ // This creates another DestructorTracker object for the main thread.
+ thread_local.get();
+ ASSERT_EQ(2U, g_destroyed.size());
+ ASSERT_FALSE(g_destroyed[0]);
+ ASSERT_FALSE(g_destroyed[1]);
+ }
+
+ // Now thread_local has died. It should have destroyed both the
+ // default value shared by all threads and the value for the main
+ // thread.
+ ASSERT_EQ(2U, g_destroyed.size());
+ EXPECT_TRUE(g_destroyed[0]);
+ EXPECT_TRUE(g_destroyed[1]);
+
+ g_destroyed.clear();
+}
+
+// Tests that when a thread exits, the thread-local object for that
+// thread is destroyed.
+TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) {
+ g_destroyed.clear();
+
+ {
+ // The next line default constructs a DestructorTracker object as
+ // the default value of objects managed by thread_local.
+ ThreadLocal<DestructorTracker> thread_local;
+ ASSERT_EQ(1U, g_destroyed.size());
+ ASSERT_FALSE(g_destroyed[0]);
+
+ // This creates another DestructorTracker object in the new thread.
+ ThreadWithParam<ThreadParam> thread(
+ &CallThreadLocalGet, &thread_local, NULL);
+ thread.Join();
+
+ // Now the new thread has exited. The per-thread object for it
+ // should have been destroyed.
+ ASSERT_EQ(2U, g_destroyed.size());
+ ASSERT_FALSE(g_destroyed[0]);
+ ASSERT_TRUE(g_destroyed[1]);
+ }
+
+ // Now thread_local has died. The default value should have been
+ // destroyed too.
+ ASSERT_EQ(2U, g_destroyed.size());
+ EXPECT_TRUE(g_destroyed[0]);
+ EXPECT_TRUE(g_destroyed[1]);
+
+ g_destroyed.clear();
+}
+
+TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) {
+ ThreadLocal<String> thread_local;
+ thread_local.set("Foo");
+ EXPECT_STREQ("Foo", thread_local.get().c_str());
+
+ String result;
+ RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result));
+ EXPECT_TRUE(result.c_str() == NULL);
+}
+
+#endif // GTEST_IS_THREADSAFE
+
} // namespace internal
} // namespace testing
diff --git a/gtest/test/gtest-test-part_test.cc b/gtest/test/gtest-test-part_test.cc
index 403c184..5a3e919 100644
--- a/gtest/test/gtest-test-part_test.cc
+++ b/gtest/test/gtest-test-part_test.cc
@@ -34,6 +34,7 @@
#include <gtest/gtest.h>
+using testing::Message;
using testing::Test;
using testing::TestPartResult;
using testing::TestPartResultArray;
@@ -53,6 +54,54 @@ class TestPartResultTest : public Test {
TestPartResult r1_, r2_, r3_;
};
+
+TEST_F(TestPartResultTest, ConstructorWorks) {
+ Message message;
+ message << "something is terribly wrong";
+ message << static_cast<const char*>(testing::internal::kStackTraceMarker);
+ message << "some unimportant stack trace";
+
+ const TestPartResult result(TestPartResult::kNonFatalFailure,
+ "some_file.cc",
+ 42,
+ message.GetString().c_str());
+
+ EXPECT_EQ(TestPartResult::kNonFatalFailure, result.type());
+ EXPECT_STREQ("some_file.cc", result.file_name());
+ EXPECT_EQ(42, result.line_number());
+ EXPECT_STREQ(message.GetString().c_str(), result.message());
+ EXPECT_STREQ("something is terribly wrong", result.summary());
+}
+
+TEST_F(TestPartResultTest, ResultAccessorsWork) {
+ const TestPartResult success(TestPartResult::kSuccess,
+ "file.cc",
+ 42,
+ "message");
+ EXPECT_TRUE(success.passed());
+ EXPECT_FALSE(success.failed());
+ EXPECT_FALSE(success.nonfatally_failed());
+ EXPECT_FALSE(success.fatally_failed());
+
+ const TestPartResult nonfatal_failure(TestPartResult::kNonFatalFailure,
+ "file.cc",
+ 42,
+ "message");
+ EXPECT_FALSE(nonfatal_failure.passed());
+ EXPECT_TRUE(nonfatal_failure.failed());
+ EXPECT_TRUE(nonfatal_failure.nonfatally_failed());
+ EXPECT_FALSE(nonfatal_failure.fatally_failed());
+
+ const TestPartResult fatal_failure(TestPartResult::kFatalFailure,
+ "file.cc",
+ 42,
+ "message");
+ EXPECT_FALSE(fatal_failure.passed());
+ EXPECT_TRUE(fatal_failure.failed());
+ EXPECT_FALSE(fatal_failure.nonfatally_failed());
+ EXPECT_TRUE(fatal_failure.fatally_failed());
+}
+
// Tests TestPartResult::type().
TEST_F(TestPartResultTest, type) {
EXPECT_EQ(TestPartResult::kSuccess, r1_.type());
diff --git a/gtest/test/gtest-tuple_test.cc b/gtest/test/gtest-tuple_test.cc
index 3829118..532f70b 100644
--- a/gtest/test/gtest-tuple_test.cc
+++ b/gtest/test/gtest-tuple_test.cc
@@ -135,12 +135,44 @@ TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) {
<< "Changing a reference field should update the underlying variable.";
}
-// Tests tuple's default constructor.
-TEST(TupleConstructorTest, DefaultConstructor) {
- // We are just testing that the following compiles.
+// Tests that tuple's default constructor default initializes each field.
+// This test needs to compile without generating warnings.
+TEST(TupleConstructorTest, DefaultConstructorDefaultInitializesEachField) {
+ // The TR1 report requires that tuple's default constructor default
+ // initializes each field, even if it's a primitive type. If the
+ // implementation forgets to do this, this test will catch it by
+ // generating warnings about using uninitialized variables (assuming
+ // a decent compiler).
+
tuple<> empty;
- tuple<int> one_field;
- tuple<double, char, bool*> three_fields;
+
+ tuple<int> a1, b1;
+ b1 = a1;
+ EXPECT_EQ(0, get<0>(b1));
+
+ tuple<int, double> a2, b2;
+ b2 = a2;
+ EXPECT_EQ(0, get<0>(b2));
+ EXPECT_EQ(0.0, get<1>(b2));
+
+ tuple<double, char, bool*> a3, b3;
+ b3 = a3;
+ EXPECT_EQ(0.0, get<0>(b3));
+ EXPECT_EQ('\0', get<1>(b3));
+ EXPECT_TRUE(get<2>(b3) == NULL);
+
+ tuple<int, int, int, int, int, int, int, int, int, int> a10, b10;
+ b10 = a10;
+ EXPECT_EQ(0, get<0>(b10));
+ EXPECT_EQ(0, get<1>(b10));
+ EXPECT_EQ(0, get<2>(b10));
+ EXPECT_EQ(0, get<3>(b10));
+ EXPECT_EQ(0, get<4>(b10));
+ EXPECT_EQ(0, get<5>(b10));
+ EXPECT_EQ(0, get<6>(b10));
+ EXPECT_EQ(0, get<7>(b10));
+ EXPECT_EQ(0, get<8>(b10));
+ EXPECT_EQ(0, get<9>(b10));
}
// Tests constructing a tuple from its fields.
diff --git a/gtest/test/gtest-typed-test_test.cc b/gtest/test/gtest-typed-test_test.cc
index 4b6e971..f2c3972 100644
--- a/gtest/test/gtest-typed-test_test.cc
+++ b/gtest/test/gtest-typed-test_test.cc
@@ -349,12 +349,12 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes);
#if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P)
-// Google Test doesn't support type-parameterized tests on some platforms
-// and compilers, such as MSVC 7.1. If we use conditional compilation to
-// compile out all code referring to the gtest_main library, MSVC linker
-// will not link that library at all and consequently complain about
-// missing entry point defined in that library (fatal error LNK1561:
-// entry point must be defined). This dummy test keeps gtest_main linked in.
+// Google Test may not support type-parameterized tests with some
+// compilers. If we use conditional compilation to compile out all
+// code referring to the gtest_main library, MSVC linker will not link
+// that library at all and consequently complain about missing entry
+// point defined in that library (fatal error LNK1561: entry point
+// must be defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {}
#endif // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P)
diff --git a/gtest/test/gtest_all_test.cc b/gtest/test/gtest_all_test.cc
index 955aa62..e1edb08 100644
--- a/gtest/test/gtest_all_test.cc
+++ b/gtest/test/gtest_all_test.cc
@@ -45,3 +45,4 @@
#include "test/gtest-typed-test2_test.cc"
#include "test/gtest_unittest.cc"
#include "test/production.cc"
+#include "src/gtest_main.cc"
diff --git a/gtest/test/gtest_break_on_failure_unittest.py b/gtest/test/gtest_break_on_failure_unittest.py
index 218d371..c819183 100755
--- a/gtest/test/gtest_break_on_failure_unittest.py
+++ b/gtest/test/gtest_break_on_failure_unittest.py
@@ -69,21 +69,24 @@ EXE_PATH = gtest_test_utils.GetTestExecutablePath(
# Utilities.
+environ = os.environ.copy()
+
+
def SetEnvVar(env_var, value):
"""Sets an environment variable to a given value; unsets it when the
given value is None.
"""
if value is not None:
- os.environ[env_var] = value
- elif env_var in os.environ:
- del os.environ[env_var]
+ environ[env_var] = value
+ elif env_var in environ:
+ del environ[env_var]
def Run(command):
"""Runs a command; returns 1 if it was killed by a signal, or 0 otherwise."""
- p = gtest_test_utils.Subprocess(command)
+ p = gtest_test_utils.Subprocess(command, env=environ)
if p.terminated_by_signal:
return 1
else:
diff --git a/gtest/test/gtest_break_on_failure_unittest_.cc b/gtest/test/gtest_break_on_failure_unittest_.cc
index 10a1203..d28d1d3 100644
--- a/gtest/test/gtest_break_on_failure_unittest_.cc
+++ b/gtest/test/gtest_break_on_failure_unittest_.cc
@@ -43,6 +43,7 @@
#if GTEST_OS_WINDOWS
#include <windows.h>
+#include <stdlib.h>
#endif
namespace {
@@ -52,6 +53,14 @@ TEST(Foo, Bar) {
EXPECT_EQ(2, 3);
}
+#if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE
+// On Windows Mobile global exception handlers are not supported.
+LONG WINAPI ExitWithExceptionCode(
+ struct _EXCEPTION_POINTERS* exception_pointers) {
+ exit(exception_pointers->ExceptionRecord->ExceptionCode);
+}
+#endif
+
} // namespace
int main(int argc, char **argv) {
@@ -59,7 +68,18 @@ int main(int argc, char **argv) {
// Suppresses display of the Windows error dialog upon encountering
// a general protection fault (segment violation).
SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS);
+
+#if !GTEST_OS_WINDOWS_MOBILE
+ // The default unhandled exception filter does not always exit
+ // with the exception code as exit code - for example it exits with
+ // 0 for EXCEPTION_ACCESS_VIOLATION and 1 for EXCEPTION_BREAKPOINT
+ // if the application is compiled in debug mode. Thus we use our own
+ // filter which always exits with the exception code for unhandled
+ // exceptions.
+ SetUnhandledExceptionFilter(ExitWithExceptionCode);
+#endif
#endif
+
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
diff --git a/gtest/test/gtest_color_test_.cc b/gtest/test/gtest_color_test_.cc
index 305aeb9..58d377c 100644
--- a/gtest/test/gtest_color_test_.cc
+++ b/gtest/test/gtest_color_test_.cc
@@ -37,11 +37,14 @@
#include <gtest/gtest.h>
-namespace testing {
-namespace internal {
-bool ShouldUseColor(bool stdout_is_tty);
-} // namespace internal
-} // namespace testing
+// Indicates that this translation unit is part of Google Test's
+// implementation. It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error. This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
using testing::internal::ShouldUseColor;
diff --git a/gtest/test/gtest_env_var_test.py b/gtest/test/gtest_env_var_test.py
index f8250d4..bcc0bfd 100755
--- a/gtest/test/gtest_env_var_test.py
+++ b/gtest/test/gtest_env_var_test.py
@@ -42,6 +42,8 @@ IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux'
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_')
+environ = os.environ.copy()
+
def AssertEq(expected, actual):
if expected != actual:
@@ -54,9 +56,9 @@ def SetEnvVar(env_var, value):
"""Sets the env variable to 'value'; unsets it when 'value' is None."""
if value is not None:
- os.environ[env_var] = value
- elif env_var in os.environ:
- del os.environ[env_var]
+ environ[env_var] = value
+ elif env_var in environ:
+ del environ[env_var]
def GetFlag(flag):
@@ -65,7 +67,7 @@ def GetFlag(flag):
args = [COMMAND]
if flag is not None:
args += [flag]
- return gtest_test_utils.Subprocess(args).output
+ return gtest_test_utils.Subprocess(args, env=environ).output
def TestFlag(flag, test_val, default_val):
diff --git a/gtest/test/gtest_filter_unittest.py b/gtest/test/gtest_filter_unittest.py
index a94a521..0d1a770 100755
--- a/gtest/test/gtest_filter_unittest.py
+++ b/gtest/test/gtest_filter_unittest.py
@@ -45,11 +45,42 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
import sets
+import sys
+
import gtest_test_utils
# Constants.
-IS_WINDOWS = os.name == 'nt'
+# Checks if this platform can pass empty environment variables to child
+# processes. We set an env variable to an empty string and invoke a python
+# script in a subprocess to print whether the variable is STILL in
+# os.environ. We then use 'eval' to parse the child's output so that an
+# exception is thrown if the input is anything other than 'True' nor 'False'.
+os.environ['EMPTY_VAR'] = ''
+child = gtest_test_utils.Subprocess(
+ [sys.executable, '-c', 'import os; print \'EMPTY_VAR\' in os.environ'])
+CAN_PASS_EMPTY_ENV = eval(child.output)
+
+
+# Check if this platform can unset environment variables in child processes.
+# We set an env variable to a non-empty string, unset it, and invoke
+# a python script in a subprocess to print whether the variable
+# is NO LONGER in os.environ.
+# We use 'eval' to parse the child's output so that an exception
+# is thrown if the input is neither 'True' nor 'False'.
+os.environ['UNSET_VAR'] = 'X'
+del os.environ['UNSET_VAR']
+child = gtest_test_utils.Subprocess(
+ [sys.executable, '-c', 'import os; print \'UNSET_VAR\' not in os.environ'])
+CAN_UNSET_ENV = eval(child.output)
+
+
+# Checks if we should test with an empty filter. This doesn't
+# make sense on platforms that cannot pass empty env variables (Win32)
+# and on platforms that cannot unset variables (since we cannot tell
+# the difference between "" and NULL -- Borland and Solaris < 5.10)
+CAN_TEST_EMPTY_FILTER = (CAN_PASS_EMPTY_ENV and CAN_UNSET_ENV)
+
# The environment variable for specifying the test filters.
FILTER_ENV_VAR = 'GTEST_FILTER'
@@ -77,6 +108,14 @@ TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ tests? from (\w+(/\w+)?)')
# Regex for parsing test names from Google Test's output.
TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+(/\w+)?)')
+# The command line flag to tell Google Test to output the list of tests it
+# will run.
+LIST_TESTS_FLAG = '--gtest_list_tests'
+
+# Indicates whether Google Test supports death tests.
+SUPPORTS_DEATH_TESTS = 'HasDeathTest' in gtest_test_utils.Subprocess(
+ [COMMAND, LIST_TESTS_FLAG]).output
+
# Full names of all tests in gtest_filter_unittests_.
PARAM_TESTS = [
'SeqP/ParamTest.TestX/0',
@@ -98,6 +137,14 @@ DISABLED_TESTS = [
'DISABLED_FoobarbazTest.TestA',
]
+if SUPPORTS_DEATH_TESTS:
+ DEATH_TESTS = [
+ 'HasDeathTest.Test1',
+ 'HasDeathTest.Test2',
+ ]
+else:
+ DEATH_TESTS = []
+
# All the non-disabled tests.
ACTIVE_TESTS = [
'FooTest.Abc',
@@ -110,35 +157,35 @@ ACTIVE_TESTS = [
'BazTest.TestOne',
'BazTest.TestA',
'BazTest.TestB',
-
- 'HasDeathTest.Test1',
- 'HasDeathTest.Test2',
- ] + PARAM_TESTS
+ ] + DEATH_TESTS + PARAM_TESTS
param_tests_present = None
# Utilities.
+environ = os.environ.copy()
+
def SetEnvVar(env_var, value):
"""Sets the env variable to 'value'; unsets it when 'value' is None."""
if value is not None:
- os.environ[env_var] = value
- elif env_var in os.environ:
- del os.environ[env_var]
+ environ[env_var] = value
+ elif env_var in environ:
+ del environ[env_var]
def RunAndReturnOutput(args = None):
"""Runs the test program and returns its output."""
- return gtest_test_utils.Subprocess([COMMAND] + (args or [])).output
+ return gtest_test_utils.Subprocess([COMMAND] + (args or []),
+ env=environ).output
def RunAndExtractTestList(args = None):
"""Runs the test program and returns its exit code and a list of tests run."""
- p = gtest_test_utils.Subprocess([COMMAND] + (args or []))
+ p = gtest_test_utils.Subprocess([COMMAND] + (args or []), env=environ)
tests_run = []
test_case = ''
test = ''
@@ -157,15 +204,12 @@ def RunAndExtractTestList(args = None):
def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs):
"""Runs the given function and arguments in a modified environment."""
try:
- original_env = os.environ.copy()
- os.environ.update(extra_env)
+ original_env = environ.copy()
+ environ.update(extra_env)
return function(*args, **kwargs)
finally:
- for key in extra_env.iterkeys():
- if key in original_env:
- os.environ[key] = original_env[key]
- else:
- del os.environ[key]
+ environ.clear()
+ environ.update(original_env)
def RunWithSharding(total_shards, shard_index, command):
@@ -179,7 +223,7 @@ def RunWithSharding(total_shards, shard_index, command):
class GTestFilterUnitTest(gtest_test_utils.TestCase):
- """Tests GTEST_FILTER env variable or --gtest_filter flag to filter tests."""
+ """Tests the env variable or the command line flag to filter tests."""
# Utilities.
@@ -211,26 +255,26 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
return tests_to_run
def RunAndVerify(self, gtest_filter, tests_to_run):
- """Checks that the binary runs correct set of tests for the given filter."""
+ """Checks that the binary runs correct set of tests for a given filter."""
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
- # First, tests using GTEST_FILTER.
+ # First, tests using the environment variable.
# Windows removes empty variables from the environment when passing it
- # to a new process. This means it is impossible to pass an empty filter
- # into a process using the GTEST_FILTER environment variable. However,
- # we can still test the case when the variable is not supplied (i.e.,
- # gtest_filter is None).
+ # to a new process. This means it is impossible to pass an empty filter
+ # into a process using the environment variable. However, we can still
+ # test the case when the variable is not supplied (i.e., gtest_filter is
+ # None).
# pylint: disable-msg=C6403
- if not IS_WINDOWS or gtest_filter != '':
+ if CAN_TEST_EMPTY_FILTER or gtest_filter != '':
SetEnvVar(FILTER_ENV_VAR, gtest_filter)
tests_run = RunAndExtractTestList()[0]
SetEnvVar(FILTER_ENV_VAR, None)
self.AssertSetEqual(tests_run, tests_to_run)
# pylint: enable-msg=C6403
- # Next, tests using --gtest_filter.
+ # Next, tests using the command line flag.
if gtest_filter is None:
args = []
@@ -260,12 +304,12 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# Windows removes empty variables from the environment when passing it
- # to a new process. This means it is impossible to pass an empty filter
- # into a process using the GTEST_FILTER environment variable. However,
- # we can still test the case when the variable is not supplied (i.e.,
- # gtest_filter is None).
+ # to a new process. This means it is impossible to pass an empty filter
+ # into a process using the environment variable. However, we can still
+ # test the case when the variable is not supplied (i.e., gtest_filter is
+ # None).
# pylint: disable-msg=C6403
- if not IS_WINDOWS or gtest_filter != '':
+ if CAN_TEST_EMPTY_FILTER or gtest_filter != '':
SetEnvVar(FILTER_ENV_VAR, gtest_filter)
partition = []
for i in range(0, total_shards):
@@ -404,10 +448,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
'BazTest.TestOne',
'BazTest.TestA',
- 'BazTest.TestB',
-
- 'HasDeathTest.Test1',
- 'HasDeathTest.Test2', ] + PARAM_TESTS)
+ 'BazTest.TestB', ] + DEATH_TESTS + PARAM_TESTS)
def testWildcardInTestName(self):
"""Tests using wildcard in the test name."""
@@ -468,7 +509,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
])
def testNegativeFilters(self):
- self.RunAndVerify('*-HasDeathTest.Test1', [
+ self.RunAndVerify('*-BazTest.TestOne', [
'FooTest.Abc',
'FooTest.Xyz',
@@ -476,24 +517,17 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
'BarTest.TestTwo',
'BarTest.TestThree',
- 'BazTest.TestOne',
'BazTest.TestA',
'BazTest.TestB',
+ ] + DEATH_TESTS + PARAM_TESTS)
- 'HasDeathTest.Test2',
- ] + PARAM_TESTS)
-
- self.RunAndVerify('*-FooTest.Abc:HasDeathTest.*', [
+ self.RunAndVerify('*-FooTest.Abc:BazTest.*', [
'FooTest.Xyz',
'BarTest.TestOne',
'BarTest.TestTwo',
'BarTest.TestThree',
-
- 'BazTest.TestOne',
- 'BazTest.TestA',
- 'BazTest.TestB',
- ] + PARAM_TESTS)
+ ] + DEATH_TESTS + PARAM_TESTS)
self.RunAndVerify('BarTest.*-BarTest.TestOne', [
'BarTest.TestTwo',
@@ -501,15 +535,11 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
])
# Tests without leading '*'.
- self.RunAndVerify('-FooTest.Abc:FooTest.Xyz:HasDeathTest.*', [
+ self.RunAndVerify('-FooTest.Abc:FooTest.Xyz:BazTest.*', [
'BarTest.TestOne',
'BarTest.TestTwo',
'BarTest.TestThree',
-
- 'BazTest.TestOne',
- 'BazTest.TestA',
- 'BazTest.TestB',
- ] + PARAM_TESTS)
+ ] + DEATH_TESTS + PARAM_TESTS)
# Value parameterized tests.
self.RunAndVerify('*/*', PARAM_TESTS)
@@ -555,7 +585,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
os.remove(shard_status_file)
def testShardStatusFileIsCreatedWithListTests(self):
- """Tests that the shard file is created with --gtest_list_tests."""
+ """Tests that the shard file is created with the "list_tests" flag."""
shard_status_file = os.path.join(gtest_test_utils.GetTempDir(),
'shard_status_file2')
@@ -563,32 +593,41 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file}
try:
- InvokeWithModifiedEnv(extra_env,
- RunAndReturnOutput,
- ['--gtest_list_tests'])
+ output = InvokeWithModifiedEnv(extra_env,
+ RunAndReturnOutput,
+ [LIST_TESTS_FLAG])
finally:
+ # This assertion ensures that Google Test enumerated the tests as
+ # opposed to running them.
+ self.assert_('[==========]' not in output,
+ 'Unexpected output during test enumeration.\n'
+ 'Please ensure that LIST_TESTS_FLAG is assigned the\n'
+ 'correct flag value for listing Google Test tests.')
+
self.assert_(os.path.exists(shard_status_file))
os.remove(shard_status_file)
- def testShardingWorksWithDeathTests(self):
- """Tests integration with death tests and sharding."""
- gtest_filter = 'HasDeathTest.*:SeqP/*'
- expected_tests = [
- 'HasDeathTest.Test1',
- 'HasDeathTest.Test2',
-
- 'SeqP/ParamTest.TestX/0',
- 'SeqP/ParamTest.TestX/1',
- 'SeqP/ParamTest.TestY/0',
- 'SeqP/ParamTest.TestY/1',
- ]
-
- for flag in ['--gtest_death_test_style=threadsafe',
- '--gtest_death_test_style=fast']:
- self.RunAndVerifyWithSharding(gtest_filter, 3, expected_tests,
- check_exit_0=True, args=[flag])
- self.RunAndVerifyWithSharding(gtest_filter, 5, expected_tests,
- check_exit_0=True, args=[flag])
+ if SUPPORTS_DEATH_TESTS:
+ def testShardingWorksWithDeathTests(self):
+ """Tests integration with death tests and sharding."""
+
+ gtest_filter = 'HasDeathTest.*:SeqP/*'
+ expected_tests = [
+ 'HasDeathTest.Test1',
+ 'HasDeathTest.Test2',
+
+ 'SeqP/ParamTest.TestX/0',
+ 'SeqP/ParamTest.TestX/1',
+ 'SeqP/ParamTest.TestY/0',
+ 'SeqP/ParamTest.TestY/1',
+ ]
+
+ for flag in ['--gtest_death_test_style=threadsafe',
+ '--gtest_death_test_style=fast']:
+ self.RunAndVerifyWithSharding(gtest_filter, 3, expected_tests,
+ check_exit_0=True, args=[flag])
+ self.RunAndVerifyWithSharding(gtest_filter, 5, expected_tests,
+ check_exit_0=True, args=[flag])
if __name__ == '__main__':
gtest_test_utils.Main()
diff --git a/gtest/test/gtest_help_test.py b/gtest/test/gtest_help_test.py
index 91081ad..3cb4c48 100755
--- a/gtest/test/gtest_help_test.py
+++ b/gtest/test/gtest_help_test.py
@@ -50,6 +50,15 @@ PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_')
FLAG_PREFIX = '--gtest_'
CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions'
DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style'
+UNKNOWN_FLAG = FLAG_PREFIX + 'unknown_flag_for_testing'
+LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests'
+INCORRECT_FLAG_VARIANTS = [re.sub('^--', '-', LIST_TESTS_FLAG),
+ re.sub('^--', '/', LIST_TESTS_FLAG),
+ re.sub('_', '-', LIST_TESTS_FLAG)]
+INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing'
+
+SUPPORTS_DEATH_TESTS = "DeathTest" in gtest_test_utils.Subprocess(
+ [PROGRAM_PATH, LIST_TESTS_FLAG]).output
# The help message must match this regex.
HELP_REGEX = re.compile(
@@ -88,18 +97,41 @@ class GTestHelpTest(gtest_test_utils.TestCase):
"""Tests the --help flag and its equivalent forms."""
def TestHelpFlag(self, flag):
- """Verifies that the right message is printed and the tests are
- skipped when the given flag is specified."""
+ """Verifies correct behavior when help flag is specified.
+
+ The right message must be printed and the tests must
+ skipped when the given flag is specified.
+
+ Args:
+ flag: A flag to pass to the binary or None.
+ """
exit_code, output = RunWithFlag(flag)
self.assertEquals(0, exit_code)
self.assert_(HELP_REGEX.search(output), output)
if IS_WINDOWS:
self.assert_(CATCH_EXCEPTIONS_FLAG in output, output)
- self.assert_(DEATH_TEST_STYLE_FLAG not in output, output)
else:
self.assert_(CATCH_EXCEPTIONS_FLAG not in output, output)
+
+ if SUPPORTS_DEATH_TESTS and not IS_WINDOWS:
self.assert_(DEATH_TEST_STYLE_FLAG in output, output)
+ else:
+ self.assert_(DEATH_TEST_STYLE_FLAG not in output, output)
+
+ def TestNonHelpFlag(self, flag):
+ """Verifies correct behavior when no help flag is specified.
+
+ Verifies that when no help flag is specified, the tests are run
+ and the help message is not printed.
+
+ Args:
+ flag: A flag to pass to the binary or None.
+ """
+
+ exit_code, output = RunWithFlag(flag)
+ self.assert_(exit_code != 0)
+ self.assert_(not HELP_REGEX.search(output), output)
def testPrintsHelpWithFullFlag(self):
self.TestHelpFlag('--help')
@@ -113,13 +145,24 @@ class GTestHelpTest(gtest_test_utils.TestCase):
def testPrintsHelpWithWindowsStyleQuestionFlag(self):
self.TestHelpFlag('/?')
+ def testPrintsHelpWithUnrecognizedGoogleTestFlag(self):
+ self.TestHelpFlag(UNKNOWN_FLAG)
+
+ def testPrintsHelpWithIncorrectFlagStyle(self):
+ for incorrect_flag in INCORRECT_FLAG_VARIANTS:
+ self.TestHelpFlag(incorrect_flag)
+
def testRunsTestsWithoutHelpFlag(self):
"""Verifies that when no help flag is specified, the tests are run
and the help message is not printed."""
- exit_code, output = RunWithFlag(None)
- self.assert_(exit_code != 0)
- self.assert_(not HELP_REGEX.search(output), output)
+ self.TestNonHelpFlag(None)
+
+ def testRunsTestsWithGtestInternalFlag(self):
+ """Verifies that the tests are run and no help message is printed when
+ a flag starting with Google Test prefix and 'internal_' is supplied."""
+
+ self.TestNonHelpFlag(INTERNAL_FLAG_FOR_TESTING)
if __name__ == '__main__':
diff --git a/gtest/test/gtest_help_test_.cc b/gtest/test/gtest_help_test_.cc
index 0282bc8..aad0d72 100644
--- a/gtest/test/gtest_help_test_.cc
+++ b/gtest/test/gtest_help_test_.cc
@@ -40,3 +40,7 @@
TEST(HelpFlagTest, ShouldNotBeRun) {
ASSERT_TRUE(false) << "Tests shouldn't be run when --help is specified.";
}
+
+#if GTEST_HAS_DEATH_TEST
+TEST(DeathTest, UsedByPythonScriptToDetectSupportForDeathTestsInThisBinary) {}
+#endif
diff --git a/gtest/test/gtest_nc.cc b/gtest/test/gtest_nc.cc
deleted file mode 100644
index 73b5db6..0000000
--- a/gtest/test/gtest_nc.cc
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright 2007, Google Inc.
-// All rights reserved.
-//
-// 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: wan@google.com (Zhanyong Wan)
-
-// This file is the input to a negative-compilation test for Google
-// Test. Code here is NOT supposed to compile. Its purpose is to
-// verify that certain incorrect usages of the Google Test API are
-// indeed rejected by the compiler.
-//
-// We still need to write the negative-compilation test itself, which
-// will be tightly coupled with the build environment.
-//
-// TODO(wan@google.com): finish the negative-compilation test.
-
-#ifdef TEST_CANNOT_IGNORE_RUN_ALL_TESTS_RESULT
-// Tests that the result of RUN_ALL_TESTS() cannot be ignored.
-
-#include <gtest/gtest.h>
-
-int main(int argc, char** argv) {
- testing::InitGoogleTest(&argc, argv);
- RUN_ALL_TESTS(); // This line shouldn't compile.
-}
-
-#elif defined(TEST_USER_CANNOT_INCLUDE_GTEST_INTERNAL_INL_H)
-// Tests that a user cannot include gtest-internal-inl.h in his code.
-
-#include "src/gtest-internal-inl.h"
-
-#elif defined(TEST_CATCHES_DECLARING_SETUP_IN_TEST_FIXTURE_WITH_TYPO)
-// Tests that the compiler catches the typo when a user declares a
-// Setup() method in a test fixture.
-
-#include <gtest/gtest.h>
-
-class MyTest : public testing::Test {
- protected:
- void Setup() {}
-};
-
-#elif defined(TEST_CATCHES_CALLING_SETUP_IN_TEST_WITH_TYPO)
-// Tests that the compiler catches the typo when a user calls Setup()
-// from a test fixture.
-
-#include <gtest/gtest.h>
-
-class MyTest : public testing::Test {
- protected:
- virtual void SetUp() {
- testing::Test::Setup(); // Tries to call SetUp() in the parent class.
- }
-};
-
-#elif defined(TEST_CATCHES_DECLARING_SETUP_IN_ENVIRONMENT_WITH_TYPO)
-// Tests that the compiler catches the typo when a user declares a
-// Setup() method in a subclass of Environment.
-
-#include <gtest/gtest.h>
-
-class MyEnvironment : public testing::Environment {
- public:
- void Setup() {}
-};
-
-#elif defined(TEST_CATCHES_CALLING_SETUP_IN_ENVIRONMENT_WITH_TYPO)
-// Tests that the compiler catches the typo when a user calls Setup()
-// in an Environment.
-
-#include <gtest/gtest.h>
-
-class MyEnvironment : public testing::Environment {
- protected:
- virtual void SetUp() {
- // Tries to call SetUp() in the parent class.
- testing::Environment::Setup();
- }
-};
-
-#elif defined(TEST_CATCHES_WRONG_CASE_IN_TYPED_TEST_P)
-// Tests that the compiler catches using the wrong test case name in
-// TYPED_TEST_P.
-
-#include <gtest/gtest.h>
-
-template <typename T>
-class FooTest : public testing::Test {
-};
-
-template <typename T>
-class BarTest : public testing::Test {
-};
-
-TYPED_TEST_CASE_P(FooTest);
-TYPED_TEST_P(BarTest, A) {} // Wrong test case name.
-REGISTER_TYPED_TEST_CASE_P(FooTest, A);
-INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types<int>);
-
-#elif defined(TEST_CATCHES_WRONG_CASE_IN_REGISTER_TYPED_TEST_CASE_P)
-// Tests that the compiler catches using the wrong test case name in
-// REGISTER_TYPED_TEST_CASE_P.
-
-#include <gtest/gtest.h>
-
-template <typename T>
-class FooTest : public testing::Test {
-};
-
-template <typename T>
-class BarTest : public testing::Test {
-};
-
-TYPED_TEST_CASE_P(FooTest);
-TYPED_TEST_P(FooTest, A) {}
-REGISTER_TYPED_TEST_CASE_P(BarTest, A); // Wrong test case name.
-INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types<int>);
-
-#elif defined(TEST_CATCHES_WRONG_CASE_IN_INSTANTIATE_TYPED_TEST_CASE_P)
-// Tests that the compiler catches using the wrong test case name in
-// INSTANTIATE_TYPED_TEST_CASE_P.
-
-#include <gtest/gtest.h>
-
-template <typename T>
-class FooTest : public testing::Test {
-};
-
-template <typename T>
-class BarTest : public testing::Test {
-};
-
-TYPED_TEST_CASE_P(FooTest);
-TYPED_TEST_P(FooTest, A) {}
-REGISTER_TYPED_TEST_CASE_P(FooTest, A);
-
-// Wrong test case name.
-INSTANTIATE_TYPED_TEST_CASE_P(My, BarTest, testing::Types<int>);
-
-#elif defined(TEST_CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX)
-// Tests that the compiler catches instantiating TYPED_TEST_CASE_P
-// twice with the same name prefix.
-
-#include <gtest/gtest.h>
-
-template <typename T>
-class FooTest : public testing::Test {
-};
-
-TYPED_TEST_CASE_P(FooTest);
-TYPED_TEST_P(FooTest, A) {}
-REGISTER_TYPED_TEST_CASE_P(FooTest, A);
-
-INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types<int>);
-
-// Wrong name prefix: "My" has been used.
-INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types<double>);
-
-#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE)
-
-#include <gtest/gtest.h>
-
-// Tests that StaticAssertTypeEq<T1, T2> cannot be used as a type.
-testing::StaticAssertTypeEq<int, int> dummy;
-
-#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE)
-
-#include <gtest/gtest.h>
-
-// Tests that StaticAssertTypeEq<T1, T2> works in a namespace scope.
-static bool dummy = testing::StaticAssertTypeEq<int, const int>();
-
-#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_CLASS)
-
-#include <gtest/gtest.h>
-
-template <typename T>
-class Helper {
- public:
- // Tests that StaticAssertTypeEq<T1, T2> works in a class.
- Helper() { testing::StaticAssertTypeEq<int, T>(); }
-
- void DoSomething() {}
-};
-
-void Test() {
- Helper<bool> h;
- h.DoSomething(); // To avoid the "unused variable" warning.
-}
-
-#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_FUNCTION)
-
-#include <gtest/gtest.h>
-
-void Test() {
- // Tests that StaticAssertTypeEq<T1, T2> works inside a function.
- testing::StaticAssertTypeEq<const int, int>();
-}
-
-#else
-// A sanity test. This should compile.
-
-#include <gtest/gtest.h>
-
-int main() {
- return RUN_ALL_TESTS();
-}
-
-#endif
diff --git a/gtest/test/gtest_nc_test.py b/gtest/test/gtest_nc_test.py
deleted file mode 100755
index 06ffb3f..0000000
--- a/gtest/test/gtest_nc_test.py
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2007, Google Inc.
-# All rights reserved.
-#
-# 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.
-
-"""Negative compilation test for Google Test."""
-
-__author__ = 'wan@google.com (Zhanyong Wan)'
-
-import os
-import sys
-import unittest
-
-
-IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux'
-if not IS_LINUX:
- sys.exit(0) # Negative compilation tests are not supported on Windows & Mac.
-
-
-class GTestNCTest(unittest.TestCase):
- """Negative compilation test for Google Test."""
-
- def testCompilerError(self):
- """Verifies that erroneous code leads to expected compiler
- messages."""
-
- # Defines a list of test specs, where each element is a tuple
- # (test name, list of regexes for matching the compiler errors).
- test_specs = [
- ('CANNOT_IGNORE_RUN_ALL_TESTS_RESULT',
- [r'ignoring return value']),
-
- ('USER_CANNOT_INCLUDE_GTEST_INTERNAL_INL_H',
- [r'must not be included except by Google Test itself']),
-
- ('CATCHES_DECLARING_SETUP_IN_TEST_FIXTURE_WITH_TYPO',
- [r'Setup_should_be_spelled_SetUp']),
-
- ('CATCHES_CALLING_SETUP_IN_TEST_WITH_TYPO',
- [r'Setup_should_be_spelled_SetUp']),
-
- ('CATCHES_DECLARING_SETUP_IN_ENVIRONMENT_WITH_TYPO',
- [r'Setup_should_be_spelled_SetUp']),
-
- ('CATCHES_CALLING_SETUP_IN_ENVIRONMENT_WITH_TYPO',
- [r'Setup_should_be_spelled_SetUp']),
-
- ('CATCHES_WRONG_CASE_IN_TYPED_TEST_P',
- [r'BarTest.*was not declared']),
-
- ('CATCHES_WRONG_CASE_IN_REGISTER_TYPED_TEST_CASE_P',
- [r'BarTest.*was not declared']),
-
- ('CATCHES_WRONG_CASE_IN_INSTANTIATE_TYPED_TEST_CASE_P',
- [r'BarTest.*not declared']),
-
- ('CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX',
- [r'redefinition of.*My.*FooTest']),
-
- ('STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE',
- [r'StaticAssertTypeEq.* does not name a type']),
-
- ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE',
- [r'StaticAssertTypeEq.*int.*const int']),
-
- ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_CLASS',
- [r'StaticAssertTypeEq.*int.*bool']),
-
- ('STATIC_ASSERT_TYPE_EQ_WORKS_IN_FUNCTION',
- [r'StaticAssertTypeEq.*const int.*int']),
-
- ('SANITY',
- None)
- ]
-
- # TODO(wan@google.com): verify that the test specs are satisfied.
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/gtest/test/gtest_output_test.py b/gtest/test/gtest_output_test.py
index c8a38f5..192030a 100755
--- a/gtest/test/gtest_output_test.py
+++ b/gtest/test/gtest_output_test.py
@@ -48,6 +48,7 @@ import gtest_test_utils
# The flag for generating the golden file
GENGOLDEN_FLAG = '--gengolden'
+CATCH_EXCEPTIONS_ENV_VAR_NAME = 'GTEST_CATCH_EXCEPTIONS'
IS_WINDOWS = os.name == 'nt'
@@ -123,18 +124,32 @@ def RemoveTime(output):
return re.sub(r'\(\d+ ms', '(? ms', output)
+def RemoveTypeInfoDetails(test_output):
+ """Removes compiler-specific type info from Google Test program's output.
+
+ Args:
+ test_output: the output of a Google Test program.
+
+ Returns:
+ output with type information normalized to canonical form.
+ """
+
+ # some compilers output the name of type 'unsigned int' as 'unsigned'
+ return re.sub(r'unsigned int', 'unsigned', test_output)
+
+
def RemoveTestCounts(output):
"""Removes test counts from a Google Test program's output."""
- output = re.sub(r'\d+ tests, listed below',
+ output = re.sub(r'\d+ tests?, listed below',
'? tests, listed below', output)
output = re.sub(r'\d+ FAILED TESTS',
'? FAILED TESTS', output)
- output = re.sub(r'\d+ tests from \d+ test cases',
+ output = re.sub(r'\d+ tests? from \d+ test cases?',
'? tests from ? test cases', output)
- output = re.sub(r'\d+ tests from ([a-zA-Z_])',
+ output = re.sub(r'\d+ tests? from ([a-zA-Z_])',
r'? tests from \1', output)
- return re.sub(r'\d+ tests\.', '? tests.', output)
+ return re.sub(r'\d+ tests?\.', '? tests.', output)
def RemoveMatchingTests(test_output, pattern):
@@ -184,16 +199,9 @@ def GetShellCommandOutput(env_cmd):
# Spawns cmd in a sub-process, and gets its standard I/O file objects.
# Set and save the environment properly.
- old_env_vars = dict(os.environ)
- os.environ.update(env_cmd[0])
- p = gtest_test_utils.Subprocess(env_cmd[1])
-
- # Changes made by os.environ.clear are not inheritable by child processes
- # until Python 2.6. To produce inheritable changes we have to delete
- # environment items with the del statement.
- for key in os.environ.keys():
- del os.environ[key]
- os.environ.update(old_env_vars)
+ environ = os.environ.copy()
+ environ.update(env_cmd[0])
+ p = gtest_test_utils.Subprocess(env_cmd[1], env=environ)
return p.output
@@ -209,8 +217,10 @@ def GetCommandOutput(env_cmd):
"""
# Disables exception pop-ups on Windows.
- os.environ['GTEST_CATCH_EXCEPTIONS'] = '1'
- return NormalizeOutput(GetShellCommandOutput(env_cmd))
+ environ, cmdline = env_cmd
+ environ = dict(environ) # Ensures we are modifying a copy.
+ environ[CATCH_EXCEPTIONS_ENV_VAR_NAME] = '1'
+ return NormalizeOutput(GetShellCommandOutput((environ, cmdline)))
def GetOutputOfAllCommands():
@@ -228,7 +238,9 @@ SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list
SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list
SUPPORTS_STACK_TRACES = False
-CAN_GENERATE_GOLDEN_FILE = SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS
+CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and
+ SUPPORTS_TYPED_TESTS and
+ SUPPORTS_THREADS)
class GTestOutputTest(gtest_test_utils.TestCase):
@@ -237,6 +249,8 @@ class GTestOutputTest(gtest_test_utils.TestCase):
test_output = RemoveMatchingTests(test_output, 'DeathTest')
if not SUPPORTS_TYPED_TESTS:
test_output = RemoveMatchingTests(test_output, 'TypedTest')
+ test_output = RemoveMatchingTests(test_output, 'TypedDeathTest')
+ test_output = RemoveMatchingTests(test_output, 'TypeParamDeathTest')
if not SUPPORTS_THREADS:
test_output = RemoveMatchingTests(test_output,
'ExpectFailureWithThreadsTest')
@@ -262,24 +276,30 @@ class GTestOutputTest(gtest_test_utils.TestCase):
# We want the test to pass regardless of certain features being
# supported or not.
+
+ # We still have to remove type name specifics in all cases.
+ normalized_actual = RemoveTypeInfoDetails(output)
+ normalized_golden = RemoveTypeInfoDetails(golden)
+
if CAN_GENERATE_GOLDEN_FILE:
- self.assert_(golden == output)
+ self.assertEqual(normalized_golden, normalized_actual)
else:
- normalized_actual = RemoveTestCounts(output)
- normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests(golden))
+ normalized_actual = RemoveTestCounts(normalized_actual)
+ normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests(
+ normalized_golden))
- # This code is very handy when debugging test differences so I left it
- # here, commented.
- # open(os.path.join(
- # gtest_test_utils.GetSourceDir(),
- # '_gtest_output_test_normalized_actual.txt'), 'wb').write(
- # normalized_actual)
- # open(os.path.join(
- # gtest_test_utils.GetSourceDir(),
- # '_gtest_output_test_normalized_golden.txt'), 'wb').write(
- # normalized_golden)
+ # This code is very handy when debugging golden file differences:
+ if os.getenv('DEBUG_GTEST_OUTPUT_TEST'):
+ open(os.path.join(
+ gtest_test_utils.GetSourceDir(),
+ '_gtest_output_test_normalized_actual.txt'), 'wb').write(
+ normalized_actual)
+ open(os.path.join(
+ gtest_test_utils.GetSourceDir(),
+ '_gtest_output_test_normalized_golden.txt'), 'wb').write(
+ normalized_golden)
- self.assert_(normalized_golden == normalized_actual)
+ self.assertEqual(normalized_golden, normalized_actual)
if __name__ == '__main__':
@@ -298,8 +318,8 @@ that does not support all the required features (death tests""")
"""\nand typed tests). Please check that you are using VC++ 8.0 SP1
or higher as your compiler.""")
else:
- message += """\nand typed tests). Please generate the golden file
-using a binary built with those features enabled."""
+ message += """\ntyped tests, and threads). Please generate the
+golden file using a binary built with those features enabled."""
sys.stderr.write(message)
sys.exit(1)
diff --git a/gtest/test/gtest_output_test_.cc b/gtest/test/gtest_output_test_.cc
index 6d75602..273e8e9 100644
--- a/gtest/test/gtest_output_test_.cc
+++ b/gtest/test/gtest_output_test_.cc
@@ -46,15 +46,17 @@
#include <stdlib.h>
-#if GTEST_HAS_PTHREAD
-#include <pthread.h>
-#endif // GTEST_HAS_PTHREAD
-
+#if GTEST_IS_THREADSAFE
using testing::ScopedFakeTestPartResultReporter;
using testing::TestPartResultArray;
+using testing::internal::Notification;
+using testing::internal::ThreadWithParam;
+#endif
+
namespace posix = ::testing::internal::posix;
using testing::internal::String;
+using testing::internal::scoped_ptr;
// Tests catching fatal failures.
@@ -214,6 +216,83 @@ TEST(SCOPED_TRACETest, CanBeRepeated) {
<< "trace point A, B, and D.";
}
+#if GTEST_IS_THREADSAFE
+// Tests that SCOPED_TRACE()s can be used concurrently from multiple
+// threads. Namely, an assertion should be affected by
+// SCOPED_TRACE()s in its own thread only.
+
+// Here's the sequence of actions that happen in the test:
+//
+// Thread A (main) | Thread B (spawned)
+// ===============================|================================
+// spawns thread B |
+// -------------------------------+--------------------------------
+// waits for n1 | SCOPED_TRACE("Trace B");
+// | generates failure #1
+// | notifies n1
+// -------------------------------+--------------------------------
+// SCOPED_TRACE("Trace A"); | waits for n2
+// generates failure #2 |
+// notifies n2 |
+// -------------------------------|--------------------------------
+// waits for n3 | generates failure #3
+// | trace B dies
+// | generates failure #4
+// | notifies n3
+// -------------------------------|--------------------------------
+// generates failure #5 | finishes
+// trace A dies |
+// generates failure #6 |
+// -------------------------------|--------------------------------
+// waits for thread B to finish |
+
+struct CheckPoints {
+ Notification n1;
+ Notification n2;
+ Notification n3;
+};
+
+static void ThreadWithScopedTrace(CheckPoints* check_points) {
+ {
+ SCOPED_TRACE("Trace B");
+ ADD_FAILURE()
+ << "Expected failure #1 (in thread B, only trace B alive).";
+ check_points->n1.Notify();
+ check_points->n2.WaitForNotification();
+
+ ADD_FAILURE()
+ << "Expected failure #3 (in thread B, trace A & B both alive).";
+ } // Trace B dies here.
+ ADD_FAILURE()
+ << "Expected failure #4 (in thread B, only trace A alive).";
+ check_points->n3.Notify();
+}
+
+TEST(SCOPED_TRACETest, WorksConcurrently) {
+ printf("(expecting 6 failures)\n");
+
+ CheckPoints check_points;
+ ThreadWithParam<CheckPoints*> thread(&ThreadWithScopedTrace,
+ &check_points,
+ NULL);
+ check_points.n1.WaitForNotification();
+
+ {
+ SCOPED_TRACE("Trace A");
+ ADD_FAILURE()
+ << "Expected failure #2 (in thread A, trace A & B both alive).";
+ check_points.n2.Notify();
+ check_points.n3.WaitForNotification();
+
+ ADD_FAILURE()
+ << "Expected failure #5 (in thread A, only trace A alive).";
+ } // Trace A dies here.
+ ADD_FAILURE()
+ << "Expected failure #6 (in thread A, no trace alive).";
+ thread.Join();
+}
+#endif // GTEST_IS_THREADSAFE
+
TEST(DisabledTestsWarningTest,
DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning) {
// This test body is intentionally empty. Its sole purpose is for
@@ -479,6 +558,63 @@ TEST_F(ExceptionInTearDownTest, ExceptionInTearDown) {
#endif // GTEST_OS_WINDOWS
+#if GTEST_IS_THREADSAFE
+
+// A unary function that may die.
+void DieIf(bool should_die) {
+ GTEST_CHECK_(!should_die) << " - death inside DieIf().";
+}
+
+// Tests running death tests in a multi-threaded context.
+
+// Used for coordination between the main and the spawn thread.
+struct SpawnThreadNotifications {
+ SpawnThreadNotifications() {}
+
+ Notification spawn_thread_started;
+ Notification spawn_thread_ok_to_terminate;
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(SpawnThreadNotifications);
+};
+
+// The function to be executed in the thread spawn by the
+// MultipleThreads test (below).
+static void ThreadRoutine(SpawnThreadNotifications* notifications) {
+ // Signals the main thread that this thread has started.
+ notifications->spawn_thread_started.Notify();
+
+ // Waits for permission to finish from the main thread.
+ notifications->spawn_thread_ok_to_terminate.WaitForNotification();
+}
+
+// This is a death-test test, but it's not named with a DeathTest
+// suffix. It starts threads which might interfere with later
+// death tests, so it must run after all other death tests.
+class DeathTestAndMultiThreadsTest : public testing::Test {
+ protected:
+ // Starts a thread and waits for it to begin.
+ virtual void SetUp() {
+ thread_.reset(new ThreadWithParam<SpawnThreadNotifications*>(
+ &ThreadRoutine, &notifications_, NULL));
+ notifications_.spawn_thread_started.WaitForNotification();
+ }
+ // Tells the thread to finish, and reaps it.
+ // Depending on the version of the thread library in use,
+ // a manager thread might still be left running that will interfere
+ // with later death tests. This is unfortunate, but this class
+ // cleans up after itself as best it can.
+ virtual void TearDown() {
+ notifications_.spawn_thread_ok_to_terminate.Notify();
+ }
+
+ private:
+ SpawnThreadNotifications notifications_;
+ scoped_ptr<ThreadWithParam<SpawnThreadNotifications*> > thread_;
+};
+
+#endif // GTEST_IS_THREADSAFE
+
// The MixedUpTestCaseTest test case verifies that Google Test will fail a
// test if it uses a different fixture class than what other tests in
// the same test case use. It deliberately contains two fixture
@@ -849,23 +985,13 @@ TEST_F(ExpectFailureTest, ExpectNonFatalFailure) {
"failure.");
}
-#if GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD
+#if GTEST_IS_THREADSAFE
class ExpectFailureWithThreadsTest : public ExpectFailureTest {
protected:
static void AddFailureInOtherThread(FailureMode failure) {
- pthread_t tid;
- pthread_create(&tid,
- NULL,
- ExpectFailureWithThreadsTest::FailureThread,
- &failure);
- pthread_join(tid, NULL);
- }
- private:
- static void* FailureThread(void* attr) {
- FailureMode* failure = static_cast<FailureMode*>(attr);
- AddFailure(*failure);
- return NULL;
+ ThreadWithParam<FailureMode> thread(&AddFailure, failure, NULL);
+ thread.Join();
}
};
@@ -901,7 +1027,7 @@ TEST_F(ScopedFakeTestPartResultReporterTest, InterceptOnlyCurrentThread) {
EXPECT_EQ(0, results.size()) << "This shouldn't fail.";
}
-#endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD
+#endif // GTEST_IS_THREADSAFE
TEST_F(ExpectFailureTest, ExpectFatalFailureOnAllThreads) {
// Expected fatal failure, but succeeds.
diff --git a/gtest/test/gtest_output_test_golden_lin.txt b/gtest/test/gtest_output_test_golden_lin.txt
index 51bae52..ec60437 100644
--- a/gtest/test/gtest_output_test_golden_lin.txt
+++ b/gtest/test/gtest_output_test_golden_lin.txt
@@ -7,7 +7,7 @@ Expected: true
gtest_output_test_.cc:#: Failure
Value of: 3
Expected: 2
-[==========] Running 56 tests from 23 test cases.
+[==========] Running 60 tests from 25 test cases.
[----------] Global test environment set-up.
FooEnvironment::SetUp() called.
BarEnvironment::SetUp() called.
@@ -65,7 +65,7 @@ i == 3
gtest_output_test_.cc:#: Failure
Expected: (3) >= (a[i]), actual: 3 vs 6
[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions
-[----------] 5 tests from SCOPED_TRACETest
+[----------] 6 tests from SCOPED_TRACETest
[ RUN ] SCOPED_TRACETest.ObeysScopes
(expected to fail)
gtest_output_test_.cc:#: Failure
@@ -148,6 +148,35 @@ gtest_output_test_.cc:#: D
gtest_output_test_.cc:#: B
gtest_output_test_.cc:#: A
[ FAILED ] SCOPED_TRACETest.CanBeRepeated
+[ RUN ] SCOPED_TRACETest.WorksConcurrently
+(expecting 6 failures)
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #1 (in thread B, only trace B alive).
+Google Test trace:
+gtest_output_test_.cc:#: Trace B
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #2 (in thread A, trace A & B both alive).
+Google Test trace:
+gtest_output_test_.cc:#: Trace A
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #3 (in thread B, trace A & B both alive).
+Google Test trace:
+gtest_output_test_.cc:#: Trace B
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #4 (in thread B, only trace A alive).
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #5 (in thread A, only trace A alive).
+Google Test trace:
+gtest_output_test_.cc:#: Trace A
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #6 (in thread A, no trace alive).
+[ FAILED ] SCOPED_TRACETest.WorksConcurrently
[----------] 1 test from NonFatalFailureInFixtureConstructorTest
[ RUN ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor
(expecting 5 failures)
@@ -506,6 +535,35 @@ Failed
Expected non-fatal failure.
[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads
+[----------] 2 tests from ExpectFailureWithThreadsTest
+[ RUN ] ExpectFailureWithThreadsTest.ExpectFatalFailure
+(expecting 2 failures)
+gtest_output_test_.cc:#: Failure
+Failed
+Expected fatal failure.
+gtest.cc:#: Failure
+Expected: 1 fatal failure
+ Actual: 0 failures
+[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure
+[ RUN ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure
+(expecting 2 failures)
+gtest_output_test_.cc:#: Failure
+Failed
+Expected non-fatal failure.
+gtest.cc:#: Failure
+Expected: 1 non-fatal failure
+ Actual: 0 failures
+[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure
+[----------] 1 test from ScopedFakeTestPartResultReporterTest
+[ RUN ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread
+(expecting 2 failures)
+gtest_output_test_.cc:#: Failure
+Failed
+Expected fatal failure.
+gtest_output_test_.cc:#: Failure
+Failed
+Expected non-fatal failure.
+[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread
[----------] Global test environment tear-down
BarEnvironment::TearDown() called.
gtest_output_test_.cc:#: Failure
@@ -515,9 +573,9 @@ FooEnvironment::TearDown() called.
gtest_output_test_.cc:#: Failure
Failed
Expected fatal failure.
-[==========] 56 tests from 23 test cases ran.
+[==========] 60 tests from 25 test cases ran.
[ PASSED ] 21 tests.
-[ FAILED ] 35 tests, listed below:
+[ FAILED ] 39 tests, listed below:
[ FAILED ] FatalFailureTest.FatalFailureInSubroutine
[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine
[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine
@@ -527,6 +585,7 @@ Expected fatal failure.
[ FAILED ] SCOPED_TRACETest.WorksInSubroutine
[ FAILED ] SCOPED_TRACETest.CanBeNested
[ FAILED ] SCOPED_TRACETest.CanBeRepeated
+[ FAILED ] SCOPED_TRACETest.WorksConcurrently
[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor
[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor
[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp
@@ -553,8 +612,11 @@ Expected fatal failure.
[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure
[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads
[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads
+[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure
+[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure
+[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread
-35 FAILED TESTS
+39 FAILED TESTS
 YOU HAVE 1 DISABLED TEST
Note: Google Test filter = FatalFailureTest.*:LoggingTest.*
diff --git a/gtest/test/gtest_shuffle_test.py b/gtest/test/gtest_shuffle_test.py
index a870a01..30d0303 100755
--- a/gtest/test/gtest_shuffle_test.py
+++ b/gtest/test/gtest_shuffle_test.py
@@ -78,16 +78,10 @@ def RandomSeedFlag(n):
def RunAndReturnOutput(extra_env, args):
"""Runs the test program and returns its output."""
- try:
- original_env = os.environ.copy()
- os.environ.update(extra_env)
- return gtest_test_utils.Subprocess([COMMAND] + args).output
- finally:
- for key in extra_env.iterkeys():
- if key in original_env:
- os.environ[key] = original_env[key]
- else:
- del os.environ[key]
+ environ_copy = os.environ.copy()
+ environ_copy.update(extra_env)
+
+ return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy).output
def GetTestsForAllIterations(extra_env, args):
diff --git a/gtest/test/gtest_stress_test.cc b/gtest/test/gtest_stress_test.cc
index 0034bb8..f5af78c 100644
--- a/gtest/test/gtest_stress_test.cc
+++ b/gtest/test/gtest_stress_test.cc
@@ -32,9 +32,11 @@
// Tests that SCOPED_TRACE() and various Google Test assertions can be
// used in a large number of threads concurrently.
-#include <iostream>
#include <gtest/gtest.h>
+#include <iostream>
+#include <vector>
+
// We must define this macro in order to #include
// gtest-internal-inl.h. This is how Google Test prevents a user from
// accidentally depending on its internal implementation.
@@ -42,12 +44,20 @@
#include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
+#if GTEST_IS_THREADSAFE
+
namespace testing {
namespace {
+using internal::Notification;
using internal::String;
using internal::TestPropertyKeyIs;
-using internal::Vector;
+using internal::ThreadWithParam;
+using internal::scoped_ptr;
+
+// In order to run tests in this file, for platforms where Google Test is
+// thread safe, implement ThreadWithParam. See the description of its API
+// in gtest-port.h, where it is defined for already supported platforms.
// How many threads to create?
const int kThreadCount = 50;
@@ -64,12 +74,13 @@ String IdToString(int id) {
return id_message.GetString();
}
-void ExpectKeyAndValueWereRecordedForId(const Vector<TestProperty>& properties,
- int id,
- const char* suffix) {
+void ExpectKeyAndValueWereRecordedForId(
+ const std::vector<TestProperty>& properties,
+ int id, const char* suffix) {
TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str());
- const TestProperty* property = properties.FindIf(matches_key);
- ASSERT_TRUE(property != NULL)
+ const std::vector<TestProperty>::const_iterator property =
+ std::find_if(properties.begin(), properties.end(), matches_key);
+ ASSERT_TRUE(property != properties.end())
<< "expecting " << suffix << " value for id " << id;
EXPECT_STREQ(IdToString(id).c_str(), property->value());
}
@@ -77,7 +88,7 @@ void ExpectKeyAndValueWereRecordedForId(const Vector<TestProperty>& properties,
// Calls a large number of Google Test assertions, where exactly one of them
// will fail.
void ManyAsserts(int id) {
- ::std::cout << "Thread #" << id << " running...\n";
+ GTEST_LOG_(INFO) << "Thread #" << id << " running...";
SCOPED_TRACE(Message() << "Thread #" << id);
@@ -104,41 +115,121 @@ void ManyAsserts(int id) {
}
}
+void CheckTestFailureCount(int expected_failures) {
+ const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
+ const TestResult* const result = info->result();
+ GTEST_CHECK_(expected_failures == result->total_part_count())
+ << "Logged " << result->total_part_count() << " failures "
+ << " vs. " << expected_failures << " expected";
+}
+
// Tests using SCOPED_TRACE() and Google Test assertions in many threads
// concurrently.
TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) {
- // TODO(wan): when Google Test is made thread-safe, run
- // ManyAsserts() in many threads here.
+ {
+ scoped_ptr<ThreadWithParam<int> > threads[kThreadCount];
+ Notification threads_can_start;
+ for (int i = 0; i != kThreadCount; i++)
+ threads[i].reset(new ThreadWithParam<int>(&ManyAsserts,
+ i,
+ &threads_can_start));
+
+ threads_can_start.Notify();
+
+ // Blocks until all the threads are done.
+ for (int i = 0; i != kThreadCount; i++)
+ threads[i]->Join();
+ }
+
+ // Ensures that kThreadCount*kThreadCount failures have been reported.
+ const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
+ const TestResult* const result = info->result();
+
+ std::vector<TestProperty> properties;
+ // We have no access to the TestResult's list of properties but we can
+ // copy them one by one.
+ for (int i = 0; i < result->test_property_count(); ++i)
+ properties.push_back(result->GetTestProperty(i));
+
+ EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count())
+ << "String and int values recorded on each thread, "
+ << "as well as one shared_key";
+ for (int i = 0; i < kThreadCount; ++i) {
+ ExpectKeyAndValueWereRecordedForId(properties, i, "string");
+ ExpectKeyAndValueWereRecordedForId(properties, i, "int");
+ }
+ CheckTestFailureCount(kThreadCount*kThreadCount);
+}
+
+void FailingThread(bool is_fatal) {
+ if (is_fatal)
+ FAIL() << "Fatal failure in some other thread. "
+ << "(This failure is expected.)";
+ else
+ ADD_FAILURE() << "Non-fatal failure in some other thread. "
+ << "(This failure is expected.)";
+}
+
+void GenerateFatalFailureInAnotherThread(bool is_fatal) {
+ ThreadWithParam<bool> thread(&FailingThread, is_fatal, NULL);
+ thread.Join();
}
TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) {
- // TODO(mheule@google.com): Test this works correctly when Google
- // Test is made thread-safe.
+ EXPECT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
+ // We should only have one failure (the one from
+ // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE
+ // should succeed.
+ CheckTestFailureCount(1);
}
+void AssertNoFatalFailureIgnoresFailuresInOtherThreads() {
+ ASSERT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
+}
TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) {
- // TODO(mheule@google.com): Test this works correctly when Google
- // Test is made thread-safe.
+ // Using a subroutine, to make sure, that the test continues.
+ AssertNoFatalFailureIgnoresFailuresInOtherThreads();
+ // We should only have one failure (the one from
+ // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE
+ // should succeed.
+ CheckTestFailureCount(1);
}
TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) {
- // TODO(mheule@google.com): Test this works correctly when Google
- // Test is made thread-safe.
+ // This statement should fail, since the current thread doesn't generate a
+ // fatal failure, only another one does.
+ EXPECT_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true), "expected");
+ CheckTestFailureCount(2);
}
TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) {
- // TODO(wan@google.com): Test this works correctly when Google Test
- // is made thread-safe.
+ // This statement should succeed, because failures in all threads are
+ // considered.
+ EXPECT_FATAL_FAILURE_ON_ALL_THREADS(
+ GenerateFatalFailureInAnotherThread(true), "expected");
+ CheckTestFailureCount(0);
+ // We need to add a failure, because main() checks that there are failures.
+ // But when only this test is run, we shouldn't have any failures.
+ ADD_FAILURE() << "This is an expected non-fatal failure.";
}
TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) {
- // TODO(mheule@google.com): Test this works correctly when Google
- // Test is made thread-safe.
+ // This statement should fail, since the current thread doesn't generate a
+ // fatal failure, only another one does.
+ EXPECT_NONFATAL_FAILURE(GenerateFatalFailureInAnotherThread(false),
+ "expected");
+ CheckTestFailureCount(2);
}
TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) {
- // TODO(wan@google.com): Test this works correctly when Google Test
- // is made thread-safe.
+ // This statement should succeed, because failures in all threads are
+ // considered.
+ EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(
+ GenerateFatalFailureInAnotherThread(false), "expected");
+ CheckTestFailureCount(0);
+ // We need to add a failure, because main() checks that there are failures,
+ // But when only this test is run, we shouldn't have any failures.
+ ADD_FAILURE() << "This is an expected non-fatal failure.";
}
} // namespace
@@ -147,5 +238,20 @@ TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) {
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
+ const int result = RUN_ALL_TESTS(); // Expected to fail.
+ GTEST_CHECK_(result == 1) << "RUN_ALL_TESTS() did not fail as expected";
+
+ printf("\nPASS\n");
+ return 0;
+}
+
+#else
+TEST(StressTest,
+ DISABLED_ThreadSafetyTestsAreSkippedWhenGoogleTestIsNotThreadSafe) {
+}
+
+int main(int argc, char **argv) {
+ testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
+#endif // GTEST_IS_THREADSAFE
diff --git a/gtest/test/gtest_test_utils.py b/gtest/test/gtest_test_utils.py
index 385662a..e0f5973 100755
--- a/gtest/test/gtest_test_utils.py
+++ b/gtest/test/gtest_test_utils.py
@@ -51,6 +51,7 @@ except:
_SUBPROCESS_MODULE_AVAILABLE = False
# pylint: enable-msg=C6204
+GTEST_OUTPUT_VAR_NAME = 'GTEST_OUTPUT'
IS_WINDOWS = os.name == 'nt'
IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0]
@@ -137,7 +138,7 @@ def GetTempDir():
return _temp_dir
-def GetTestExecutablePath(executable_name):
+def GetTestExecutablePath(executable_name, build_dir=None):
"""Returns the absolute path of the test binary given its name.
The function will print a message and abort the program if the resulting file
@@ -145,12 +146,15 @@ def GetTestExecutablePath(executable_name):
Args:
executable_name: name of the test binary that the test script runs.
+ build_dir: directory where to look for executables, by default
+ the result of GetBuildDir().
Returns:
The absolute path of the test binary.
"""
- path = os.path.abspath(os.path.join(GetBuildDir(), executable_name))
+ path = os.path.abspath(os.path.join(build_dir or GetBuildDir(),
+ executable_name))
if (IS_WINDOWS or IS_CYGWIN) and not path.endswith('.exe'):
path += '.exe'
@@ -190,23 +194,28 @@ def GetExitStatus(exit_code):
class Subprocess:
- def __init__(self, command, working_dir=None, capture_stderr=True):
+ def __init__(self, command, working_dir=None, capture_stderr=True, env=None):
"""Changes into a specified directory, if provided, and executes a command.
- Restores the old directory afterwards. Execution results are returned
- via the following attributes:
- terminated_by_sygnal True iff the child process has been terminated
- by a signal.
- signal Sygnal that terminated the child process.
- exited True iff the child process exited normally.
- exit_code The code with which the child proces exited.
- output Child process's stdout and stderr output
- combined in a string.
+
+ Restores the old directory afterwards.
Args:
command: The command to run, in the form of sys.argv.
working_dir: The directory to change into.
capture_stderr: Determines whether to capture stderr in the output member
or to discard it.
+ env: Dictionary with environment to pass to the subprocess.
+
+ Returns:
+ An object that represents outcome of the executed process. It has the
+ following attributes:
+ terminated_by_signal True iff the child process has been terminated
+ by a signal.
+ signal Sygnal that terminated the child process.
+ exited True iff the child process exited normally.
+ exit_code The code with which the child process exited.
+ output Child process's stdout and stderr output
+ combined in a string.
"""
# The subprocess module is the preferrable way of running programs
@@ -224,13 +233,30 @@ class Subprocess:
p = subprocess.Popen(command,
stdout=subprocess.PIPE, stderr=stderr,
- cwd=working_dir, universal_newlines=True)
+ cwd=working_dir, universal_newlines=True, env=env)
# communicate returns a tuple with the file obect for the child's
# output.
self.output = p.communicate()[0]
self._return_code = p.returncode
else:
old_dir = os.getcwd()
+
+ def _ReplaceEnvDict(dest, src):
+ # Changes made by os.environ.clear are not inheritable by child
+ # processes until Python 2.6. To produce inheritable changes we have
+ # to delete environment items with the del statement.
+ for key in dest:
+ del dest[key]
+ dest.update(src)
+
+ # When 'env' is not None, backup the environment variables and replace
+ # them with the passed 'env'. When 'env' is None, we simply use the
+ # current 'os.environ' for compatibility with the subprocess.Popen
+ # semantics used above.
+ if env is not None:
+ old_environ = os.environ.copy()
+ _ReplaceEnvDict(os.environ, env)
+
try:
if working_dir is not None:
os.chdir(working_dir)
@@ -243,6 +269,12 @@ class Subprocess:
ret_code = p.wait()
finally:
os.chdir(old_dir)
+
+ # Restore the old environment variables
+ # if they were replaced.
+ if env is not None:
+ _ReplaceEnvDict(os.environ, old_environ)
+
# Converts ret_code to match the semantics of
# subprocess.Popen.returncode.
if os.WIFSIGNALED(ret_code):
@@ -267,4 +299,11 @@ def Main():
# unittest.main(). Otherwise the latter will be confused by the
# --gtest_* flags.
_ParseAndStripGTestFlags(sys.argv)
+ # The tested binaries should not be writing XML output files unless the
+ # script explicitly instructs them to.
+ # TODO(vladl@google.com): Move this into Subprocess when we implement
+ # passing environment into it as a parameter.
+ if GTEST_OUTPUT_VAR_NAME in os.environ:
+ del os.environ[GTEST_OUTPUT_VAR_NAME]
+
_test_module.main()
diff --git a/gtest/test/gtest_unittest.cc b/gtest/test/gtest_unittest.cc
index 5c69b46..a14f065 100644
--- a/gtest/test/gtest_unittest.cc
+++ b/gtest/test/gtest_unittest.cc
@@ -33,6 +33,7 @@
// Google Test work.
#include <gtest/gtest.h>
+#include <vector>
// Verifies that the command line flag variables can be accessed
// in code once <gtest/gtest.h> has been #included.
@@ -70,21 +71,11 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
#include <stdlib.h>
#include <time.h>
-#if GTEST_HAS_PTHREAD
-#include <pthread.h>
-#endif // GTEST_HAS_PTHREAD
-
-#ifdef __BORLANDC__
#include <map>
-#endif
namespace testing {
namespace internal {
-bool ShouldUseColor(bool stdout_is_tty);
-const char* FormatTimeInMillisAsSeconds(TimeInMillis ms);
-bool ParseInt32Flag(const char* str, const char* flag, Int32* value);
-
// Provides access to otherwise private parts of the TestEventListeners class
// that are needed to test it.
class TestEventListenersAccessor {
@@ -148,15 +139,19 @@ using testing::TestPartResultArray;
using testing::TestProperty;
using testing::TestResult;
using testing::UnitTest;
+using testing::kMaxStackTraceDepth;
using testing::internal::AlwaysFalse;
using testing::internal::AlwaysTrue;
using testing::internal::AppendUserMessage;
using testing::internal::CodePointToUtf8;
+using testing::internal::CountIf;
using testing::internal::EqFailure;
using testing::internal::FloatingPoint;
using testing::internal::FormatTimeInMillisAsSeconds;
+using testing::internal::ForEach;
using testing::internal::GTestFlagSaver;
using testing::internal::GetCurrentOsStackTraceExceptTop;
+using testing::internal::GetElementOr;
using testing::internal::GetNextRandomSeed;
using testing::internal::GetRandomSeedFromFlag;
using testing::internal::GetTestTypeId;
@@ -168,26 +163,35 @@ using testing::internal::ParseInt32Flag;
using testing::internal::ShouldRunTestOnShard;
using testing::internal::ShouldShard;
using testing::internal::ShouldUseColor;
+using testing::internal::Shuffle;
+using testing::internal::ShuffleRange;
using testing::internal::StreamableToString;
using testing::internal::String;
using testing::internal::TestEventListenersAccessor;
using testing::internal::TestResultAccessor;
-using testing::internal::ThreadLocal;
using testing::internal::UInt32;
-using testing::internal::Vector;
using testing::internal::WideStringToUtf8;
using testing::internal::kMaxRandomSeed;
using testing::internal::kTestTypeIdInGoogleTest;
using testing::internal::scoped_ptr;
-class TestingVector : public Vector<int> {
+#if GTEST_HAS_STREAM_REDIRECTION_
+using testing::internal::CaptureStdout;
+using testing::internal::GetCapturedStdout;
+#endif // GTEST_HAS_STREAM_REDIRECTION_
+
+#if GTEST_IS_THREADSAFE
+using testing::internal::ThreadWithParam;
+#endif
+
+class TestingVector : public std::vector<int> {
};
::std::ostream& operator<<(::std::ostream& os,
const TestingVector& vector) {
os << "{ ";
- for (int i = 0; i < vector.size(); i++) {
- os << vector.GetElement(i) << " ";
+ for (size_t i = 0; i < vector.size(); i++) {
+ os << vector[i] << " ";
}
os << "}";
return os;
@@ -266,27 +270,26 @@ TEST(GetTestTypeIdTest, ReturnsTheSameValueInsideOrOutsideOfGoogleTest) {
// Tests FormatTimeInMillisAsSeconds().
TEST(FormatTimeInMillisAsSecondsTest, FormatsZero) {
- EXPECT_STREQ("0", FormatTimeInMillisAsSeconds(0));
+ EXPECT_EQ("0", FormatTimeInMillisAsSeconds(0));
}
TEST(FormatTimeInMillisAsSecondsTest, FormatsPositiveNumber) {
- EXPECT_STREQ("0.003", FormatTimeInMillisAsSeconds(3));
- EXPECT_STREQ("0.01", FormatTimeInMillisAsSeconds(10));
- EXPECT_STREQ("0.2", FormatTimeInMillisAsSeconds(200));
- EXPECT_STREQ("1.2", FormatTimeInMillisAsSeconds(1200));
- EXPECT_STREQ("3", FormatTimeInMillisAsSeconds(3000));
+ EXPECT_EQ("0.003", FormatTimeInMillisAsSeconds(3));
+ EXPECT_EQ("0.01", FormatTimeInMillisAsSeconds(10));
+ EXPECT_EQ("0.2", FormatTimeInMillisAsSeconds(200));
+ EXPECT_EQ("1.2", FormatTimeInMillisAsSeconds(1200));
+ EXPECT_EQ("3", FormatTimeInMillisAsSeconds(3000));
}
TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) {
- EXPECT_STREQ("-0.003", FormatTimeInMillisAsSeconds(-3));
- EXPECT_STREQ("-0.01", FormatTimeInMillisAsSeconds(-10));
- EXPECT_STREQ("-0.2", FormatTimeInMillisAsSeconds(-200));
- EXPECT_STREQ("-1.2", FormatTimeInMillisAsSeconds(-1200));
- EXPECT_STREQ("-3", FormatTimeInMillisAsSeconds(-3000));
+ EXPECT_EQ("-0.003", FormatTimeInMillisAsSeconds(-3));
+ EXPECT_EQ("-0.01", FormatTimeInMillisAsSeconds(-10));
+ EXPECT_EQ("-0.2", FormatTimeInMillisAsSeconds(-200));
+ EXPECT_EQ("-1.2", FormatTimeInMillisAsSeconds(-1200));
+ EXPECT_EQ("-3", FormatTimeInMillisAsSeconds(-3000));
}
-#if !GTEST_OS_SYMBIAN
-// NULL testing does not work with Symbian compilers.
+#if GTEST_CAN_COMPARE_NULL
#ifdef __BORLANDC__
// Silences warnings: "Condition is always true", "Unreachable code"
@@ -320,11 +323,11 @@ TEST(NullLiteralTest, IsFalseForNonNullLiterals) {
}
#ifdef __BORLANDC__
-// Restores warnings after previous "#pragma option push" supressed them
+// Restores warnings after previous "#pragma option push" suppressed them.
#pragma option pop
#endif
-#endif // !GTEST_OS_SYMBIAN
+#endif // GTEST_CAN_COMPARE_NULL
//
// Tests CodePointToUtf8().
@@ -547,339 +550,80 @@ TEST(RandomTest, RepeatsWhenReseeded) {
}
}
-// Tests the Vector class template.
-
-// Tests Vector::Clear().
-TEST(VectorTest, Clear) {
- Vector<int> a;
- a.PushBack(1);
- a.Clear();
- EXPECT_EQ(0, a.size());
+// Tests STL container utilities.
- a.PushBack(2);
- a.PushBack(3);
- a.Clear();
- EXPECT_EQ(0, a.size());
-}
-
-// Tests Vector::PushBack().
-TEST(VectorTest, PushBack) {
- Vector<char> a;
- a.PushBack('a');
- ASSERT_EQ(1, a.size());
- EXPECT_EQ('a', a.GetElement(0));
-
- a.PushBack('b');
- ASSERT_EQ(2, a.size());
- EXPECT_EQ('a', a.GetElement(0));
- EXPECT_EQ('b', a.GetElement(1));
-}
-
-// Tests Vector::PushFront().
-TEST(VectorTest, PushFront) {
- Vector<int> a;
- ASSERT_EQ(0, a.size());
-
- // Calls PushFront() on an empty Vector.
- a.PushFront(1);
- ASSERT_EQ(1, a.size());
- EXPECT_EQ(1, a.GetElement(0));
-
- // Calls PushFront() on a singleton Vector.
- a.PushFront(2);
- ASSERT_EQ(2, a.size());
- EXPECT_EQ(2, a.GetElement(0));
- EXPECT_EQ(1, a.GetElement(1));
-
- // Calls PushFront() on a Vector with more than one elements.
- a.PushFront(3);
- ASSERT_EQ(3, a.size());
- EXPECT_EQ(3, a.GetElement(0));
- EXPECT_EQ(2, a.GetElement(1));
- EXPECT_EQ(1, a.GetElement(2));
-}
-
-// Tests Vector::PopFront().
-TEST(VectorTest, PopFront) {
- Vector<int> a;
-
- // Popping on an empty Vector should fail.
- EXPECT_FALSE(a.PopFront(NULL));
-
- // Popping again on an empty Vector should fail, and the result element
- // shouldn't be overwritten.
- int element = 1;
- EXPECT_FALSE(a.PopFront(&element));
- EXPECT_EQ(1, element);
-
- a.PushFront(2);
- a.PushFront(3);
-
- // PopFront() should pop the element in the front of the Vector.
- EXPECT_TRUE(a.PopFront(&element));
- EXPECT_EQ(3, element);
-
- // After popping the last element, the Vector should be empty.
- EXPECT_TRUE(a.PopFront(NULL));
- EXPECT_EQ(0, a.size());
-}
-
-// Tests inserting at the beginning using Vector::Insert().
-TEST(VectorTest, InsertAtBeginning) {
- Vector<int> a;
- ASSERT_EQ(0, a.size());
-
- // Inserts into an empty Vector.
- a.Insert(1, 0);
- ASSERT_EQ(1, a.size());
- EXPECT_EQ(1, a.GetElement(0));
-
- // Inserts at the beginning of a singleton Vector.
- a.Insert(2, 0);
- ASSERT_EQ(2, a.size());
- EXPECT_EQ(2, a.GetElement(0));
- EXPECT_EQ(1, a.GetElement(1));
-
- // Inserts at the beginning of a Vector with more than one elements.
- a.Insert(3, 0);
- ASSERT_EQ(3, a.size());
- EXPECT_EQ(3, a.GetElement(0));
- EXPECT_EQ(2, a.GetElement(1));
- EXPECT_EQ(1, a.GetElement(2));
-}
-
-// Tests inserting at a location other than the beginning using
-// Vector::Insert().
-TEST(VectorTest, InsertNotAtBeginning) {
- // Prepares a singleton Vector.
- Vector<int> a;
- a.PushBack(1);
-
- // Inserts at the end of a singleton Vector.
- a.Insert(2, a.size());
- ASSERT_EQ(2, a.size());
- EXPECT_EQ(1, a.GetElement(0));
- EXPECT_EQ(2, a.GetElement(1));
-
- // Inserts at the end of a Vector with more than one elements.
- a.Insert(3, a.size());
- ASSERT_EQ(3, a.size());
- EXPECT_EQ(1, a.GetElement(0));
- EXPECT_EQ(2, a.GetElement(1));
- EXPECT_EQ(3, a.GetElement(2));
-
- // Inserts in the middle of a Vector.
- a.Insert(4, 1);
- ASSERT_EQ(4, a.size());
- EXPECT_EQ(1, a.GetElement(0));
- EXPECT_EQ(4, a.GetElement(1));
- EXPECT_EQ(2, a.GetElement(2));
- EXPECT_EQ(3, a.GetElement(3));
-}
-
-// Tests Vector::GetElementOr().
-TEST(VectorTest, GetElementOr) {
- Vector<char> a;
- EXPECT_EQ('x', a.GetElementOr(0, 'x'));
-
- a.PushBack('a');
- a.PushBack('b');
- EXPECT_EQ('a', a.GetElementOr(0, 'x'));
- EXPECT_EQ('b', a.GetElementOr(1, 'x'));
- EXPECT_EQ('x', a.GetElementOr(-2, 'x'));
- EXPECT_EQ('x', a.GetElementOr(2, 'x'));
-}
-
-TEST(VectorTest, Swap) {
- Vector<int> a;
- a.PushBack(0);
- a.PushBack(1);
- a.PushBack(2);
-
- // Swaps an element with itself.
- a.Swap(0, 0);
- ASSERT_EQ(0, a.GetElement(0));
- ASSERT_EQ(1, a.GetElement(1));
- ASSERT_EQ(2, a.GetElement(2));
-
- // Swaps two different elements where the indices go up.
- a.Swap(0, 1);
- ASSERT_EQ(1, a.GetElement(0));
- ASSERT_EQ(0, a.GetElement(1));
- ASSERT_EQ(2, a.GetElement(2));
-
- // Swaps two different elements where the indices go down.
- a.Swap(2, 0);
- ASSERT_EQ(2, a.GetElement(0));
- ASSERT_EQ(0, a.GetElement(1));
- ASSERT_EQ(1, a.GetElement(2));
-}
-
-TEST(VectorTest, Clone) {
- // Clones an empty Vector.
- Vector<int> a;
- scoped_ptr<Vector<int> > empty(a.Clone());
- EXPECT_EQ(0, empty->size());
-
- // Clones a singleton.
- a.PushBack(42);
- scoped_ptr<Vector<int> > singleton(a.Clone());
- ASSERT_EQ(1, singleton->size());
- EXPECT_EQ(42, singleton->GetElement(0));
-
- // Clones a Vector with more elements.
- a.PushBack(43);
- a.PushBack(44);
- scoped_ptr<Vector<int> > big(a.Clone());
- ASSERT_EQ(3, big->size());
- EXPECT_EQ(42, big->GetElement(0));
- EXPECT_EQ(43, big->GetElement(1));
- EXPECT_EQ(44, big->GetElement(2));
-}
-
-// Tests Vector::Erase().
-TEST(VectorDeathTest, Erase) {
- Vector<int> a;
-
- // Tests erasing from an empty vector.
- EXPECT_DEATH_IF_SUPPORTED(
- a.Erase(0),
- "Invalid Vector index 0: must be in range \\[0, -1\\]\\.");
+// Tests CountIf().
- // Tests erasing from a singleton vector.
- a.PushBack(0);
+static bool IsPositive(int n) { return n > 0; }
- a.Erase(0);
- EXPECT_EQ(0, a.size());
+TEST(ContainerUtilityTest, CountIf) {
+ std::vector<int> v;
+ EXPECT_EQ(0, CountIf(v, IsPositive)); // Works for an empty container.
- // Tests Erase parameters beyond the bounds of the vector.
- Vector<int> a1;
- a1.PushBack(0);
- a1.PushBack(1);
- a1.PushBack(2);
+ v.push_back(-1);
+ v.push_back(0);
+ EXPECT_EQ(0, CountIf(v, IsPositive)); // Works when no value satisfies.
- EXPECT_DEATH_IF_SUPPORTED(
- a1.Erase(3),
- "Invalid Vector index 3: must be in range \\[0, 2\\]\\.");
- EXPECT_DEATH_IF_SUPPORTED(
- a1.Erase(-1),
- "Invalid Vector index -1: must be in range \\[0, 2\\]\\.");
-
- // Tests erasing at the end of the vector.
- Vector<int> a2;
- a2.PushBack(0);
- a2.PushBack(1);
- a2.PushBack(2);
-
- a2.Erase(2);
- ASSERT_EQ(2, a2.size());
- EXPECT_EQ(0, a2.GetElement(0));
- EXPECT_EQ(1, a2.GetElement(1));
-
- // Tests erasing in the middle of the vector.
- Vector<int> a3;
- a3.PushBack(0);
- a3.PushBack(1);
- a3.PushBack(2);
-
- a3.Erase(1);
- ASSERT_EQ(2, a3.size());
- EXPECT_EQ(0, a3.GetElement(0));
- EXPECT_EQ(2, a3.GetElement(1));
-
- // Tests erasing at the beginning of the vector.
- Vector<int> a4;
- a4.PushBack(0);
- a4.PushBack(1);
- a4.PushBack(2);
-
- a4.Erase(0);
- ASSERT_EQ(2, a4.size());
- EXPECT_EQ(1, a4.GetElement(0));
- EXPECT_EQ(2, a4.GetElement(1));
-}
-
-// Tests the GetElement accessor.
-TEST(VectorDeathTest, GetElement) {
- Vector<int> a;
- a.PushBack(0);
- a.PushBack(1);
- a.PushBack(2);
- const Vector<int>& b = a;
-
- EXPECT_EQ(0, b.GetElement(0));
- EXPECT_EQ(1, b.GetElement(1));
- EXPECT_EQ(2, b.GetElement(2));
- EXPECT_DEATH_IF_SUPPORTED(
- b.GetElement(3),
- "Invalid Vector index 3: must be in range \\[0, 2\\]\\.");
- EXPECT_DEATH_IF_SUPPORTED(
- b.GetElement(-1),
- "Invalid Vector index -1: must be in range \\[0, 2\\]\\.");
+ v.push_back(2);
+ v.push_back(-10);
+ v.push_back(10);
+ EXPECT_EQ(2, CountIf(v, IsPositive));
}
-// Tests the GetMutableElement accessor.
-TEST(VectorDeathTest, GetMutableElement) {
- Vector<int> a;
- a.PushBack(0);
- a.PushBack(1);
- a.PushBack(2);
+// Tests ForEach().
- EXPECT_EQ(0, a.GetMutableElement(0));
- EXPECT_EQ(1, a.GetMutableElement(1));
- EXPECT_EQ(2, a.GetMutableElement(2));
+static int g_sum = 0;
+static void Accumulate(int n) { g_sum += n; }
- a.GetMutableElement(0) = 42;
- EXPECT_EQ(42, a.GetMutableElement(0));
- EXPECT_EQ(1, a.GetMutableElement(1));
- EXPECT_EQ(2, a.GetMutableElement(2));
+TEST(ContainerUtilityTest, ForEach) {
+ std::vector<int> v;
+ g_sum = 0;
+ ForEach(v, Accumulate);
+ EXPECT_EQ(0, g_sum); // Works for an empty container;
- EXPECT_DEATH_IF_SUPPORTED(
- a.GetMutableElement(3),
- "Invalid Vector index 3: must be in range \\[0, 2\\]\\.");
- EXPECT_DEATH_IF_SUPPORTED(
- a.GetMutableElement(-1),
- "Invalid Vector index -1: must be in range \\[0, 2\\]\\.");
+ g_sum = 0;
+ v.push_back(1);
+ ForEach(v, Accumulate);
+ EXPECT_EQ(1, g_sum); // Works for a container with one element.
+
+ g_sum = 0;
+ v.push_back(20);
+ v.push_back(300);
+ ForEach(v, Accumulate);
+ EXPECT_EQ(321, g_sum);
}
-TEST(VectorDeathTest, Swap) {
- Vector<int> a;
- a.PushBack(0);
- a.PushBack(1);
- a.PushBack(2);
+// Tests GetElementOr().
+TEST(ContainerUtilityTest, GetElementOr) {
+ std::vector<char> a;
+ EXPECT_EQ('x', GetElementOr(a, 0, 'x'));
- EXPECT_DEATH_IF_SUPPORTED(
- a.Swap(-1, 1),
- "Invalid first swap element -1: must be in range \\[0, 2\\]");
- EXPECT_DEATH_IF_SUPPORTED(
- a.Swap(3, 1),
- "Invalid first swap element 3: must be in range \\[0, 2\\]");
- EXPECT_DEATH_IF_SUPPORTED(
- a.Swap(1, -1),
- "Invalid second swap element -1: must be in range \\[0, 2\\]");
- EXPECT_DEATH_IF_SUPPORTED(
- a.Swap(1, 3),
- "Invalid second swap element 3: must be in range \\[0, 2\\]");
+ a.push_back('a');
+ a.push_back('b');
+ EXPECT_EQ('a', GetElementOr(a, 0, 'x'));
+ EXPECT_EQ('b', GetElementOr(a, 1, 'x'));
+ EXPECT_EQ('x', GetElementOr(a, -2, 'x'));
+ EXPECT_EQ('x', GetElementOr(a, 2, 'x'));
}
-TEST(VectorDeathTest, ShuffleRange) {
- Vector<int> a;
- a.PushBack(0);
- a.PushBack(1);
- a.PushBack(2);
+TEST(ContainerUtilityDeathTest, ShuffleRange) {
+ std::vector<int> a;
+ a.push_back(0);
+ a.push_back(1);
+ a.push_back(2);
testing::internal::Random random(1);
EXPECT_DEATH_IF_SUPPORTED(
- a.ShuffleRange(&random, -1, 1),
+ ShuffleRange(&random, -1, 1, &a),
"Invalid shuffle range start -1: must be in range \\[0, 3\\]");
EXPECT_DEATH_IF_SUPPORTED(
- a.ShuffleRange(&random, 4, 4),
+ ShuffleRange(&random, 4, 4, &a),
"Invalid shuffle range start 4: must be in range \\[0, 3\\]");
EXPECT_DEATH_IF_SUPPORTED(
- a.ShuffleRange(&random, 3, 2),
+ ShuffleRange(&random, 3, 2, &a),
"Invalid shuffle range finish 2: must be in range \\[3, 3\\]");
EXPECT_DEATH_IF_SUPPORTED(
- a.ShuffleRange(&random, 3, 4),
+ ShuffleRange(&random, 3, 4, &a),
"Invalid shuffle range finish 4: must be in range \\[3, 3\\]");
}
@@ -889,18 +633,18 @@ class VectorShuffleTest : public Test {
VectorShuffleTest() : random_(1) {
for (int i = 0; i < kVectorSize; i++) {
- vector_.PushBack(i);
+ vector_.push_back(i);
}
}
static bool VectorIsCorrupt(const TestingVector& vector) {
- if (kVectorSize != vector.size()) {
+ if (kVectorSize != static_cast<int>(vector.size())) {
return true;
}
bool found_in_vector[kVectorSize] = { false };
- for (int i = 0; i < vector.size(); i++) {
- const int e = vector.GetElement(i);
+ for (size_t i = 0; i < vector.size(); i++) {
+ const int e = vector[i];
if (e < 0 || e >= kVectorSize || found_in_vector[e]) {
return true;
}
@@ -918,7 +662,7 @@ class VectorShuffleTest : public Test {
static bool RangeIsShuffled(const TestingVector& vector, int begin, int end) {
for (int i = begin; i < end; i++) {
- if (i != vector.GetElement(i)) {
+ if (i != vector[i]) {
return true;
}
}
@@ -931,7 +675,7 @@ class VectorShuffleTest : public Test {
}
static bool VectorIsShuffled(const TestingVector& vector) {
- return RangeIsShuffled(vector, 0, vector.size());
+ return RangeIsShuffled(vector, 0, static_cast<int>(vector.size()));
}
static bool VectorIsUnshuffled(const TestingVector& vector) {
@@ -946,39 +690,39 @@ const int VectorShuffleTest::kVectorSize;
TEST_F(VectorShuffleTest, HandlesEmptyRange) {
// Tests an empty range at the beginning...
- vector_.ShuffleRange(&random_, 0, 0);
+ ShuffleRange(&random_, 0, 0, &vector_);
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
ASSERT_PRED1(VectorIsUnshuffled, vector_);
// ...in the middle...
- vector_.ShuffleRange(&random_, kVectorSize/2, kVectorSize/2);
+ ShuffleRange(&random_, kVectorSize/2, kVectorSize/2, &vector_);
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
ASSERT_PRED1(VectorIsUnshuffled, vector_);
// ...at the end...
- vector_.ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1);
+ ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1, &vector_);
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
ASSERT_PRED1(VectorIsUnshuffled, vector_);
// ...and past the end.
- vector_.ShuffleRange(&random_, kVectorSize, kVectorSize);
+ ShuffleRange(&random_, kVectorSize, kVectorSize, &vector_);
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
ASSERT_PRED1(VectorIsUnshuffled, vector_);
}
TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) {
// Tests a size one range at the beginning...
- vector_.ShuffleRange(&random_, 0, 1);
+ ShuffleRange(&random_, 0, 1, &vector_);
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
ASSERT_PRED1(VectorIsUnshuffled, vector_);
// ...in the middle...
- vector_.ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1);
+ ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1, &vector_);
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
ASSERT_PRED1(VectorIsUnshuffled, vector_);
// ...and at the end.
- vector_.ShuffleRange(&random_, kVectorSize - 1, kVectorSize);
+ ShuffleRange(&random_, kVectorSize - 1, kVectorSize, &vector_);
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
ASSERT_PRED1(VectorIsUnshuffled, vector_);
}
@@ -987,20 +731,20 @@ TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) {
// we can guarantee that the following "random" tests will succeed.
TEST_F(VectorShuffleTest, ShufflesEntireVector) {
- vector_.Shuffle(&random_);
+ Shuffle(&random_, &vector_);
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
EXPECT_FALSE(VectorIsUnshuffled(vector_)) << vector_;
// Tests the first and last elements in particular to ensure that
// there are no off-by-one problems in our shuffle algorithm.
- EXPECT_NE(0, vector_.GetElement(0));
- EXPECT_NE(kVectorSize - 1, vector_.GetElement(kVectorSize - 1));
+ EXPECT_NE(0, vector_[0]);
+ EXPECT_NE(kVectorSize - 1, vector_[kVectorSize - 1]);
}
TEST_F(VectorShuffleTest, ShufflesStartOfVector) {
const int kRangeSize = kVectorSize/2;
- vector_.ShuffleRange(&random_, 0, kRangeSize);
+ ShuffleRange(&random_, 0, kRangeSize, &vector_);
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
EXPECT_PRED3(RangeIsShuffled, vector_, 0, kRangeSize);
@@ -1009,7 +753,7 @@ TEST_F(VectorShuffleTest, ShufflesStartOfVector) {
TEST_F(VectorShuffleTest, ShufflesEndOfVector) {
const int kRangeSize = kVectorSize / 2;
- vector_.ShuffleRange(&random_, kRangeSize, kVectorSize);
+ ShuffleRange(&random_, kRangeSize, kVectorSize, &vector_);
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize);
@@ -1018,7 +762,7 @@ TEST_F(VectorShuffleTest, ShufflesEndOfVector) {
TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) {
int kRangeSize = kVectorSize/3;
- vector_.ShuffleRange(&random_, kRangeSize, 2*kRangeSize);
+ ShuffleRange(&random_, kRangeSize, 2*kRangeSize, &vector_);
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize);
@@ -1029,20 +773,19 @@ TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) {
TEST_F(VectorShuffleTest, ShufflesRepeatably) {
TestingVector vector2;
for (int i = 0; i < kVectorSize; i++) {
- vector2.PushBack(i);
+ vector2.push_back(i);
}
random_.Reseed(1234);
- vector_.Shuffle(&random_);
+ Shuffle(&random_, &vector_);
random_.Reseed(1234);
- vector2.Shuffle(&random_);
+ Shuffle(&random_, &vector2);
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
ASSERT_PRED1(VectorIsNotCorrupt, vector2);
for (int i = 0; i < kVectorSize; i++) {
- EXPECT_EQ(vector_.GetElement(i), vector2.GetElement(i))
- << " where i is " << i;
+ EXPECT_EQ(vector_[i], vector2[i]) << " where i is " << i;
}
}
@@ -1107,8 +850,6 @@ TEST(StringTest, Constructors) {
EXPECT_EQ('c', s7.c_str()[3]);
}
-#if GTEST_HAS_STD_STRING
-
TEST(StringTest, ConvertsFromStdString) {
// An empty std::string.
const std::string src1("");
@@ -1148,8 +889,6 @@ TEST(StringTest, ConvertsToStdString) {
EXPECT_EQ(std::string("x\0y", 3), dest3);
}
-#endif // GTEST_HAS_STD_STRING
-
#if GTEST_HAS_GLOBAL_STRING
TEST(StringTest, ConvertsFromGlobalString) {
@@ -1383,12 +1122,16 @@ TEST(StringTest, CanBeAssignedSelf) {
EXPECT_STREQ("hello", dest.c_str());
}
+// Sun Studio < 12 incorrectly rejects this code due to an overloading
+// ambiguity.
+#if !(defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
// Tests streaming a String.
TEST(StringTest, Streams) {
EXPECT_EQ(StreamableToString(String()), "(null)");
EXPECT_EQ(StreamableToString(String("")), "");
EXPECT_EQ(StreamableToString(String("a\0b", 3)), "a\\0b");
}
+#endif
// Tests that String::Format() works.
TEST(StringTest, FormatWorks) {
@@ -1532,25 +1275,14 @@ TEST_F(ScopedFakeTestPartResultReporterTest, DeprecatedConstructor) {
EXPECT_EQ(1, results.size());
}
-#if GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD
+#if GTEST_IS_THREADSAFE
class ScopedFakeTestPartResultReporterWithThreadsTest
: public ScopedFakeTestPartResultReporterTest {
protected:
static void AddFailureInOtherThread(FailureMode failure) {
- pthread_t tid;
- pthread_create(&tid,
- NULL,
- ScopedFakeTestPartResultReporterWithThreadsTest::
- FailureThread,
- &failure);
- pthread_join(tid, NULL);
- }
- private:
- static void* FailureThread(void* attr) {
- FailureMode* failure = static_cast<FailureMode*>(attr);
- AddFailure(*failure);
- return NULL;
+ ThreadWithParam<FailureMode> thread(&AddFailure, failure, NULL);
+ thread.Join();
}
};
@@ -1573,7 +1305,7 @@ TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest,
EXPECT_TRUE(results.GetTestPartResult(3).fatally_failed());
}
-#endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD
+#endif // GTEST_IS_THREADSAFE
// Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. Makes sure that they
// work even if the failure is generated in a called function rather than
@@ -1621,7 +1353,7 @@ void DoesNotAbortHelper(bool* aborted) {
}
#ifdef __BORLANDC__
-// Restores warnings after previous "#pragma option push" supressed them
+// Restores warnings after previous "#pragma option push" suppressed them.
#pragma option pop
#endif
@@ -1639,7 +1371,7 @@ static int global_var = 0;
#define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++
TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) {
-#ifndef __BORLANDC__
+#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600
// ICE's in C++Builder 2007.
EXPECT_FATAL_FAILURE({
GTEST_USE_UNPROTECTED_COMMA_;
@@ -1684,7 +1416,7 @@ TEST_F(ExpectNonfatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) {
}, "");
}
-#if GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD
+#if GTEST_IS_THREADSAFE
typedef ScopedFakeTestPartResultReporterWithThreadsTest
ExpectFailureWithThreadsTest;
@@ -1699,7 +1431,7 @@ TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailureOnAllThreads) {
AddFailureInOtherThread(NONFATAL_FAILURE), "Expected non-fatal failure.");
}
-#endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD
+#endif // GTEST_IS_THREADSAFE
// Tests the TestProperty class.
@@ -1717,61 +1449,12 @@ TEST(TestPropertyTest, SetValue) {
EXPECT_STREQ("value_2", property.value());
}
-// Tests the TestPartResult class.
-
-TEST(TestPartResultTest, ConstructorWorks) {
- Message message;
- message << "something is terribly wrong";
- message << static_cast<const char*>(testing::internal::kStackTraceMarker);
- message << "some unimportant stack trace";
-
- const TestPartResult result(TestPartResult::kNonFatalFailure,
- "some_file.cc",
- 42,
- message.GetString().c_str());
-
- EXPECT_EQ(TestPartResult::kNonFatalFailure, result.type());
- EXPECT_STREQ("some_file.cc", result.file_name());
- EXPECT_EQ(42, result.line_number());
- EXPECT_STREQ(message.GetString().c_str(), result.message());
- EXPECT_STREQ("something is terribly wrong", result.summary());
-}
-
-TEST(TestPartResultTest, ResultAccessorsWork) {
- const TestPartResult success(TestPartResult::kSuccess,
- "file.cc",
- 42,
- "message");
- EXPECT_TRUE(success.passed());
- EXPECT_FALSE(success.failed());
- EXPECT_FALSE(success.nonfatally_failed());
- EXPECT_FALSE(success.fatally_failed());
-
- const TestPartResult nonfatal_failure(TestPartResult::kNonFatalFailure,
- "file.cc",
- 42,
- "message");
- EXPECT_FALSE(nonfatal_failure.passed());
- EXPECT_TRUE(nonfatal_failure.failed());
- EXPECT_TRUE(nonfatal_failure.nonfatally_failed());
- EXPECT_FALSE(nonfatal_failure.fatally_failed());
-
- const TestPartResult fatal_failure(TestPartResult::kFatalFailure,
- "file.cc",
- 42,
- "message");
- EXPECT_FALSE(fatal_failure.passed());
- EXPECT_TRUE(fatal_failure.failed());
- EXPECT_FALSE(fatal_failure.nonfatally_failed());
- EXPECT_TRUE(fatal_failure.fatally_failed());
-}
-
// Tests the TestResult class
// The test fixture for testing TestResult.
class TestResultTest : public Test {
protected:
- typedef Vector<TestPartResult> TPRVector;
+ typedef std::vector<TestPartResult> TPRVector;
// We make use of 2 TestPartResult objects,
TestPartResult * pr1, * pr2;
@@ -1798,23 +1481,23 @@ class TestResultTest : public Test {
r2 = new TestResult();
// In order to test TestResult, we need to modify its internal
- // state, in particular the TestPartResult Vector it holds.
- // test_part_results() returns a const reference to this Vector.
+ // state, in particular the TestPartResult vector it holds.
+ // test_part_results() returns a const reference to this vector.
// We cast it to a non-const object s.t. it can be modified (yes,
// this is a hack).
- TPRVector* results1 = const_cast<Vector<TestPartResult> *>(
+ TPRVector* results1 = const_cast<TPRVector*>(
&TestResultAccessor::test_part_results(*r1));
- TPRVector* results2 = const_cast<Vector<TestPartResult> *>(
+ TPRVector* results2 = const_cast<TPRVector*>(
&TestResultAccessor::test_part_results(*r2));
// r0 is an empty TestResult.
// r1 contains a single SUCCESS TestPartResult.
- results1->PushBack(*pr1);
+ results1->push_back(*pr1);
// r2 contains a SUCCESS, and a FAILURE.
- results2->PushBack(*pr1);
- results2->PushBack(*pr2);
+ results2->push_back(*pr1);
+ results2->push_back(*pr2);
}
virtual void TearDown() {
@@ -1869,12 +1552,8 @@ typedef TestResultTest TestResultDeathTest;
TEST_F(TestResultDeathTest, GetTestPartResult) {
CompareTestPartResult(*pr1, r2->GetTestPartResult(0));
CompareTestPartResult(*pr2, r2->GetTestPartResult(1));
- EXPECT_DEATH_IF_SUPPORTED(
- r2->GetTestPartResult(2),
- "Invalid Vector index 2: must be in range \\[0, 1\\]\\.");
- EXPECT_DEATH_IF_SUPPORTED(
- r2->GetTestPartResult(-1),
- "Invalid Vector index -1: must be in range \\[0, 1\\]\\.");
+ EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(2), "");
+ EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(-1), "");
}
// Tests TestResult has no properties when none are added.
@@ -1956,12 +1635,8 @@ TEST(TestResultPropertyDeathTest, GetTestProperty) {
EXPECT_STREQ("key_3", fetched_property_3.key());
EXPECT_STREQ("3", fetched_property_3.value());
- EXPECT_DEATH_IF_SUPPORTED(
- test_result.GetTestProperty(3),
- "Invalid Vector index 3: must be in range \\[0, 2\\]\\.");
- EXPECT_DEATH_IF_SUPPORTED(
- test_result.GetTestProperty(-1),
- "Invalid Vector index -1: must be in range \\[0, 2\\]\\.");
+ EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(3), "");
+ EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(-1), "");
}
// When a property using a reserved key is supplied to this function, it tests
@@ -2022,6 +1697,7 @@ class GTestFlagSaverTest : public Test {
GTEST_FLAG(random_seed) = 0;
GTEST_FLAG(repeat) = 1;
GTEST_FLAG(shuffle) = false;
+ GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth;
GTEST_FLAG(throw_on_failure) = false;
}
@@ -2047,6 +1723,7 @@ class GTestFlagSaverTest : public Test {
EXPECT_EQ(0, GTEST_FLAG(random_seed));
EXPECT_EQ(1, GTEST_FLAG(repeat));
EXPECT_FALSE(GTEST_FLAG(shuffle));
+ EXPECT_EQ(kMaxStackTraceDepth, GTEST_FLAG(stack_trace_depth));
EXPECT_FALSE(GTEST_FLAG(throw_on_failure));
GTEST_FLAG(also_run_disabled_tests) = true;
@@ -2061,6 +1738,7 @@ class GTestFlagSaverTest : public Test {
GTEST_FLAG(random_seed) = 1;
GTEST_FLAG(repeat) = 100;
GTEST_FLAG(shuffle) = true;
+ GTEST_FLAG(stack_trace_depth) = 1;
GTEST_FLAG(throw_on_failure) = true;
}
private:
@@ -2091,7 +1769,7 @@ static void SetEnv(const char* name, const char* value) {
#if GTEST_OS_WINDOWS_MOBILE
// Environment variables are not supported on Windows CE.
return;
-#elif defined(__BORLANDC__)
+#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
// C++Builder's putenv only stores a pointer to its parameter; we have to
// ensure that the string remains valid as long as it might be needed.
// We use an std::map to do so.
@@ -2104,7 +1782,11 @@ static void SetEnv(const char* name, const char* value) {
prev_env = added_env[name];
}
added_env[name] = new String((Message() << name << "=" << value).GetString());
- putenv(added_env[name]->c_str());
+
+ // The standard signature of putenv accepts a 'char*' argument. Other
+ // implementations, like C++Builder's, accept a 'const char*'.
+ // We cast away the 'const' since that would work for both variants.
+ putenv(const_cast<char*>(added_env[name]->c_str()));
delete prev_env;
#elif GTEST_OS_WINDOWS // If we are on Windows proper.
_putenv((Message() << name << "=" << value).GetString().c_str());
@@ -2418,6 +2100,25 @@ AssertionResult AssertIsEven(const char* expr, int n) {
return AssertionFailure(msg);
}
+// A predicate function that returns AssertionResult for use in
+// EXPECT/ASSERT_TRUE/FALSE.
+AssertionResult ResultIsEven(int n) {
+ if (IsEven(n))
+ return AssertionSuccess() << n << " is even";
+ else
+ return AssertionFailure() << n << " is odd";
+}
+
+// A predicate function that returns AssertionResult but gives no
+// explanation why it succeeds. Needed for testing that
+// EXPECT/ASSERT_FALSE handles such functions correctly.
+AssertionResult ResultIsEvenNoExplanation(int n) {
+ if (IsEven(n))
+ return AssertionSuccess();
+ else
+ return AssertionFailure() << n << " is odd";
+}
+
// A predicate-formatter functor that asserts the argument is an even
// number.
struct AssertIsEvenFunctor {
@@ -2615,10 +2316,6 @@ TEST(PredTest, SingleEvaluationOnFailure) {
// Some helper functions for testing using overloaded/template
// functions with ASSERT_PREDn and EXPECT_PREDn.
-bool IsPositive(int n) {
- return n > 0;
-}
-
bool IsPositive(double x) {
return x > 0;
}
@@ -2841,8 +2538,6 @@ TEST(IsSubstringTest, GeneratesCorrectMessageForCString) {
"needle", "haystack").failure_message());
}
-#if GTEST_HAS_STD_STRING
-
// Tests that IsSubstring returns the correct result when the input
// argument type is ::std::string.
TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) {
@@ -2850,8 +2545,6 @@ TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) {
EXPECT_FALSE(IsSubstring("", "", "hello", std::string("world")));
}
-#endif // GTEST_HAS_STD_STRING
-
#if GTEST_HAS_STD_WSTRING
// Tests that IsSubstring returns the correct result when the input
// argument type is ::std::wstring.
@@ -2902,8 +2595,6 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) {
L"needle", L"two needles").failure_message());
}
-#if GTEST_HAS_STD_STRING
-
// Tests that IsNotSubstring returns the correct result when the input
// argument type is ::std::string.
TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) {
@@ -2923,8 +2614,6 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) {
::std::string("needle"), "two needles").failure_message());
}
-#endif // GTEST_HAS_STD_STRING
-
#if GTEST_HAS_STD_WSTRING
// Tests that IsNotSubstring returns the correct result when the input
@@ -3043,7 +2732,10 @@ TEST_F(FloatTest, AlmostZeros) {
// In C++Builder, names within local classes (such as used by
// EXPECT_FATAL_FAILURE) cannot be resolved against static members of the
// scoping class. Use a static local alias as a workaround.
- static const FloatTest::TestValues& v(this->values_);
+ // We use the assignment syntax since some compilers, like Sun Studio,
+ // don't allow initializing references using construction syntax
+ // (parentheses).
+ static const FloatTest::TestValues& v = this->values_;
EXPECT_FLOAT_EQ(0.0, v.close_to_positive_zero);
EXPECT_FLOAT_EQ(-0.0, v.close_to_negative_zero);
@@ -3095,7 +2787,10 @@ TEST_F(FloatTest, NaN) {
// In C++Builder, names within local classes (such as used by
// EXPECT_FATAL_FAILURE) cannot be resolved against static members of the
// scoping class. Use a static local alias as a workaround.
- static const FloatTest::TestValues& v(this->values_);
+ // We use the assignment syntax since some compilers, like Sun Studio,
+ // don't allow initializing references using construction syntax
+ // (parentheses).
+ static const FloatTest::TestValues& v = this->values_;
EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan1),
"v.nan1");
@@ -3130,9 +2825,9 @@ TEST_F(FloatTest, Commutative) {
TEST_F(FloatTest, EXPECT_NEAR) {
EXPECT_NEAR(-1.0f, -1.1f, 0.2f);
EXPECT_NEAR(2.0f, 3.0f, 1.0f);
- EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f,1.2f, 0.1f), // NOLINT
- "The difference between 1.0f and 1.2f is 0.2, "
- "which exceeds 0.1f");
+ EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f,1.5f, 0.25f), // NOLINT
+ "The difference between 1.0f and 1.5f is 0.5, "
+ "which exceeds 0.25f");
// To work around a bug in gcc 2.95.0, there is intentionally no
// space after the first comma in the previous line.
}
@@ -3141,9 +2836,9 @@ TEST_F(FloatTest, EXPECT_NEAR) {
TEST_F(FloatTest, ASSERT_NEAR) {
ASSERT_NEAR(-1.0f, -1.1f, 0.2f);
ASSERT_NEAR(2.0f, 3.0f, 1.0f);
- EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0f,1.2f, 0.1f), // NOLINT
- "The difference between 1.0f and 1.2f is 0.2, "
- "which exceeds 0.1f");
+ EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0f,1.5f, 0.25f), // NOLINT
+ "The difference between 1.0f and 1.5f is 0.5, "
+ "which exceeds 0.25f");
// To work around a bug in gcc 2.95.0, there is intentionally no
// space after the first comma in the previous line.
}
@@ -3210,7 +2905,10 @@ TEST_F(DoubleTest, AlmostZeros) {
// In C++Builder, names within local classes (such as used by
// EXPECT_FATAL_FAILURE) cannot be resolved against static members of the
// scoping class. Use a static local alias as a workaround.
- static const DoubleTest::TestValues& v(this->values_);
+ // We use the assignment syntax since some compilers, like Sun Studio,
+ // don't allow initializing references using construction syntax
+ // (parentheses).
+ static const DoubleTest::TestValues& v = this->values_;
EXPECT_DOUBLE_EQ(0.0, v.close_to_positive_zero);
EXPECT_DOUBLE_EQ(-0.0, v.close_to_negative_zero);
@@ -3260,7 +2958,10 @@ TEST_F(DoubleTest, NaN) {
// In C++Builder, names within local classes (such as used by
// EXPECT_FATAL_FAILURE) cannot be resolved against static members of the
// scoping class. Use a static local alias as a workaround.
- static const DoubleTest::TestValues& v(this->values_);
+ // We use the assignment syntax since some compilers, like Sun Studio,
+ // don't allow initializing references using construction syntax
+ // (parentheses).
+ static const DoubleTest::TestValues& v = this->values_;
// Nokia's STLport crashes if we try to output infinity or NaN.
EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan1),
@@ -3296,9 +2997,9 @@ TEST_F(DoubleTest, Commutative) {
TEST_F(DoubleTest, EXPECT_NEAR) {
EXPECT_NEAR(-1.0, -1.1, 0.2);
EXPECT_NEAR(2.0, 3.0, 1.0);
- EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.2, 0.1), // NOLINT
- "The difference between 1.0 and 1.2 is 0.2, "
- "which exceeds 0.1");
+ EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.5, 0.25), // NOLINT
+ "The difference between 1.0 and 1.5 is 0.5, "
+ "which exceeds 0.25");
// To work around a bug in gcc 2.95.0, there is intentionally no
// space after the first comma in the previous statement.
}
@@ -3307,9 +3008,9 @@ TEST_F(DoubleTest, EXPECT_NEAR) {
TEST_F(DoubleTest, ASSERT_NEAR) {
ASSERT_NEAR(-1.0, -1.1, 0.2);
ASSERT_NEAR(2.0, 3.0, 1.0);
- EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.2, 0.1), // NOLINT
- "The difference between 1.0 and 1.2 is 0.2, "
- "which exceeds 0.1");
+ EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.5, 0.25), // NOLINT
+ "The difference between 1.0 and 1.5 is 0.5, "
+ "which exceeds 0.25");
// To work around a bug in gcc 2.95.0, there is intentionally no
// space after the first comma in the previous statement.
}
@@ -3786,6 +3487,23 @@ TEST(AssertionTest, ASSERT_TRUE) {
"2 < 1");
}
+// Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult.
+TEST(AssertionTest, AssertTrueWithAssertionResult) {
+ ASSERT_TRUE(ResultIsEven(2));
+#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600
+ // ICE's in C++Builder 2007.
+ EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)),
+ "Value of: ResultIsEven(3)\n"
+ " Actual: false (3 is odd)\n"
+ "Expected: true");
+#endif
+ ASSERT_TRUE(ResultIsEvenNoExplanation(2));
+ EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)),
+ "Value of: ResultIsEvenNoExplanation(3)\n"
+ " Actual: false (3 is odd)\n"
+ "Expected: true");
+}
+
// Tests ASSERT_FALSE.
TEST(AssertionTest, ASSERT_FALSE) {
ASSERT_FALSE(2 < 1); // NOLINT
@@ -3795,6 +3513,23 @@ TEST(AssertionTest, ASSERT_FALSE) {
"Expected: false");
}
+// Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult.
+TEST(AssertionTest, AssertFalseWithAssertionResult) {
+ ASSERT_FALSE(ResultIsEven(3));
+#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600
+ // ICE's in C++Builder 2007.
+ EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)),
+ "Value of: ResultIsEven(2)\n"
+ " Actual: true (2 is even)\n"
+ "Expected: false");
+#endif
+ ASSERT_FALSE(ResultIsEvenNoExplanation(3));
+ EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)),
+ "Value of: ResultIsEvenNoExplanation(2)\n"
+ " Actual: true\n"
+ "Expected: false");
+}
+
#ifdef __BORLANDC__
// Restores warnings after previous "#pragma option push" supressed them
#pragma option pop
@@ -3822,10 +3557,7 @@ TEST(AssertionTest, ASSERT_EQ) {
}
// Tests ASSERT_EQ(NULL, pointer).
-#if !GTEST_OS_SYMBIAN
-// The NULL-detection template magic fails to compile with
-// the Nokia compiler and crashes the ARM compiler, hence
-// not testing on Symbian.
+#if GTEST_CAN_COMPARE_NULL
TEST(AssertionTest, ASSERT_EQ_NULL) {
// A success.
const char* p = NULL;
@@ -3840,7 +3572,7 @@ TEST(AssertionTest, ASSERT_EQ_NULL) {
EXPECT_FATAL_FAILURE(ASSERT_EQ(NULL, &n),
"Value of: &n\n");
}
-#endif // !GTEST_OS_SYMBIAN
+#endif // GTEST_CAN_COMPARE_NULL
// Tests ASSERT_EQ(0, non_pointer). Since the literal 0 can be
// treated as a null pointer by the compiler, we need to make sure
@@ -3902,13 +3634,15 @@ void ThrowNothing() {}
// Tests ASSERT_THROW.
TEST(AssertionTest, ASSERT_THROW) {
ASSERT_THROW(ThrowAnInteger(), int);
-#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600 || defined(_DEBUG)
- // ICE's in C++Builder 2007 (Release build).
+
+#ifndef __BORLANDC__
+ // ICE's in C++Builder 2007 and 2009.
EXPECT_FATAL_FAILURE(
ASSERT_THROW(ThrowAnInteger(), bool),
"Expected: ThrowAnInteger() throws an exception of type bool.\n"
" Actual: it throws a different type.");
#endif
+
EXPECT_FATAL_FAILURE(
ASSERT_THROW(ThrowNothing(), bool),
"Expected: ThrowNothing() throws an exception of type bool.\n"
@@ -3955,7 +3689,7 @@ TEST(AssertionTest, NonFixtureSubroutine) {
// An uncopyable class.
class Uncopyable {
public:
- explicit Uncopyable(int value) : value_(value) {}
+ explicit Uncopyable(int a_value) : value_(a_value) {}
int value() const { return value_; }
bool operator==(const Uncopyable& rhs) const {
@@ -4017,7 +3751,8 @@ TEST(AssertionTest, ExpectWorksWithUncopyableObject) {
// The version of gcc used in XCode 2.2 has a bug and doesn't allow
// anonymous enums in assertions. Therefore the following test is not
// done on Mac.
-#if !GTEST_OS_MAC
+// Sun Studio also rejects this code.
+#if !GTEST_OS_MAC && !defined(__SUNPRO_CC)
// Tests using assertions with anonymous enums.
enum {
@@ -4062,7 +3797,7 @@ TEST(AssertionTest, AnonymousEnum) {
"Value of: CASE_B");
}
-#endif // !GTEST_OS_MAC
+#endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC)
#if GTEST_OS_WINDOWS
@@ -4336,6 +4071,20 @@ TEST(ExpectTest, EXPECT_TRUE) {
"2 > 3");
}
+// Tests EXPECT_TRUE(predicate) for predicates returning AssertionResult.
+TEST(ExpectTest, ExpectTrueWithAssertionResult) {
+ EXPECT_TRUE(ResultIsEven(2));
+ EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEven(3)),
+ "Value of: ResultIsEven(3)\n"
+ " Actual: false (3 is odd)\n"
+ "Expected: true");
+ EXPECT_TRUE(ResultIsEvenNoExplanation(2));
+ EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEvenNoExplanation(3)),
+ "Value of: ResultIsEvenNoExplanation(3)\n"
+ " Actual: false (3 is odd)\n"
+ "Expected: true");
+}
+
// Tests EXPECT_FALSE.
TEST(ExpectTest, EXPECT_FALSE) {
EXPECT_FALSE(2 < 1); // NOLINT
@@ -4347,6 +4096,20 @@ TEST(ExpectTest, EXPECT_FALSE) {
"2 < 3");
}
+// Tests EXPECT_FALSE(predicate) for predicates returning AssertionResult.
+TEST(ExpectTest, ExpectFalseWithAssertionResult) {
+ EXPECT_FALSE(ResultIsEven(3));
+ EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEven(2)),
+ "Value of: ResultIsEven(2)\n"
+ " Actual: true (2 is even)\n"
+ "Expected: false");
+ EXPECT_FALSE(ResultIsEvenNoExplanation(3));
+ EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEvenNoExplanation(2)),
+ "Value of: ResultIsEvenNoExplanation(2)\n"
+ " Actual: true\n"
+ "Expected: false");
+}
+
#ifdef __BORLANDC__
// Restores warnings after previous "#pragma option push" supressed them
#pragma option pop
@@ -4375,7 +4138,7 @@ TEST(ExpectTest, EXPECT_EQ_Double) {
"5.1");
}
-#if !GTEST_OS_SYMBIAN
+#if GTEST_CAN_COMPARE_NULL
// Tests EXPECT_EQ(NULL, pointer).
TEST(ExpectTest, EXPECT_EQ_NULL) {
// A success.
@@ -4391,7 +4154,7 @@ TEST(ExpectTest, EXPECT_EQ_NULL) {
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n),
"Value of: &n\n");
}
-#endif // !GTEST_OS_SYMBIAN
+#endif // GTEST_CAN_COMPARE_NULL
// Tests EXPECT_EQ(0, non_pointer). Since the literal 0 can be
// treated as a null pointer by the compiler, we need to make sure
@@ -4542,7 +4305,6 @@ TEST(StreamableToStringTest, NullCString) {
// Tests using streamable values as assertion messages.
-#if GTEST_HAS_STD_STRING
// Tests using std::string as an assertion message.
TEST(StreamableTest, string) {
static const std::string str(
@@ -4563,8 +4325,6 @@ TEST(StreamableTest, stringWithEmbeddedNUL) {
"Here's a NUL\\0 and some more string");
}
-#endif // GTEST_HAS_STD_STRING
-
// Tests that we can output a NUL char.
TEST(StreamableTest, NULChar) {
EXPECT_FATAL_FAILURE({ // NOLINT
@@ -4687,7 +4447,6 @@ TEST(EqAssertionTest, WideChar) {
"Value of: wchar");
}
-#if GTEST_HAS_STD_STRING
// Tests using ::std::string values in {EXPECT|ASSERT}_EQ.
TEST(EqAssertionTest, StdString) {
// Compares a const char* to an std::string that has identical
@@ -4718,8 +4477,6 @@ TEST(EqAssertionTest, StdString) {
" Actual: \"A \\0 in the middle\"");
}
-#endif // GTEST_HAS_STD_STRING
-
#if GTEST_HAS_STD_WSTRING
// Tests using ::std::wstring values in {EXPECT|ASSERT}_EQ.
@@ -4952,11 +4709,68 @@ TEST_F(TestLifeCycleTest, Test2) {
} // namespace
+// Tests that the copy constructor works when it is NOT optimized away by
+// the compiler.
+TEST(AssertionResultTest, CopyConstructorWorksWhenNotOptimied) {
+ // Checks that the copy constructor doesn't try to dereference NULL pointers
+ // in the source object.
+ AssertionResult r1 = AssertionSuccess();
+ AssertionResult r2 = r1;
+ // The following line is added to prevent the compiler from optimizing
+ // away the constructor call.
+ r1 << "abc";
+
+ AssertionResult r3 = r1;
+ EXPECT_EQ(static_cast<bool>(r3), static_cast<bool>(r1));
+ EXPECT_STREQ("abc", r1.message());
+}
+
+// Tests that AssertionSuccess and AssertionFailure construct
+// AssertionResult objects as expected.
+TEST(AssertionResultTest, ConstructionWorks) {
+ AssertionResult r1 = AssertionSuccess();
+ EXPECT_TRUE(r1);
+ EXPECT_STREQ("", r1.message());
+
+ AssertionResult r2 = AssertionSuccess() << "abc";
+ EXPECT_TRUE(r2);
+ EXPECT_STREQ("abc", r2.message());
+
+ AssertionResult r3 = AssertionFailure();
+ EXPECT_FALSE(r3);
+ EXPECT_STREQ("", r3.message());
+
+ AssertionResult r4 = AssertionFailure() << "def";
+ EXPECT_FALSE(r4);
+ EXPECT_STREQ("def", r4.message());
+
+ AssertionResult r5 = AssertionFailure(Message() << "ghi");
+ EXPECT_FALSE(r5);
+ EXPECT_STREQ("ghi", r5.message());
+}
+
+// Tests that the negation fips the predicate result but keeps the message.
+TEST(AssertionResultTest, NegationWorks) {
+ AssertionResult r1 = AssertionSuccess() << "abc";
+ EXPECT_FALSE(!r1);
+ EXPECT_STREQ("abc", (!r1).message());
+
+ AssertionResult r2 = AssertionFailure() << "def";
+ EXPECT_TRUE(!r2);
+ EXPECT_STREQ("def", (!r2).message());
+}
+
+TEST(AssertionResultTest, StreamingWorks) {
+ AssertionResult r = AssertionSuccess();
+ r << "abc" << 'd' << 0 << true;
+ EXPECT_STREQ("abcd0true", r.message());
+}
+
// Tests streaming a user type whose definition and operator << are
// both in the global namespace.
class Base {
public:
- explicit Base(int x) : x_(x) {}
+ explicit Base(int an_x) : x_(an_x) {}
int x() const { return x_; }
private:
int x_;
@@ -4983,7 +4797,7 @@ TEST(MessageTest, CanStreamUserTypeInGlobalNameSpace) {
namespace {
class MyTypeInUnnamedNameSpace : public Base {
public:
- explicit MyTypeInUnnamedNameSpace(int x): Base(x) {}
+ explicit MyTypeInUnnamedNameSpace(int an_x): Base(an_x) {}
};
std::ostream& operator<<(std::ostream& os,
const MyTypeInUnnamedNameSpace& val) {
@@ -5008,7 +4822,7 @@ TEST(MessageTest, CanStreamUserTypeInUnnamedNameSpace) {
namespace namespace1 {
class MyTypeInNameSpace1 : public Base {
public:
- explicit MyTypeInNameSpace1(int x): Base(x) {}
+ explicit MyTypeInNameSpace1(int an_x): Base(an_x) {}
};
std::ostream& operator<<(std::ostream& os,
const MyTypeInNameSpace1& val) {
@@ -5033,7 +4847,7 @@ TEST(MessageTest, CanStreamUserTypeInUserNameSpace) {
namespace namespace2 {
class MyTypeInNameSpace2 : public ::Base {
public:
- explicit MyTypeInNameSpace2(int x): Base(x) {}
+ explicit MyTypeInNameSpace2(int an_x): Base(an_x) {}
};
} // namespace namespace2
std::ostream& operator<<(std::ostream& os,
@@ -5215,6 +5029,7 @@ struct Flags {
random_seed(0),
repeat(1),
shuffle(false),
+ stack_trace_depth(kMaxStackTraceDepth),
throw_on_failure(false) {}
// Factory methods.
@@ -5307,6 +5122,14 @@ struct Flags {
return flags;
}
+ // Creates a Flags struct where the GTEST_FLAG(stack_trace_depth) flag has
+ // the given value.
+ static Flags StackTraceDepth(Int32 stack_trace_depth) {
+ Flags flags;
+ flags.stack_trace_depth = stack_trace_depth;
+ return flags;
+ }
+
// Creates a Flags struct where the gtest_throw_on_failure flag has
// the given value.
static Flags ThrowOnFailure(bool throw_on_failure) {
@@ -5327,6 +5150,7 @@ struct Flags {
Int32 random_seed;
Int32 repeat;
bool shuffle;
+ Int32 stack_trace_depth;
bool throw_on_failure;
};
@@ -5346,6 +5170,7 @@ class InitGoogleTestTest : public Test {
GTEST_FLAG(random_seed) = 0;
GTEST_FLAG(repeat) = 1;
GTEST_FLAG(shuffle) = false;
+ GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth;
GTEST_FLAG(throw_on_failure) = false;
}
@@ -5375,6 +5200,7 @@ class InitGoogleTestTest : public Test {
EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat));
EXPECT_EQ(expected.shuffle, GTEST_FLAG(shuffle));
EXPECT_EQ(expected.throw_on_failure, GTEST_FLAG(throw_on_failure));
+ EXPECT_EQ(expected.stack_trace_depth, GTEST_FLAG(stack_trace_depth));
}
// Parses a command line (specified by argc1 and argv1), then
@@ -5383,23 +5209,52 @@ class InitGoogleTestTest : public Test {
template <typename CharType>
static void TestParsingFlags(int argc1, const CharType** argv1,
int argc2, const CharType** argv2,
- const Flags& expected) {
+ const Flags& expected, bool should_print_help) {
+ const bool saved_help_flag = ::testing::internal::g_help_flag;
+ ::testing::internal::g_help_flag = false;
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+ CaptureStdout();
+#endif // GTEST_HAS_STREAM_REDIRECTION_
+
// Parses the command line.
internal::ParseGoogleTestFlagsOnly(&argc1, const_cast<CharType**>(argv1));
+#if GTEST_HAS_STREAM_REDIRECTION_
+ const String captured_stdout = GetCapturedStdout();
+#endif // GTEST_HAS_STREAM_REDIRECTION_
+
// Verifies the flag values.
CheckFlags(expected);
// Verifies that the recognized flags are removed from the command
// line.
AssertStringArrayEq(argc1 + 1, argv1, argc2 + 1, argv2);
+
+ // ParseGoogleTestFlagsOnly should neither set g_help_flag nor print the
+ // help message for the flags it recognizes.
+ EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag);
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+ const char* const expected_help_fragment =
+ "This program contains tests written using";
+ if (should_print_help) {
+ EXPECT_PRED_FORMAT2(IsSubstring, expected_help_fragment, captured_stdout);
+ } else {
+ EXPECT_PRED_FORMAT2(IsNotSubstring,
+ expected_help_fragment, captured_stdout);
+ }
+#endif // GTEST_HAS_STREAM_REDIRECTION_
+
+ ::testing::internal::g_help_flag = saved_help_flag;
}
// This macro wraps TestParsingFlags s.t. the user doesn't need
// to specify the array sizes.
-#define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected) \
+#define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \
TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \
- sizeof(argv2)/sizeof(*argv2) - 1, argv2, expected)
+ sizeof(argv2)/sizeof(*argv2) - 1, argv2, \
+ expected, should_print_help)
};
// Tests parsing an empty command line.
@@ -5412,7 +5267,7 @@ TEST_F(InitGoogleTestTest, Empty) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags());
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false);
}
// Tests parsing a command line that has no flag.
@@ -5427,7 +5282,7 @@ TEST_F(InitGoogleTestTest, NoFlag) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags());
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false);
}
// Tests parsing a bad --gtest_filter flag.
@@ -5444,7 +5299,7 @@ TEST_F(InitGoogleTestTest, FilterBad) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), true);
}
// Tests parsing an empty --gtest_filter flag.
@@ -5460,7 +5315,7 @@ TEST_F(InitGoogleTestTest, FilterEmpty) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), false);
}
// Tests parsing a non-empty --gtest_filter flag.
@@ -5476,7 +5331,7 @@ TEST_F(InitGoogleTestTest, FilterNonEmpty) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc"));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc"), false);
}
// Tests parsing --gtest_break_on_failure.
@@ -5492,7 +5347,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false);
}
// Tests parsing --gtest_break_on_failure=0.
@@ -5508,7 +5363,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false);
}
// Tests parsing --gtest_break_on_failure=f.
@@ -5524,7 +5379,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false);
}
// Tests parsing --gtest_break_on_failure=F.
@@ -5540,7 +5395,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false);
}
// Tests parsing a --gtest_break_on_failure flag that has a "true"
@@ -5557,7 +5412,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureTrue) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false);
}
// Tests parsing --gtest_catch_exceptions.
@@ -5573,7 +5428,7 @@ TEST_F(InitGoogleTestTest, CatchExceptions) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::CatchExceptions(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::CatchExceptions(true), false);
}
// Tests parsing --gtest_death_test_use_fork.
@@ -5589,7 +5444,7 @@ TEST_F(InitGoogleTestTest, DeathTestUseFork) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::DeathTestUseFork(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::DeathTestUseFork(true), false);
}
// Tests having the same flag twice with different values. The
@@ -5607,7 +5462,7 @@ TEST_F(InitGoogleTestTest, DuplicatedFlags) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("b"));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("b"), false);
}
// Tests having an unrecognized flag on the command line.
@@ -5629,7 +5484,7 @@ TEST_F(InitGoogleTestTest, UnrecognizedFlag) {
Flags flags;
flags.break_on_failure = true;
flags.filter = "b";
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, flags);
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, flags, false);
}
// Tests having a --gtest_list_tests flag
@@ -5645,7 +5500,7 @@ TEST_F(InitGoogleTestTest, ListTestsFlag) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false);
}
// Tests having a --gtest_list_tests flag with a "true" value
@@ -5661,7 +5516,7 @@ TEST_F(InitGoogleTestTest, ListTestsTrue) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false);
}
// Tests having a --gtest_list_tests flag with a "false" value
@@ -5677,7 +5532,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false);
}
// Tests parsing --gtest_list_tests=f.
@@ -5693,7 +5548,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_f) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false);
}
// Tests parsing --gtest_list_tests=F.
@@ -5709,7 +5564,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_F) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false);
}
// Tests parsing --gtest_output (invalid).
@@ -5726,7 +5581,7 @@ TEST_F(InitGoogleTestTest, OutputEmpty) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags());
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), true);
}
// Tests parsing --gtest_output=xml
@@ -5742,7 +5597,7 @@ TEST_F(InitGoogleTestTest, OutputXml) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml"));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml"), false);
}
// Tests parsing --gtest_output=xml:file
@@ -5758,7 +5613,7 @@ TEST_F(InitGoogleTestTest, OutputXmlFile) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:file"));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:file"), false);
}
// Tests parsing --gtest_output=xml:directory/path/
@@ -5774,7 +5629,8 @@ TEST_F(InitGoogleTestTest, OutputXmlDirectory) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:directory/path/"));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2,
+ Flags::Output("xml:directory/path/"), false);
}
// Tests having a --gtest_print_time flag
@@ -5790,7 +5646,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFlag) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false);
}
// Tests having a --gtest_print_time flag with a "true" value
@@ -5806,7 +5662,7 @@ TEST_F(InitGoogleTestTest, PrintTimeTrue) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false);
}
// Tests having a --gtest_print_time flag with a "false" value
@@ -5822,7 +5678,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false);
}
// Tests parsing --gtest_print_time=f.
@@ -5838,7 +5694,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_f) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false);
}
// Tests parsing --gtest_print_time=F.
@@ -5854,7 +5710,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_F) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false);
}
// Tests parsing --gtest_random_seed=number
@@ -5870,7 +5726,7 @@ TEST_F(InitGoogleTestTest, RandomSeed) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::RandomSeed(1000));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::RandomSeed(1000), false);
}
// Tests parsing --gtest_repeat=number
@@ -5886,7 +5742,7 @@ TEST_F(InitGoogleTestTest, Repeat) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Repeat(1000));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Repeat(1000), false);
}
// Tests having a --gtest_also_run_disabled_tests flag
@@ -5902,7 +5758,8 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2,
+ Flags::AlsoRunDisabledTests(true), false);
}
// Tests having a --gtest_also_run_disabled_tests flag with a "true" value
@@ -5918,7 +5775,8 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2,
+ Flags::AlsoRunDisabledTests(true), false);
}
// Tests having a --gtest_also_run_disabled_tests flag with a "false" value
@@ -5934,7 +5792,8 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(false));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2,
+ Flags::AlsoRunDisabledTests(false), false);
}
// Tests parsing --gtest_shuffle.
@@ -5950,7 +5809,7 @@ TEST_F(InitGoogleTestTest, ShuffleWithoutValue) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false);
}
// Tests parsing --gtest_shuffle=0.
@@ -5966,7 +5825,7 @@ TEST_F(InitGoogleTestTest, ShuffleFalse_0) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false), false);
}
// Tests parsing a --gtest_shuffle flag that has a "true"
@@ -5983,7 +5842,23 @@ TEST_F(InitGoogleTestTest, ShuffleTrue) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false);
+}
+
+// Tests parsing --gtest_stack_trace_depth=number.
+TEST_F(InitGoogleTestTest, StackTraceDepth) {
+ const char* argv[] = {
+ "foo.exe",
+ "--gtest_stack_trace_depth=5",
+ NULL
+ };
+
+ const char* argv2[] = {
+ "foo.exe",
+ NULL
+ };
+
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::StackTraceDepth(5), false);
}
// Tests parsing --gtest_throw_on_failure.
@@ -5999,7 +5874,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false);
}
// Tests parsing --gtest_throw_on_failure=0.
@@ -6015,7 +5890,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(false));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(false), false);
}
// Tests parsing a --gtest_throw_on_failure flag that has a "true"
@@ -6032,7 +5907,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) {
NULL
};
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true));
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false);
}
#if GTEST_OS_WINDOWS
@@ -6058,7 +5933,7 @@ TEST_F(InitGoogleTestTest, WideStrings) {
expected_flags.filter = "Foo*";
expected_flags.list_tests = true;
- GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags);
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false);
}
#endif // GTEST_OS_WINDOWS
@@ -6420,23 +6295,6 @@ TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) {
StaticAssertTypeEq<int*, IntAlias*>();
}
-TEST(ThreadLocalTest, DefaultConstructor) {
- ThreadLocal<int> t1;
- EXPECT_EQ(0, t1.get());
-
- ThreadLocal<void*> t2;
- EXPECT_TRUE(t2.get() == NULL);
-}
-
-TEST(ThreadLocalTest, Init) {
- ThreadLocal<int> t1(123);
- EXPECT_EQ(123, t1.get());
-
- int i = 0;
- ThreadLocal<int*> t2(&i);
- EXPECT_EQ(&i, t2.get());
-}
-
TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) {
testing::UnitTest* const unit_test = testing::UnitTest::GetInstance();
@@ -6608,26 +6466,26 @@ TEST(TestEventListenersTest, Append) {
// order.
class SequenceTestingListener : public EmptyTestEventListener {
public:
- SequenceTestingListener(Vector<String>* vector, const char* id)
+ SequenceTestingListener(std::vector<String>* vector, const char* id)
: vector_(vector), id_(id) {}
protected:
virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {
- vector_->PushBack(GetEventDescription("OnTestProgramStart"));
+ vector_->push_back(GetEventDescription("OnTestProgramStart"));
}
virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {
- vector_->PushBack(GetEventDescription("OnTestProgramEnd"));
+ vector_->push_back(GetEventDescription("OnTestProgramEnd"));
}
virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
int /*iteration*/) {
- vector_->PushBack(GetEventDescription("OnTestIterationStart"));
+ vector_->push_back(GetEventDescription("OnTestIterationStart"));
}
virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
int /*iteration*/) {
- vector_->PushBack(GetEventDescription("OnTestIterationEnd"));
+ vector_->push_back(GetEventDescription("OnTestIterationEnd"));
}
private:
@@ -6637,14 +6495,14 @@ class SequenceTestingListener : public EmptyTestEventListener {
return message.GetString();
}
- Vector<String>* vector_;
+ std::vector<String>* vector_;
const char* const id_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(SequenceTestingListener);
};
TEST(EventListenerTest, AppendKeepsOrder) {
- Vector<String> vec;
+ std::vector<String> vec;
TestEventListeners listeners;
listeners.Append(new SequenceTestingListener(&vec, "1st"));
listeners.Append(new SequenceTestingListener(&vec, "2nd"));
@@ -6652,34 +6510,34 @@ TEST(EventListenerTest, AppendKeepsOrder) {
TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart(
*UnitTest::GetInstance());
- ASSERT_EQ(3, vec.size());
- EXPECT_STREQ("1st.OnTestProgramStart", vec.GetElement(0).c_str());
- EXPECT_STREQ("2nd.OnTestProgramStart", vec.GetElement(1).c_str());
- EXPECT_STREQ("3rd.OnTestProgramStart", vec.GetElement(2).c_str());
+ ASSERT_EQ(3U, vec.size());
+ EXPECT_STREQ("1st.OnTestProgramStart", vec[0].c_str());
+ EXPECT_STREQ("2nd.OnTestProgramStart", vec[1].c_str());
+ EXPECT_STREQ("3rd.OnTestProgramStart", vec[2].c_str());
- vec.Clear();
+ vec.clear();
TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd(
*UnitTest::GetInstance());
- ASSERT_EQ(3, vec.size());
- EXPECT_STREQ("3rd.OnTestProgramEnd", vec.GetElement(0).c_str());
- EXPECT_STREQ("2nd.OnTestProgramEnd", vec.GetElement(1).c_str());
- EXPECT_STREQ("1st.OnTestProgramEnd", vec.GetElement(2).c_str());
+ ASSERT_EQ(3U, vec.size());
+ EXPECT_STREQ("3rd.OnTestProgramEnd", vec[0].c_str());
+ EXPECT_STREQ("2nd.OnTestProgramEnd", vec[1].c_str());
+ EXPECT_STREQ("1st.OnTestProgramEnd", vec[2].c_str());
- vec.Clear();
+ vec.clear();
TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart(
*UnitTest::GetInstance(), 0);
- ASSERT_EQ(3, vec.size());
- EXPECT_STREQ("1st.OnTestIterationStart", vec.GetElement(0).c_str());
- EXPECT_STREQ("2nd.OnTestIterationStart", vec.GetElement(1).c_str());
- EXPECT_STREQ("3rd.OnTestIterationStart", vec.GetElement(2).c_str());
+ ASSERT_EQ(3U, vec.size());
+ EXPECT_STREQ("1st.OnTestIterationStart", vec[0].c_str());
+ EXPECT_STREQ("2nd.OnTestIterationStart", vec[1].c_str());
+ EXPECT_STREQ("3rd.OnTestIterationStart", vec[2].c_str());
- vec.Clear();
+ vec.clear();
TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd(
*UnitTest::GetInstance(), 0);
- ASSERT_EQ(3, vec.size());
- EXPECT_STREQ("3rd.OnTestIterationEnd", vec.GetElement(0).c_str());
- EXPECT_STREQ("2nd.OnTestIterationEnd", vec.GetElement(1).c_str());
- EXPECT_STREQ("1st.OnTestIterationEnd", vec.GetElement(2).c_str());
+ ASSERT_EQ(3U, vec.size());
+ EXPECT_STREQ("3rd.OnTestIterationEnd", vec[0].c_str());
+ EXPECT_STREQ("2nd.OnTestIterationEnd", vec[1].c_str());
+ EXPECT_STREQ("1st.OnTestIterationEnd", vec[2].c_str());
}
// Tests that a listener removed from a TestEventListeners list stops receiving
@@ -6845,3 +6703,16 @@ TEST(EventListenerTest, RemovingDefaultXmlGeneratorWorks) {
EXPECT_FALSE(is_destroyed);
delete listener;
}
+
+// Sanity tests to ensure that the alternative, verbose spellings of
+// some of the macros work. We don't test them thoroughly as that
+// would be quite involved. Since their implementations are
+// straightforward, and they are rarely used, we'll just rely on the
+// users to tell us when they are broken.
+GTEST_TEST(AlternativeNameTest, Works) { // GTEST_TEST is the same as TEST.
+ GTEST_SUCCEED() << "OK"; // GTEST_SUCCEED is the same as SUCCEED.
+
+ // GTEST_FAIL is the same as FAIL.
+ EXPECT_FATAL_FAILURE(GTEST_FAIL() << "An expected failure",
+ "An expected failure");
+}
diff --git a/gtest/test/production.h b/gtest/test/production.h
index 59970da..8f16fff 100644
--- a/gtest/test/production.h
+++ b/gtest/test/production.h
@@ -48,7 +48,7 @@ class PrivateCode {
int x() const { return x_; }
private:
- void set_x(int x) { x_ = x; }
+ void set_x(int an_x) { x_ = an_x; }
int x_;
};
diff --git a/gtest/test/run_tests_util.py b/gtest/test/run_tests_util.py
new file mode 100755
index 0000000..9e57931
--- /dev/null
+++ b/gtest/test/run_tests_util.py
@@ -0,0 +1,466 @@
+# Copyright 2008 Google Inc. All Rights Reserved.
+#
+# 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.
+
+"""Provides facilities for running SCons-built Google Test/Mock tests."""
+
+
+import optparse
+import os
+import re
+import sets
+import sys
+
+try:
+ # subrocess module is a preferable way to invoke subprocesses but it may
+ # not be available on MacOS X 10.4.
+ # Suppresses the 'Import not at the top of the file' lint complaint.
+ # pylint: disable-msg=C6204
+ import subprocess
+except ImportError:
+ subprocess = None
+
+HELP_MSG = """Runs the specified tests for %(proj)s.
+
+SYNOPSIS
+ run_tests.py [OPTION]... [BUILD_DIR]... [TEST]...
+
+DESCRIPTION
+ Runs the specified tests (either binary or Python), and prints a
+ summary of the results. BUILD_DIRS will be used to search for the
+ binaries. If no TESTs are specified, all binary tests found in
+ BUILD_DIRs and all Python tests found in the directory test/ (in the
+ %(proj)s root) are run.
+
+ TEST is a name of either a binary or a Python test. A binary test is
+ an executable file named *_test or *_unittest (with the .exe
+ extension on Windows) A Python test is a script named *_test.py or
+ *_unittest.py.
+
+OPTIONS
+ -h, --help
+ Print this help message.
+ -c CONFIGURATIONS
+ Specify build directories via build configurations.
+ CONFIGURATIONS is either a comma-separated list of build
+ configurations or 'all'. Each configuration is equivalent to
+ adding 'scons/build/<configuration>/%(proj)s/scons' to BUILD_DIRs.
+ Specifying -c=all is equivalent to providing all directories
+ listed in KNOWN BUILD DIRECTORIES section below.
+ -a
+ Equivalent to -c=all
+ -b
+ Equivalent to -c=all with the exception that the script will not
+ fail if some of the KNOWN BUILD DIRECTORIES do not exists; the
+ script will simply not run the tests there. 'b' stands for
+ 'built directories'.
+
+RETURN VALUE
+ Returns 0 if all tests are successful; otherwise returns 1.
+
+EXAMPLES
+ run_tests.py
+ Runs all tests for the default build configuration.
+ run_tests.py -a
+ Runs all tests with binaries in KNOWN BUILD DIRECTORIES.
+ run_tests.py -b
+ Runs all tests in KNOWN BUILD DIRECTORIES that have been
+ built.
+ run_tests.py foo/
+ Runs all tests in the foo/ directory and all Python tests in
+ the directory test. The Python tests are instructed to look
+ for binaries in foo/.
+ run_tests.py bar_test.exe test/baz_test.exe foo/ bar/
+ Runs foo/bar_test.exe, bar/bar_test.exe, foo/baz_test.exe, and
+ bar/baz_test.exe.
+ run_tests.py foo bar test/foo_test.py
+ Runs test/foo_test.py twice instructing it to look for its
+ test binaries in the directories foo and bar,
+ correspondingly.
+
+KNOWN BUILD DIRECTORIES
+ run_tests.py knows about directories where the SCons build script
+ deposits its products. These are the directories where run_tests.py
+ will be looking for its binaries. Currently, %(proj)s's SConstruct file
+ defines them as follows (the default build directory is the first one
+ listed in each group):
+ On Windows:
+ <%(proj)s root>/scons/build/win-dbg8/%(proj)s/scons/
+ <%(proj)s root>/scons/build/win-opt8/%(proj)s/scons/
+ On Mac:
+ <%(proj)s root>/scons/build/mac-dbg/%(proj)s/scons/
+ <%(proj)s root>/scons/build/mac-opt/%(proj)s/scons/
+ On other platforms:
+ <%(proj)s root>/scons/build/dbg/%(proj)s/scons/
+ <%(proj)s root>/scons/build/opt/%(proj)s/scons/"""
+
+IS_WINDOWS = os.name == 'nt'
+IS_MAC = os.name == 'posix' and os.uname()[0] == 'Darwin'
+IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0]
+
+# Definition of CONFIGS must match that of the build directory names in the
+# SConstruct script. The first list item is the default build configuration.
+if IS_WINDOWS:
+ CONFIGS = ('win-dbg8', 'win-opt8')
+elif IS_MAC:
+ CONFIGS = ('mac-dbg', 'mac-opt')
+else:
+ CONFIGS = ('dbg', 'opt')
+
+if IS_WINDOWS or IS_CYGWIN:
+ PYTHON_TEST_REGEX = re.compile(r'_(unit)?test\.py$', re.IGNORECASE)
+ BINARY_TEST_REGEX = re.compile(r'_(unit)?test(\.exe)?$', re.IGNORECASE)
+ BINARY_TEST_SEARCH_REGEX = re.compile(r'_(unit)?test\.exe$', re.IGNORECASE)
+else:
+ PYTHON_TEST_REGEX = re.compile(r'_(unit)?test\.py$')
+ BINARY_TEST_REGEX = re.compile(r'_(unit)?test$')
+ BINARY_TEST_SEARCH_REGEX = BINARY_TEST_REGEX
+
+
+def _GetGtestBuildDir(injected_os, script_dir, config):
+ """Calculates path to the Google Test SCons build directory."""
+
+ return injected_os.path.normpath(injected_os.path.join(script_dir,
+ 'scons/build',
+ config,
+ 'gtest/scons'))
+
+
+def _GetConfigFromBuildDir(build_dir):
+ """Extracts the configuration name from the build directory."""
+
+ # We don't want to depend on build_dir containing the correct path
+ # separators.
+ m = re.match(r'.*[\\/]([^\\/]+)[\\/][^\\/]+[\\/]scons[\\/]?$', build_dir)
+ if m:
+ return m.group(1)
+ else:
+ print >>sys.stderr, ('%s is an invalid build directory that does not '
+ 'correspond to any configuration.' % (build_dir,))
+ return ''
+
+
+# All paths in this script are either absolute or relative to the current
+# working directory, unless otherwise specified.
+class TestRunner(object):
+ """Provides facilities for running Python and binary tests for Google Test."""
+
+ def __init__(self,
+ script_dir,
+ build_dir_var_name='GTEST_BUILD_DIR',
+ injected_os=os,
+ injected_subprocess=subprocess,
+ injected_build_dir_finder=_GetGtestBuildDir):
+ """Initializes a TestRunner instance.
+
+ Args:
+ script_dir: File path to the calling script.
+ build_dir_var_name: Name of the env variable used to pass the
+ the build directory path to the invoked
+ tests.
+ injected_os: standard os module or a mock/stub for
+ testing.
+ injected_subprocess: standard subprocess module or a mock/stub
+ for testing
+ injected_build_dir_finder: function that determines the path to
+ the build directory.
+ """
+
+ self.os = injected_os
+ self.subprocess = injected_subprocess
+ self.build_dir_finder = injected_build_dir_finder
+ self.build_dir_var_name = build_dir_var_name
+ self.script_dir = script_dir
+
+ def _GetBuildDirForConfig(self, config):
+ """Returns the build directory for a given configuration."""
+
+ return self.build_dir_finder(self.os, self.script_dir, config)
+
+ def _Run(self, args):
+ """Runs the executable with given args (args[0] is the executable name).
+
+ Args:
+ args: Command line arguments for the process.
+
+ Returns:
+ Process's exit code if it exits normally, or -signal if the process is
+ killed by a signal.
+ """
+
+ if self.subprocess:
+ return self.subprocess.Popen(args).wait()
+ else:
+ return self.os.spawnv(self.os.P_WAIT, args[0], args)
+
+ def _RunBinaryTest(self, test):
+ """Runs the binary test given its path.
+
+ Args:
+ test: Path to the test binary.
+
+ Returns:
+ Process's exit code if it exits normally, or -signal if the process is
+ killed by a signal.
+ """
+
+ return self._Run([test])
+
+ def _RunPythonTest(self, test, build_dir):
+ """Runs the Python test script with the specified build directory.
+
+ Args:
+ test: Path to the test's Python script.
+ build_dir: Path to the directory where the test binary is to be found.
+
+ Returns:
+ Process's exit code if it exits normally, or -signal if the process is
+ killed by a signal.
+ """
+
+ old_build_dir = self.os.environ.get(self.build_dir_var_name)
+
+ try:
+ self.os.environ[self.build_dir_var_name] = build_dir
+
+ # If this script is run on a Windows machine that has no association
+ # between the .py extension and a python interpreter, simply passing
+ # the script name into subprocess.Popen/os.spawn will not work.
+ print 'Running %s . . .' % (test,)
+ return self._Run([sys.executable, test])
+
+ finally:
+ if old_build_dir is None:
+ del self.os.environ[self.build_dir_var_name]
+ else:
+ self.os.environ[self.build_dir_var_name] = old_build_dir
+
+ def _FindFilesByRegex(self, directory, regex):
+ """Returns files in a directory whose names match a regular expression.
+
+ Args:
+ directory: Path to the directory to search for files.
+ regex: Regular expression to filter file names.
+
+ Returns:
+ The list of the paths to the files in the directory.
+ """
+
+ return [self.os.path.join(directory, file_name)
+ for file_name in self.os.listdir(directory)
+ if re.search(regex, file_name)]
+
+ # TODO(vladl@google.com): Implement parsing of scons/SConscript to run all
+ # tests defined there when no tests are specified.
+ # TODO(vladl@google.com): Update the docstring after the code is changed to
+ # try to test all builds defined in scons/SConscript.
+ def GetTestsToRun(self,
+ args,
+ named_configurations,
+ built_configurations,
+ available_configurations=CONFIGS,
+ python_tests_to_skip=None):
+ """Determines what tests should be run.
+
+ Args:
+ args: The list of non-option arguments from the command line.
+ named_configurations: The list of configurations specified via -c or -a.
+ built_configurations: True if -b has been specified.
+ available_configurations: a list of configurations available on the
+ current platform, injectable for testing.
+ python_tests_to_skip: a collection of (configuration, python test name)s
+ that need to be skipped.
+
+ Returns:
+ A tuple with 2 elements: the list of Python tests to run and the list of
+ binary tests to run.
+ """
+
+ if named_configurations == 'all':
+ named_configurations = ','.join(available_configurations)
+
+ normalized_args = [self.os.path.normpath(arg) for arg in args]
+
+ # A final list of build directories which will be searched for the test
+ # binaries. First, add directories specified directly on the command
+ # line.
+ build_dirs = filter(self.os.path.isdir, normalized_args)
+
+ # Adds build directories specified via their build configurations using
+ # the -c or -a options.
+ if named_configurations:
+ build_dirs += [self._GetBuildDirForConfig(config)
+ for config in named_configurations.split(',')]
+
+ # Adds KNOWN BUILD DIRECTORIES if -b is specified.
+ if built_configurations:
+ build_dirs += [self._GetBuildDirForConfig(config)
+ for config in available_configurations
+ if self.os.path.isdir(self._GetBuildDirForConfig(config))]
+
+ # If no directories were specified either via -a, -b, -c, or directly, use
+ # the default configuration.
+ elif not build_dirs:
+ build_dirs = [self._GetBuildDirForConfig(available_configurations[0])]
+
+ # Makes sure there are no duplications.
+ build_dirs = sets.Set(build_dirs)
+
+ errors_found = False
+ listed_python_tests = [] # All Python tests listed on the command line.
+ listed_binary_tests = [] # All binary tests listed on the command line.
+
+ test_dir = self.os.path.normpath(self.os.path.join(self.script_dir, 'test'))
+
+ # Sifts through non-directory arguments fishing for any Python or binary
+ # tests and detecting errors.
+ for argument in sets.Set(normalized_args) - build_dirs:
+ if re.search(PYTHON_TEST_REGEX, argument):
+ python_path = self.os.path.join(test_dir,
+ self.os.path.basename(argument))
+ if self.os.path.isfile(python_path):
+ listed_python_tests.append(python_path)
+ else:
+ sys.stderr.write('Unable to find Python test %s' % argument)
+ errors_found = True
+ elif re.search(BINARY_TEST_REGEX, argument):
+ # This script also accepts binary test names prefixed with test/ for
+ # the convenience of typing them (can use path completions in the
+ # shell). Strips test/ prefix from the binary test names.
+ listed_binary_tests.append(self.os.path.basename(argument))
+ else:
+ sys.stderr.write('%s is neither test nor build directory' % argument)
+ errors_found = True
+
+ if errors_found:
+ return None
+
+ user_has_listed_tests = listed_python_tests or listed_binary_tests
+
+ if user_has_listed_tests:
+ selected_python_tests = listed_python_tests
+ else:
+ selected_python_tests = self._FindFilesByRegex(test_dir,
+ PYTHON_TEST_REGEX)
+
+ # TODO(vladl@google.com): skip unbuilt Python tests when -b is specified.
+ python_test_pairs = []
+ for directory in build_dirs:
+ for test in selected_python_tests:
+ config = _GetConfigFromBuildDir(directory)
+ file_name = os.path.basename(test)
+ if python_tests_to_skip and (config, file_name) in python_tests_to_skip:
+ print ('NOTE: %s is skipped for configuration %s, as it does not '
+ 'work there.' % (file_name, config))
+ else:
+ python_test_pairs.append((directory, test))
+
+ binary_test_pairs = []
+ for directory in build_dirs:
+ if user_has_listed_tests:
+ binary_test_pairs.extend(
+ [(directory, self.os.path.join(directory, test))
+ for test in listed_binary_tests])
+ else:
+ tests = self._FindFilesByRegex(directory, BINARY_TEST_SEARCH_REGEX)
+ binary_test_pairs.extend([(directory, test) for test in tests])
+
+ return (python_test_pairs, binary_test_pairs)
+
+ def RunTests(self, python_tests, binary_tests):
+ """Runs Python and binary tests and reports results to the standard output.
+
+ Args:
+ python_tests: List of Python tests to run in the form of tuples
+ (build directory, Python test script).
+ binary_tests: List of binary tests to run in the form of tuples
+ (build directory, binary file).
+
+ Returns:
+ The exit code the program should pass into sys.exit().
+ """
+
+ if python_tests or binary_tests:
+ results = []
+ for directory, test in python_tests:
+ results.append((directory,
+ test,
+ self._RunPythonTest(test, directory) == 0))
+ for directory, test in binary_tests:
+ results.append((directory,
+ self.os.path.basename(test),
+ self._RunBinaryTest(test) == 0))
+
+ failed = [(directory, test)
+ for (directory, test, success) in results
+ if not success]
+ print
+ print '%d tests run.' % len(results)
+ if failed:
+ print 'The following %d tests failed:' % len(failed)
+ for (directory, test) in failed:
+ print '%s in %s' % (test, directory)
+ return 1
+ else:
+ print 'All tests passed!'
+ else: # No tests defined
+ print 'Nothing to test - no tests specified!'
+
+ return 0
+
+
+def ParseArgs(project_name, argv=None, help_callback=None):
+ """Parses the options run_tests.py uses."""
+
+ # Suppresses lint warning on unused arguments. These arguments are
+ # required by optparse, even though they are unused.
+ # pylint: disable-msg=W0613
+ def PrintHelp(option, opt, value, parser):
+ print HELP_MSG % {'proj': project_name}
+ sys.exit(1)
+
+ parser = optparse.OptionParser()
+ parser.add_option('-c',
+ action='store',
+ dest='configurations',
+ default=None)
+ parser.add_option('-a',
+ action='store_const',
+ dest='configurations',
+ default=None,
+ const='all')
+ parser.add_option('-b',
+ action='store_const',
+ dest='built_configurations',
+ default=False,
+ const=True)
+ # Replaces the built-in help with ours.
+ parser.remove_option('-h')
+ parser.add_option('-h', '--help',
+ action='callback',
+ callback=help_callback or PrintHelp)
+ return parser.parse_args(argv)
diff --git a/gtest/test/run_tests_util_test.py b/gtest/test/run_tests_util_test.py
new file mode 100755
index 0000000..9c55726
--- /dev/null
+++ b/gtest/test/run_tests_util_test.py
@@ -0,0 +1,676 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Google Inc. All Rights Reserved.
+#
+# 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.
+
+"""Tests for run_tests_util.py test runner script."""
+
+__author__ = 'vladl@google.com (Vlad Losev)'
+
+import os
+import re
+import sets
+import unittest
+
+import run_tests_util
+
+
+GTEST_DBG_DIR = 'scons/build/dbg/gtest/scons'
+GTEST_OPT_DIR = 'scons/build/opt/gtest/scons'
+GTEST_OTHER_DIR = 'scons/build/other/gtest/scons'
+
+
+def AddExeExtension(path):
+ """Appends .exe to the path on Windows or Cygwin."""
+
+ if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN:
+ return path + '.exe'
+ else:
+ return path
+
+
+class FakePath(object):
+ """A fake os.path module for testing."""
+
+ def __init__(self, current_dir=os.getcwd(), known_paths=None):
+ self.current_dir = current_dir
+ self.tree = {}
+ self.path_separator = os.sep
+
+ # known_paths contains either absolute or relative paths. Relative paths
+ # are absolutized with self.current_dir.
+ if known_paths:
+ self._AddPaths(known_paths)
+
+ def _AddPath(self, path):
+ ends_with_slash = path.endswith('/')
+ path = self.abspath(path)
+ if ends_with_slash:
+ path += self.path_separator
+ name_list = path.split(self.path_separator)
+ tree = self.tree
+ for name in name_list[:-1]:
+ if not name:
+ continue
+ if name in tree:
+ tree = tree[name]
+ else:
+ tree[name] = {}
+ tree = tree[name]
+
+ name = name_list[-1]
+ if name:
+ if name in tree:
+ assert tree[name] == 1
+ else:
+ tree[name] = 1
+
+ def _AddPaths(self, paths):
+ for path in paths:
+ self._AddPath(path)
+
+ def PathElement(self, path):
+ """Returns an internal representation of directory tree entry for path."""
+ tree = self.tree
+ name_list = self.abspath(path).split(self.path_separator)
+ for name in name_list:
+ if not name:
+ continue
+ tree = tree.get(name, None)
+ if tree is None:
+ break
+
+ return tree
+
+ # Silences pylint warning about using standard names.
+ # pylint: disable-msg=C6409
+ def normpath(self, path):
+ return os.path.normpath(path)
+
+ def abspath(self, path):
+ return self.normpath(os.path.join(self.current_dir, path))
+
+ def isfile(self, path):
+ return self.PathElement(self.abspath(path)) == 1
+
+ def isdir(self, path):
+ return type(self.PathElement(self.abspath(path))) == type(dict())
+
+ def basename(self, path):
+ return os.path.basename(path)
+
+ def dirname(self, path):
+ return os.path.dirname(path)
+
+ def join(self, *kargs):
+ return os.path.join(*kargs)
+
+
+class FakeOs(object):
+ """A fake os module for testing."""
+ P_WAIT = os.P_WAIT
+
+ def __init__(self, fake_path_module):
+ self.path = fake_path_module
+
+ # Some methods/attributes are delegated to the real os module.
+ self.environ = os.environ
+
+ # pylint: disable-msg=C6409
+ def listdir(self, path):
+ assert self.path.isdir(path)
+ return self.path.PathElement(path).iterkeys()
+
+ def spawnv(self, wait, executable, *kargs):
+ assert wait == FakeOs.P_WAIT
+ return self.spawn_impl(executable, kargs)
+
+
+class GetTestsToRunTest(unittest.TestCase):
+ """Exercises TestRunner.GetTestsToRun."""
+
+ def NormalizeGetTestsToRunResults(self, results):
+ """Normalizes path data returned from GetTestsToRun for comparison."""
+
+ def NormalizePythonTestPair(pair):
+ """Normalizes path data in the (directory, python_script) pair."""
+
+ return (os.path.normpath(pair[0]), os.path.normpath(pair[1]))
+
+ def NormalizeBinaryTestPair(pair):
+ """Normalizes path data in the (directory, binary_executable) pair."""
+
+ directory, executable = map(os.path.normpath, pair)
+
+ # On Windows and Cygwin, the test file names have the .exe extension, but
+ # they can be invoked either by name or by name+extension. Our test must
+ # accommodate both situations.
+ if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN:
+ executable = re.sub(r'\.exe$', '', executable)
+ return (directory, executable)
+
+ python_tests = sets.Set(map(NormalizePythonTestPair, results[0]))
+ binary_tests = sets.Set(map(NormalizeBinaryTestPair, results[1]))
+ return (python_tests, binary_tests)
+
+ def AssertResultsEqual(self, results, expected):
+ """Asserts results returned by GetTestsToRun equal to expected results."""
+
+ self.assertEqual(self.NormalizeGetTestsToRunResults(results),
+ self.NormalizeGetTestsToRunResults(expected),
+ 'Incorrect set of tests returned:\n%s\nexpected:\n%s' %
+ (results, expected))
+
+ def setUp(self):
+ self.fake_os = FakeOs(FakePath(
+ current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)),
+ known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'),
+ AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'),
+ 'test/gtest_color_test.py']))
+ self.fake_configurations = ['dbg', 'opt']
+ self.test_runner = run_tests_util.TestRunner(script_dir='.',
+ injected_os=self.fake_os,
+ injected_subprocess=None)
+
+ def testBinaryTestsOnly(self):
+ """Exercises GetTestsToRun with parameters designating binary tests only."""
+
+ # A default build.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_unittest'],
+ '',
+ False,
+ available_configurations=self.fake_configurations),
+ ([],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
+
+ # An explicitly specified directory.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ [GTEST_DBG_DIR, 'gtest_unittest'],
+ '',
+ False,
+ available_configurations=self.fake_configurations),
+ ([],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
+
+ # A particular configuration.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_unittest'],
+ 'other',
+ False,
+ available_configurations=self.fake_configurations),
+ ([],
+ [(GTEST_OTHER_DIR, GTEST_OTHER_DIR + '/gtest_unittest')]))
+
+ # All available configurations
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_unittest'],
+ 'all',
+ False,
+ available_configurations=self.fake_configurations),
+ ([],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'),
+ (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')]))
+
+ # All built configurations (unbuilt don't cause failure).
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_unittest'],
+ '',
+ True,
+ available_configurations=self.fake_configurations + ['unbuilt']),
+ ([],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'),
+ (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')]))
+
+ # A combination of an explicit directory and a configuration.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ [GTEST_DBG_DIR, 'gtest_unittest'],
+ 'opt',
+ False,
+ available_configurations=self.fake_configurations),
+ ([],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'),
+ (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')]))
+
+ # Same test specified in an explicit directory and via a configuration.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ [GTEST_DBG_DIR, 'gtest_unittest'],
+ 'dbg',
+ False,
+ available_configurations=self.fake_configurations),
+ ([],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
+
+ # All built configurations + explicit directory + explicit configuration.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ [GTEST_DBG_DIR, 'gtest_unittest'],
+ 'opt',
+ True,
+ available_configurations=self.fake_configurations),
+ ([],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'),
+ (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')]))
+
+ def testPythonTestsOnly(self):
+ """Exercises GetTestsToRun with parameters designating Python tests only."""
+
+ # A default build.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_color_test.py'],
+ '',
+ False,
+ available_configurations=self.fake_configurations),
+ ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+ []))
+
+ # An explicitly specified directory.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ [GTEST_DBG_DIR, 'test/gtest_color_test.py'],
+ '',
+ False,
+ available_configurations=self.fake_configurations),
+ ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+ []))
+
+ # A particular configuration.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_color_test.py'],
+ 'other',
+ False,
+ available_configurations=self.fake_configurations),
+ ([(GTEST_OTHER_DIR, 'test/gtest_color_test.py')],
+ []))
+
+ # All available configurations
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['test/gtest_color_test.py'],
+ 'all',
+ False,
+ available_configurations=self.fake_configurations),
+ ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'),
+ (GTEST_OPT_DIR, 'test/gtest_color_test.py')],
+ []))
+
+ # All built configurations (unbuilt don't cause failure).
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_color_test.py'],
+ '',
+ True,
+ available_configurations=self.fake_configurations + ['unbuilt']),
+ ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'),
+ (GTEST_OPT_DIR, 'test/gtest_color_test.py')],
+ []))
+
+ # A combination of an explicit directory and a configuration.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ [GTEST_DBG_DIR, 'gtest_color_test.py'],
+ 'opt',
+ False,
+ available_configurations=self.fake_configurations),
+ ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'),
+ (GTEST_OPT_DIR, 'test/gtest_color_test.py')],
+ []))
+
+ # Same test specified in an explicit directory and via a configuration.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ [GTEST_DBG_DIR, 'gtest_color_test.py'],
+ 'dbg',
+ False,
+ available_configurations=self.fake_configurations),
+ ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+ []))
+
+ # All built configurations + explicit directory + explicit configuration.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ [GTEST_DBG_DIR, 'gtest_color_test.py'],
+ 'opt',
+ True,
+ available_configurations=self.fake_configurations),
+ ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'),
+ (GTEST_OPT_DIR, 'test/gtest_color_test.py')],
+ []))
+
+ def testCombinationOfBinaryAndPythonTests(self):
+ """Exercises GetTestsToRun with mixed binary/Python tests."""
+
+ # Use only default configuration for this test.
+
+ # Neither binary nor Python tests are specified so find all.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ [],
+ '',
+ False,
+ available_configurations=self.fake_configurations),
+ ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
+
+ # Specifying both binary and Python tests.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_unittest', 'gtest_color_test.py'],
+ '',
+ False,
+ available_configurations=self.fake_configurations),
+ ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
+
+ # Specifying binary tests suppresses Python tests.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_unittest'],
+ '',
+ False,
+ available_configurations=self.fake_configurations),
+ ([],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
+
+ # Specifying Python tests suppresses binary tests.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_color_test.py'],
+ '',
+ False,
+ available_configurations=self.fake_configurations),
+ ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+ []))
+
+ def testIgnoresNonTestFiles(self):
+ """Verifies that GetTestsToRun ignores non-test files in the filesystem."""
+
+ self.fake_os = FakeOs(FakePath(
+ current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)),
+ known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_nontest'),
+ 'test/']))
+ self.test_runner = run_tests_util.TestRunner(script_dir='.',
+ injected_os=self.fake_os,
+ injected_subprocess=None)
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ [],
+ '',
+ True,
+ available_configurations=self.fake_configurations),
+ ([], []))
+
+ def testWorksFromDifferentDir(self):
+ """Exercises GetTestsToRun from a directory different from run_test.py's."""
+
+ # Here we simulate an test script in directory /d/ called from the
+ # directory /a/b/c/.
+ self.fake_os = FakeOs(FakePath(
+ current_dir=os.path.abspath('/a/b/c'),
+ known_paths=[
+ '/a/b/c/',
+ AddExeExtension('/d/' + GTEST_DBG_DIR + '/gtest_unittest'),
+ AddExeExtension('/d/' + GTEST_OPT_DIR + '/gtest_unittest'),
+ '/d/test/gtest_color_test.py']))
+ self.fake_configurations = ['dbg', 'opt']
+ self.test_runner = run_tests_util.TestRunner(script_dir='/d/',
+ injected_os=self.fake_os,
+ injected_subprocess=None)
+ # A binary test.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_unittest'],
+ '',
+ False,
+ available_configurations=self.fake_configurations),
+ ([],
+ [('/d/' + GTEST_DBG_DIR, '/d/' + GTEST_DBG_DIR + '/gtest_unittest')]))
+
+ # A Python test.
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ ['gtest_color_test.py'],
+ '',
+ False,
+ available_configurations=self.fake_configurations),
+ ([('/d/' + GTEST_DBG_DIR, '/d/test/gtest_color_test.py')], []))
+
+ def testNonTestBinary(self):
+ """Exercises GetTestsToRun with a non-test parameter."""
+
+ self.assert_(
+ not self.test_runner.GetTestsToRun(
+ ['gtest_unittest_not_really'],
+ '',
+ False,
+ available_configurations=self.fake_configurations))
+
+ def testNonExistingPythonTest(self):
+ """Exercises GetTestsToRun with a non-existent Python test parameter."""
+
+ self.assert_(
+ not self.test_runner.GetTestsToRun(
+ ['nonexistent_test.py'],
+ '',
+ False,
+ available_configurations=self.fake_configurations))
+
+ if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN:
+
+ def testDoesNotPickNonExeFilesOnWindows(self):
+ """Verifies that GetTestsToRun does not find _test files on Windows."""
+
+ self.fake_os = FakeOs(FakePath(
+ current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)),
+ known_paths=['/d/' + GTEST_DBG_DIR + '/gtest_test', 'test/']))
+ self.test_runner = run_tests_util.TestRunner(script_dir='.',
+ injected_os=self.fake_os,
+ injected_subprocess=None)
+ self.AssertResultsEqual(
+ self.test_runner.GetTestsToRun(
+ [],
+ '',
+ True,
+ available_configurations=self.fake_configurations),
+ ([], []))
+
+
+class RunTestsTest(unittest.TestCase):
+ """Exercises TestRunner.RunTests."""
+
+ def SpawnSuccess(self, unused_executable, unused_argv):
+ """Fakes test success by returning 0 as an exit code."""
+
+ self.num_spawn_calls += 1
+ return 0
+
+ def SpawnFailure(self, unused_executable, unused_argv):
+ """Fakes test success by returning 1 as an exit code."""
+
+ self.num_spawn_calls += 1
+ return 1
+
+ def setUp(self):
+ self.fake_os = FakeOs(FakePath(
+ current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)),
+ known_paths=[
+ AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'),
+ AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'),
+ 'test/gtest_color_test.py']))
+ self.fake_configurations = ['dbg', 'opt']
+ self.test_runner = run_tests_util.TestRunner(
+ script_dir=os.path.dirname(__file__) or '.',
+ injected_os=self.fake_os,
+ injected_subprocess=None)
+ self.num_spawn_calls = 0 # A number of calls to spawn.
+
+ def testRunPythonTestSuccess(self):
+ """Exercises RunTests to handle a Python test success."""
+
+ self.fake_os.spawn_impl = self.SpawnSuccess
+ self.assertEqual(
+ self.test_runner.RunTests(
+ [(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+ []),
+ 0)
+ self.assertEqual(self.num_spawn_calls, 1)
+
+ def testRunBinaryTestSuccess(self):
+ """Exercises RunTests to handle a binary test success."""
+
+ self.fake_os.spawn_impl = self.SpawnSuccess
+ self.assertEqual(
+ self.test_runner.RunTests(
+ [],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]),
+ 0)
+ self.assertEqual(self.num_spawn_calls, 1)
+
+ def testRunPythonTestFauilure(self):
+ """Exercises RunTests to handle a Python test failure."""
+
+ self.fake_os.spawn_impl = self.SpawnFailure
+ self.assertEqual(
+ self.test_runner.RunTests(
+ [(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+ []),
+ 1)
+ self.assertEqual(self.num_spawn_calls, 1)
+
+ def testRunBinaryTestFailure(self):
+ """Exercises RunTests to handle a binary test failure."""
+
+ self.fake_os.spawn_impl = self.SpawnFailure
+ self.assertEqual(
+ self.test_runner.RunTests(
+ [],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]),
+ 1)
+ self.assertEqual(self.num_spawn_calls, 1)
+
+ def testCombinedTestSuccess(self):
+ """Exercises RunTests to handle a success of both Python and binary test."""
+
+ self.fake_os.spawn_impl = self.SpawnSuccess
+ self.assertEqual(
+ self.test_runner.RunTests(
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]),
+ 0)
+ self.assertEqual(self.num_spawn_calls, 2)
+
+ def testCombinedTestSuccessAndFailure(self):
+ """Exercises RunTests to handle a success of both Python and binary test."""
+
+ def SpawnImpl(executable, argv):
+ self.num_spawn_calls += 1
+ # Simulates failure of a Python test and success of a binary test.
+ if '.py' in executable or '.py' in argv[0]:
+ return 1
+ else:
+ return 0
+
+ self.fake_os.spawn_impl = SpawnImpl
+ self.assertEqual(
+ self.test_runner.RunTests(
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')],
+ [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]),
+ 0)
+ self.assertEqual(self.num_spawn_calls, 2)
+
+
+class ParseArgsTest(unittest.TestCase):
+ """Exercises ParseArgs."""
+
+ def testNoOptions(self):
+ options, args = run_tests_util.ParseArgs('gtest', argv=['script.py'])
+ self.assertEqual(args, ['script.py'])
+ self.assert_(options.configurations is None)
+ self.assertFalse(options.built_configurations)
+
+ def testOptionC(self):
+ options, args = run_tests_util.ParseArgs(
+ 'gtest', argv=['script.py', '-c', 'dbg'])
+ self.assertEqual(args, ['script.py'])
+ self.assertEqual(options.configurations, 'dbg')
+ self.assertFalse(options.built_configurations)
+
+ def testOptionA(self):
+ options, args = run_tests_util.ParseArgs('gtest', argv=['script.py', '-a'])
+ self.assertEqual(args, ['script.py'])
+ self.assertEqual(options.configurations, 'all')
+ self.assertFalse(options.built_configurations)
+
+ def testOptionB(self):
+ options, args = run_tests_util.ParseArgs('gtest', argv=['script.py', '-b'])
+ self.assertEqual(args, ['script.py'])
+ self.assert_(options.configurations is None)
+ self.assertTrue(options.built_configurations)
+
+ def testOptionCAndOptionB(self):
+ options, args = run_tests_util.ParseArgs(
+ 'gtest', argv=['script.py', '-c', 'dbg', '-b'])
+ self.assertEqual(args, ['script.py'])
+ self.assertEqual(options.configurations, 'dbg')
+ self.assertTrue(options.built_configurations)
+
+ def testOptionH(self):
+ help_called = [False]
+
+ # Suppresses lint warning on unused arguments. These arguments are
+ # required by optparse, even though they are unused.
+ # pylint: disable-msg=W0613
+ def VerifyHelp(option, opt, value, parser):
+ help_called[0] = True
+
+ # Verifies that -h causes the help callback to be called.
+ help_called[0] = False
+ _, args = run_tests_util.ParseArgs(
+ 'gtest', argv=['script.py', '-h'], help_callback=VerifyHelp)
+ self.assertEqual(args, ['script.py'])
+ self.assertTrue(help_called[0])
+
+ # Verifies that --help causes the help callback to be called.
+ help_called[0] = False
+ _, args = run_tests_util.ParseArgs(
+ 'gtest', argv=['script.py', '--help'], help_callback=VerifyHelp)
+ self.assertEqual(args, ['script.py'])
+ self.assertTrue(help_called[0])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/gtest/xcode/Config/General.xcconfig b/gtest/xcode/Config/General.xcconfig
index 9fcada1..f23e322 100644
--- a/gtest/xcode/Config/General.xcconfig
+++ b/gtest/xcode/Config/General.xcconfig
@@ -17,7 +17,7 @@ ZERO_LINK = NO
PREBINDING = NO
// Strictest warning policy
-WARNING_CFLAGS = -Wall -Werror -Wendif-labels -Wnewline-eof -Wno-sign-compare
+WARNING_CFLAGS = -Wall -Werror -Wendif-labels -Wnewline-eof -Wno-sign-compare -Wshadow
// Work around Xcode bugs by using external strip. See:
// http://lists.apple.com/archives/Xcode-users/2006/Feb/msg00050.html
diff --git a/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj b/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj
index 8244910..497617e 100644
--- a/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj
+++ b/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj
@@ -6,13 +6,40 @@
objectVersion = 42;
objects = {
+/* Begin PBXAggregateTarget section */
+ 4024D162113D7D2400C7059E /* Test */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = 4024D169113D7D4600C7059E /* Build configuration list for PBXAggregateTarget "Test" */;
+ buildPhases = (
+ 4024D161113D7D2400C7059E /* ShellScript */,
+ );
+ dependencies = (
+ 4024D166113D7D3100C7059E /* PBXTargetDependency */,
+ );
+ name = Test;
+ productName = TestAndBuild;
+ };
+ 4024D1E9113D83FF00C7059E /* TestAndBuild */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = 4024D1F0113D842B00C7059E /* Build configuration list for PBXAggregateTarget "TestAndBuild" */;
+ buildPhases = (
+ );
+ dependencies = (
+ 4024D1ED113D840900C7059E /* PBXTargetDependency */,
+ 4024D1EF113D840D00C7059E /* PBXTargetDependency */,
+ );
+ name = TestAndBuild;
+ productName = TestAndBuild;
+ };
+/* End PBXAggregateTarget section */
+
/* Begin PBXBuildFile section */
3B7EB1250E5AEE3500C7F239 /* widget.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1230E5AEE3500C7F239 /* widget.cc */; };
3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B7EB1240E5AEE3500C7F239 /* widget.h */; settings = {ATTRIBUTES = (Public, ); }; };
3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */; };
3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */; };
- 408BEC281046D72200DEF522 /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 408BEC271046D72200DEF522 /* gtest.framework */; };
- 408BEC431046D7B300DEF522 /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 408BEC421046D7B300DEF522 /* libgtest_main.a */; };
+ 4024D188113D7D7800C7059E /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4024D185113D7D5500C7059E /* libgtest.a */; };
+ 4024D189113D7D7A00C7059E /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4024D183113D7D5500C7059E /* libgtest_main.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -23,6 +50,27 @@
remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
remoteInfo = gTestExample;
};
+ 4024D165113D7D3100C7059E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 3B07BDE90E3F3F9E00647869;
+ remoteInfo = WidgetFrameworkTest;
+ };
+ 4024D1EC113D840900C7059E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
+ remoteInfo = WidgetFramework;
+ };
+ 4024D1EE113D840D00C7059E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 4024D162113D7D2400C7059E;
+ remoteInfo = Test;
+ };
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
@@ -30,8 +78,9 @@
3B7EB1230E5AEE3500C7F239 /* widget.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget.cc; sourceTree = "<group>"; };
3B7EB1240E5AEE3500C7F239 /* widget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = widget.h; sourceTree = "<group>"; };
3B7EB1270E5AEE4600C7F239 /* widget_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget_test.cc; sourceTree = "<group>"; };
- 408BEC271046D72200DEF522 /* gtest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = gtest.framework; path = /Library/Frameworks/gtest.framework; sourceTree = "<absolute>"; };
- 408BEC421046D7B300DEF522 /* libgtest_main.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest_main.a; path = /Library/Frameworks/gtest.framework/Versions/A/Resources/libgtest_main.a; sourceTree = "<absolute>"; };
+ 4024D183113D7D5500C7059E /* libgtest_main.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest_main.a; path = /usr/local/lib/libgtest_main.a; sourceTree = "<absolute>"; };
+ 4024D185113D7D5500C7059E /* libgtest.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest.a; path = /usr/local/lib/libgtest.a; sourceTree = "<absolute>"; };
+ 4024D1E2113D838200C7059E /* runtests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = runtests.sh; sourceTree = "<group>"; };
8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
8D07F2C80486CC7A007CD1D0 /* Widget.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Widget.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@@ -41,9 +90,9 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 4024D189113D7D7A00C7059E /* libgtest_main.a in Frameworks */,
+ 4024D188113D7D7800C7059E /* libgtest.a in Frameworks */,
3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */,
- 408BEC281046D72200DEF522 /* gtest.framework in Frameworks */,
- 408BEC431046D7B300DEF522 /* libgtest_main.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -69,6 +118,7 @@
0867D691FE84028FC02AAC07 /* gTestExample */ = {
isa = PBXGroup;
children = (
+ 4024D1E1113D836C00C7059E /* Scripts */,
08FB77ACFE841707C02AAC07 /* Source */,
089C1665FE841158C02AAC07 /* Resources */,
3B07BE350E4094E400647869 /* Test */,
@@ -81,8 +131,8 @@
0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = {
isa = PBXGroup;
children = (
- 408BEC421046D7B300DEF522 /* libgtest_main.a */,
- 408BEC271046D72200DEF522 /* gtest.framework */,
+ 4024D183113D7D5500C7059E /* libgtest_main.a */,
+ 4024D185113D7D5500C7059E /* libgtest.a */,
);
name = "External Frameworks and Libraries";
sourceTree = "<group>";
@@ -112,6 +162,14 @@
name = Test;
sourceTree = "<group>";
};
+ 4024D1E1113D836C00C7059E /* Scripts */ = {
+ isa = PBXGroup;
+ children = (
+ 4024D1E2113D838200C7059E /* runtests.sh */,
+ );
+ name = Scripts;
+ sourceTree = "<group>";
+ };
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@@ -178,6 +236,8 @@
targets = (
8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */,
3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */,
+ 4024D162113D7D2400C7059E /* Test */,
+ 4024D1E9113D83FF00C7059E /* TestAndBuild */,
);
};
/* End PBXProject section */
@@ -202,6 +262,22 @@
};
/* End PBXRezBuildPhase section */
+/* Begin PBXShellScriptBuildPhase section */
+ 4024D161113D7D2400C7059E /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/bash $SRCROOT/runtests.sh $BUILT_PRODUCTS_DIR/WidgetFrameworkTest\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
/* Begin PBXSourcesBuildPhase section */
3B07BDE70E3F3F9E00647869 /* Sources */ = {
isa = PBXSourcesBuildPhase;
@@ -227,6 +303,21 @@
target = 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */;
targetProxy = 3B07BDF00E3F3FAE00647869 /* PBXContainerItemProxy */;
};
+ 4024D166113D7D3100C7059E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */;
+ targetProxy = 4024D165113D7D3100C7059E /* PBXContainerItemProxy */;
+ };
+ 4024D1ED113D840900C7059E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */;
+ targetProxy = 4024D1EC113D840900C7059E /* PBXContainerItemProxy */;
+ };
+ 4024D1EF113D840D00C7059E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 4024D162113D7D2400C7059E /* Test */;
+ targetProxy = 4024D1EE113D840D00C7059E /* PBXContainerItemProxy */;
+ };
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
@@ -244,6 +335,34 @@
};
name = Release;
};
+ 4024D163113D7D2400C7059E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = TestAndBuild;
+ };
+ name = Debug;
+ };
+ 4024D164113D7D2400C7059E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = TestAndBuild;
+ };
+ name = Release;
+ };
+ 4024D1EA113D83FF00C7059E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = TestAndBuild;
+ };
+ name = Debug;
+ };
+ 4024D1EB113D83FF00C7059E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = TestAndBuild;
+ };
+ name = Release;
+ };
4FADC24308B4156D00ABE55E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -296,6 +415,24 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 4024D169113D7D4600C7059E /* Build configuration list for PBXAggregateTarget "Test" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4024D163113D7D2400C7059E /* Debug */,
+ 4024D164113D7D2400C7059E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 4024D1F0113D842B00C7059E /* Build configuration list for PBXAggregateTarget "TestAndBuild" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4024D1EA113D83FF00C7059E /* Debug */,
+ 4024D1EB113D83FF00C7059E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "WidgetFramework" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/gtest/xcode/Samples/FrameworkSample/runtests.sh b/gtest/xcode/Samples/FrameworkSample/runtests.sh
new file mode 100644
index 0000000..4a0d413
--- /dev/null
+++ b/gtest/xcode/Samples/FrameworkSample/runtests.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+#
+# Copyright 2008, Google Inc.
+# All rights reserved.
+#
+# 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.
+
+# Executes the samples and tests for the Google Test Framework.
+
+# Help the dynamic linker find the path to the libraries.
+export DYLD_FRAMEWORK_PATH=$BUILT_PRODUCTS_DIR
+export DYLD_LIBRARY_PATH=$BUILT_PRODUCTS_DIR
+
+# Create some executables.
+test_executables=$@
+
+# Now execute each one in turn keeping track of how many succeeded and failed.
+succeeded=0
+failed=0
+failed_list=()
+for test in ${test_executables[*]}; do
+ "$test"
+ result=$?
+ if [ $result -eq 0 ]; then
+ succeeded=$(( $succeeded + 1 ))
+ else
+ failed=$(( failed + 1 ))
+ failed_list="$failed_list $test"
+ fi
+done
+
+# Report the successes and failures to the console.
+echo "Tests complete with $succeeded successes and $failed failures."
+if [ $failed -ne 0 ]; then
+ echo "The following tests failed:"
+ echo $failed_list
+fi
+exit $failed
diff --git a/gtest/xcode/Samples/FrameworkSample/widget.cc b/gtest/xcode/Samples/FrameworkSample/widget.cc
index d03ca00..bfc4e7f 100644
--- a/gtest/xcode/Samples/FrameworkSample/widget.cc
+++ b/gtest/xcode/Samples/FrameworkSample/widget.cc
@@ -27,7 +27,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.
//
-// Author: preston.jackson@gmail.com (Preston Jackson)
+// Author: preston.a.jackson@gmail.com (Preston Jackson)
//
// Google Test - FrameworkSample
// widget.cc
@@ -42,7 +42,7 @@ Widget::Widget(int number, const std::string& name)
name_(name) {}
Widget::~Widget() {}
-
+
float Widget::GetFloatValue() const {
return number_;
}
@@ -50,7 +50,7 @@ float Widget::GetFloatValue() const {
int Widget::GetIntValue() const {
return static_cast<int>(number_);
}
-
+
std::string Widget::GetStringValue() const {
return name_;
}
diff --git a/gtest/xcode/Samples/FrameworkSample/widget.h b/gtest/xcode/Samples/FrameworkSample/widget.h
index 59cc82c..0c55cdc 100644
--- a/gtest/xcode/Samples/FrameworkSample/widget.h
+++ b/gtest/xcode/Samples/FrameworkSample/widget.h
@@ -27,7 +27,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.
//
-// Author: preston.jackson@gmail.com (Preston Jackson)
+// Author: preston.a.jackson@gmail.com (Preston Jackson)
//
// Google Test - FrameworkSample
// widget.h
@@ -43,15 +43,15 @@ class Widget {
public:
Widget(int number, const std::string& name);
~Widget();
-
+
// Public accessors to number data
float GetFloatValue() const;
int GetIntValue() const;
-
+
// Public accessors to the string data
std::string GetStringValue() const;
void GetCharPtrValue(char* buffer, size_t max_size) const;
-
+
private:
// Data members
float number_;
diff --git a/gtest/xcode/Samples/FrameworkSample/widget_test.cc b/gtest/xcode/Samples/FrameworkSample/widget_test.cc
index 0a7c4f0..61c0d2f 100644
--- a/gtest/xcode/Samples/FrameworkSample/widget_test.cc
+++ b/gtest/xcode/Samples/FrameworkSample/widget_test.cc
@@ -27,7 +27,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.
//
-// Author: preston.jackson@gmail.com (Preston Jackson)
+// Author: preston.a.jackson@gmail.com (Preston Jackson)
//
// Google Test - FrameworkSample
// widget_test.cc
@@ -58,7 +58,7 @@ TEST(WidgetInitializerTest, TestConversion) {
char buffer[max_size];
widget.GetCharPtrValue(buffer, max_size);
EXPECT_STREQ("name", buffer);
-}
+}
// Use the Google Test main that is linked into the framework. It does something
// like this:
diff --git a/gtest/xcode/Scripts/runtests.sh b/gtest/xcode/Scripts/runtests.sh
index 9d23a77..3fc229f 100644
--- a/gtest/xcode/Scripts/runtests.sh
+++ b/gtest/xcode/Scripts/runtests.sh
@@ -1,4 +1,33 @@
#!/bin/bash
+#
+# Copyright 2008, Google Inc.
+# All rights reserved.
+#
+# 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.
# Executes the samples and tests for the Google Test Framework.
diff --git a/gtest/xcode/Scripts/versiongenerate.py b/gtest/xcode/Scripts/versiongenerate.py
index 3b19a96..81de8c9 100644..100755
--- a/gtest/xcode/Scripts/versiongenerate.py
+++ b/gtest/xcode/Scripts/versiongenerate.py
@@ -1,4 +1,33 @@
-#/usr/bin/python
+#!/usr/bin/env python
+#
+# Copyright 2008, Google Inc.
+# All rights reserved.
+#
+# 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.
"""A script to prepare version informtion for use the gtest Info.plist file.
@@ -13,7 +42,7 @@
1. The AC_INIT macro will be contained within the first 1024 characters
of configure.ac
2. The version string will be 3 integers separated by periods and will be
- surrounded by squre brackets, "[" and "]" (e.g. [1.0.1]). The first
+ surrounded by squre brackets, "[" and "]" (e.g. [1.0.1]). The first
segment represents the major version, the second represents the minor
version and the third represents the fix version.
3. No ")" character exists between the opening "(" and closing ")" of
@@ -25,7 +54,7 @@ import re
# Read the command line argument (the output directory for Version.h)
if (len(sys.argv) < 3):
- print "Usage: /usr/bin/python versiongenerate.py input_dir output_dir"
+ print "Usage: versiongenerate.py input_dir output_dir"
sys.exit(1)
else:
input_dir = sys.argv[1]
diff --git a/install-sh b/install-sh
index a5897de..377bb86 100755
--- a/install-sh
+++ b/install-sh
@@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
-scriptversion=2006-12-25.00
+scriptversion=2011-11-20.07; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@@ -35,7 +35,7 @@ scriptversion=2006-12-25.00
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
+# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
@@ -156,6 +156,10 @@ while test $# -ne 0; do
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
shift;;
-T) no_target_directory=true;;
@@ -186,6 +190,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
fi
shift # arg
dst_arg=$arg
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
done
fi
@@ -194,13 +202,17 @@ if test $# -eq 0; then
echo "$0: no input file specified." >&2
exit 1
fi
- # It's OK to call `install-sh -d' without argument.
+ # It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
- trap '(exit $?); exit' 1 2 13 15
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
@@ -228,9 +240,9 @@ fi
for src
do
- # Protect names starting with `-'.
+ # Protect names problematic for 'test' and other utilities.
case $src in
- -*) src=./$src;;
+ -* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
@@ -252,12 +264,7 @@ do
echo "$0: no destination specified." >&2
exit 1
fi
-
dst=$dst_arg
- # Protect names starting with `-'.
- case $dst in
- -*) dst=./$dst;;
- esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
@@ -347,7 +354,7 @@ do
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writeable bit of parent directory when it shouldn't.
+ # other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
@@ -385,7 +392,7 @@ do
case $dstdir in
/*) prefix='/';;
- -*) prefix='./';;
+ [-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
@@ -403,7 +410,7 @@ do
for d
do
- test -z "$d" && continue
+ test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
@@ -515,5 +522,6 @@ done
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
# End:
diff --git a/java/README.txt b/java/README.txt
index 4dfef14..b02e88b 100644
--- a/java/README.txt
+++ b/java/README.txt
@@ -101,7 +101,7 @@ extensions.
To create a jar file for the runtime and run tests invoke
"mvn package -P micro" from the <protobuf-root>/java
directory. The generated jar file is
-<protobuf-root>java/target/protobuf-java-2.2.0-micro.jar.
+<protobuf-root>java/target/protobuf-java-2.6.0-micro.jar.
If you wish to compile the MICRO_RUNTIME your self, place
the 7 files below, in <root>/com/google/protobuf and
@@ -593,6 +593,28 @@ ignore_services={true,false} (default: false)
parcelable_messages={true,false} (default: false)
Android-specific option to generate Parcelable messages.
+generate_intdefs={true,false} (default: false)
+ Android-specific option to generate @IntDef annotations for enums.
+
+ If turned on, an @IntDef annotation (a public @interface) will be
+ generated for each enum, and every integer parameter and return
+ value in the generated code meant for this enum will be annotated
+ with it. This interface is generated with the same name and at the
+ same place as the enum members' container interfaces described
+ above under enum_style=java, regardless of the enum_style option
+ used. When this is combined with enum_style=java, the interface
+ will be both the @IntDef annotation and the container of the enum
+ members; otherwise the interface has an empty body.
+
+ Your app must declare a compile-time dependency on the
+ android-support-annotations library.
+
+ For more information on how these @IntDef annotations help with
+ compile-time type safety, see:
+ https://sites.google.com/a/android.com/tools/tech-docs/support-annotations
+ and
+ https://developer.android.com/reference/android/support/annotation/IntDef.html
+
To use nano protobufs within the Android repo:
@@ -621,7 +643,7 @@ To use nano protobufs within the Android repo:
To use nano protobufs outside of Android repo:
- Link with the generated jar file
- <protobuf-root>java/target/protobuf-java-2.3.0-nano.jar.
+ <protobuf-root>java/target/protobuf-java-2.6.0-nano.jar.
- Invoke with --javanano_out, e.g.:
./protoc '--javanano_out=\
@@ -643,10 +665,10 @@ Please run the following steps to test:
- cd ../../..
- . build/envsetup.sh
- lunch 1
-- "make -j12 aprotoc libprotobuf-java-2.3.0-nano aprotoc-test-nano-params NanoAndroidTest" and
+- "make -j12 aprotoc libprotobuf-java-nano aprotoc-test-nano-params NanoAndroidTest" and
check for build errors.
- Plug in an Android device or start an emulator.
-- adb install -r out/target/product/generic/data/app/NanoAndroidTest.apk
+- adb install -r out/target/product/generic/data/app/NanoAndroidTest/NanoAndroidTest.apk
- Run:
"adb shell am instrument -w com.google.protobuf.nano.test/android.test.InstrumentationTestRunner"
and verify all tests pass.
@@ -660,4 +682,4 @@ Usage
The complete documentation for Protocol Buffers is available via the
web at:
- http://code.google.com/apis/protocolbuffers/
+ https://developers.google.com/protocol-buffers/
diff --git a/java/pom.xml b/java/pom.xml
index d263bec..f73e874 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -10,15 +10,15 @@
</parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
- <version>2.3.0</version>
- <packaging>jar</packaging>
+ <version>2.6.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>http://code.google.com/p/protobuf</url>
+ <url>https://developers.google.com/protocol-buffers/</url>
<licenses>
<license>
<name>New BSD license</name>
@@ -27,9 +27,9 @@
</license>
</licenses>
<scm>
- <url>http://code.google.com/p/protobuf/source/browse</url>
+ <url>https://github.com/google/protobuf</url>
<connection>
- scm:svn:http://protobuf.googlecode.com/svn/trunk/
+ scm:git:https://github.com/google/protobuf.git
</connection>
</scm>
<dependencies>
@@ -96,23 +96,37 @@
<configuration>
<tasks>
<mkdir dir="target/generated-test-sources" />
- <!--mkdir dir="target/generated-test-sources/opt-space" /-->
- <!--mkdir dir="target/generated-test-sources/opt-speed" /-->
<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/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" />
@@ -152,19 +166,19 @@
<arg value="../src/google/protobuf/unittest_repeated_merge_nano.proto" />
</exec>
<exec executable="../src/protoc">
- <arg value="--javanano_out=store_unknown_fields=true,generate_equals=true:target/generated-test-sources" />
+ <arg value="--javanano_out=store_unknown_fields=true,generate_equals=true,generate_clone=true:target/generated-test-sources" />
<arg value="--proto_path=../src" />
<arg value="--proto_path=src/test/java" />
<arg value="../src/google/protobuf/unittest_extension_nano.proto" />
</exec>
<exec executable="../src/protoc">
- <arg value="--javanano_out=store_unknown_fields=true,generate_equals=true:target/generated-test-sources" />
+ <arg value="--javanano_out=store_unknown_fields=true,generate_equals=true,generate_clone=true:target/generated-test-sources" />
<arg value="--proto_path=../src" />
<arg value="--proto_path=src/test/java" />
<arg value="../src/google/protobuf/unittest_extension_singular_nano.proto" />
</exec>
<exec executable="../src/protoc">
- <arg value="--javanano_out=store_unknown_fields=true,generate_equals=true:target/generated-test-sources" />
+ <arg value="--javanano_out=store_unknown_fields=true,generate_equals=true,generate_clone=true:target/generated-test-sources" />
<arg value="--proto_path=../src" />
<arg value="--proto_path=src/test/java" />
<arg value="../src/google/protobuf/unittest_extension_repeated_nano.proto" />
@@ -211,10 +225,14 @@
<arg value="--proto_path=src/test/java" />
<arg value="../src/google/protobuf/unittest_reference_types_nano.proto" />
</exec>
+ <exec executable="../src/protoc">
+ <arg value="--javanano_out=optional_field_style=reftypes_compat_mode,generate_equals=true,java_outer_classname=google/protobuf/unittest_reference_types_nano.proto|NanoReferenceTypesCompat:target/generated-test-sources" />
+ <arg value="--proto_path=../src" />
+ <arg value="--proto_path=src/test/java" />
+ <arg value="../src/google/protobuf/unittest_reference_types_nano.proto" />
+ </exec>
</tasks>
<testSourceRoot>target/generated-test-sources</testSourceRoot>
- <!--testSourceRoot>target/generated-test-sources/opt-space</testSourceRoot-->
- <!--testSourceRoot>target/generated-test-sources/opt-speed</testSourceRoot-->
</configuration>
<goals>
<goal>run</goal>
@@ -222,6 +240,18 @@
</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=2.6.1</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
</plugins>
</build>
<profiles>
@@ -240,11 +270,25 @@
<include>**/ExtensionRegistryLite.java</include>
<include>**/FieldSet.java</include>
<include>**/GeneratedMessageLite.java</include>
- <include>**/InvalidProtocolBufferException.java</include>
<include>**/Internal.java</include>
+ <include>**/InvalidProtocolBufferException.java</include>
+ <include>**/LazyStringArrayList.java</include>
+ <include>**/LazyStringList.java</include>
<include>**/MessageLite.java</include>
+ <include>**/MessageLiteOrBuilder.java</include>
+ <include>**/SmallSortedMap.java</include>
<include>**/UninitializedMessageException.java</include>
+ <include>**/UnmodifiableLazyStringList.java</include>
<include>**/WireFormat.java</include>
+ <include>**/Parser.java</include>
+ <include>**/AbstractParser.java</include>
+ <include>**/BoundedByteString.java</include>
+ <include>**/LiteralByteString.java</include>
+ <include>**/RopeByteString.java</include>
+ <include>**/Utf8.java</include>
+ <include>**/LazyField.java</include>
+ <include>**/LazyFieldLite.java</include>
+ <include>**/ProtocolStringList.java</include>
</includes>
<testIncludes>
<testInclude>**/LiteTest.java</testInclude>
diff --git a/java/src/main/java/com/google/protobuf/AbstractMessage.java b/java/src/main/java/com/google/protobuf/AbstractMessage.java
index b059bc9..ae9d5e3 100644
--- a/java/src/main/java/com/google/protobuf/AbstractMessage.java
+++ b/java/src/main/java/com/google/protobuf/AbstractMessage.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -30,12 +30,13 @@
package com.google.protobuf;
-import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.OneofDescriptor;
+import com.google.protobuf.Internal.EnumLite;
-import java.io.InputStream;
import java.io.IOException;
-import java.util.ArrayList;
+import java.io.InputStream;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -47,37 +48,30 @@ import java.util.Map;
*/
public abstract class AbstractMessage extends AbstractMessageLite
implements Message {
- @SuppressWarnings("unchecked")
public boolean isInitialized() {
- // Check that all required fields are present.
- for (final FieldDescriptor field : getDescriptorForType().getFields()) {
- if (field.isRequired()) {
- if (!hasField(field)) {
- return false;
- }
- }
- }
+ return MessageReflection.isInitialized(this);
+ }
- // Check that embedded messages are initialized.
- for (final Map.Entry<FieldDescriptor, Object> entry :
- getAllFields().entrySet()) {
- final FieldDescriptor field = entry.getKey();
- if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
- if (field.isRepeated()) {
- for (final Message element : (List<Message>) entry.getValue()) {
- if (!element.isInitialized()) {
- return false;
- }
- }
- } else {
- if (!((Message) entry.getValue()).isInitialized()) {
- return false;
- }
- }
- }
- }
- return true;
+ public List<String> findInitializationErrors() {
+ return MessageReflection.findMissingFields(this);
+ }
+
+ public String getInitializationErrorString() {
+ return MessageReflection.delimitWithCommas(findInitializationErrors());
+ }
+
+ /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+ @Override
+ public boolean hasOneof(OneofDescriptor oneof) {
+ throw new UnsupportedOperationException("hasOneof() is not implemented.");
+ }
+
+ /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+ @Override
+ public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
+ throw new UnsupportedOperationException(
+ "getOneofFieldDescriptor() is not implemented.");
}
@Override
@@ -86,28 +80,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
}
public void writeTo(final CodedOutputStream output) throws IOException {
- final boolean isMessageSet =
- getDescriptorForType().getOptions().getMessageSetWireFormat();
-
- for (final Map.Entry<FieldDescriptor, Object> entry :
- getAllFields().entrySet()) {
- final FieldDescriptor field = entry.getKey();
- final Object value = entry.getValue();
- if (isMessageSet && field.isExtension() &&
- field.getType() == FieldDescriptor.Type.MESSAGE &&
- !field.isRepeated()) {
- output.writeMessageSetExtension(field.getNumber(), (Message) value);
- } else {
- FieldSet.writeField(field, value, output);
- }
- }
-
- final UnknownFieldSet unknownFields = getUnknownFields();
- if (isMessageSet) {
- unknownFields.writeAsMessageSetTo(output);
- } else {
- unknownFields.writeTo(output);
- }
+ MessageReflection.writeMessageTo(this, output, false);
}
private int memoizedSize = -1;
@@ -118,33 +91,8 @@ public abstract class AbstractMessage extends AbstractMessageLite
return size;
}
- size = 0;
- final boolean isMessageSet =
- getDescriptorForType().getOptions().getMessageSetWireFormat();
-
- for (final Map.Entry<FieldDescriptor, Object> entry :
- getAllFields().entrySet()) {
- final FieldDescriptor field = entry.getKey();
- final Object value = entry.getValue();
- if (isMessageSet && field.isExtension() &&
- field.getType() == FieldDescriptor.Type.MESSAGE &&
- !field.isRepeated()) {
- size += CodedOutputStream.computeMessageSetExtensionSize(
- field.getNumber(), (Message) value);
- } else {
- size += FieldSet.computeFieldSize(field, value);
- }
- }
-
- final UnknownFieldSet unknownFields = getUnknownFields();
- if (isMessageSet) {
- size += unknownFields.getSerializedSizeAsMessageSet();
- } else {
- size += unknownFields.getSerializedSize();
- }
-
- memoizedSize = size;
- return size;
+ memoizedSize = MessageReflection.getSerializedSize(this);
+ return memoizedSize;
}
@Override
@@ -159,18 +107,117 @@ public abstract class AbstractMessage extends AbstractMessageLite
if (getDescriptorForType() != otherMessage.getDescriptorForType()) {
return false;
}
- return getAllFields().equals(otherMessage.getAllFields()) &&
+ return compareFields(getAllFields(), otherMessage.getAllFields()) &&
getUnknownFields().equals(otherMessage.getUnknownFields());
}
@Override
public int hashCode() {
- int hash = 41;
- hash = (19 * hash) + getDescriptorForType().hashCode();
- hash = (53 * hash) + getAllFields().hashCode();
- hash = (29 * hash) + getUnknownFields().hashCode();
+ int hash = memoizedHashCode;
+ if (hash == 0) {
+ hash = 41;
+ hash = (19 * hash) + getDescriptorForType().hashCode();
+ hash = hashFields(hash, getAllFields());
+ hash = (29 * hash) + getUnknownFields().hashCode();
+ memoizedHashCode = hash;
+ }
return hash;
}
+
+ private static ByteString toByteString(Object value) {
+ if (value instanceof byte[]) {
+ return ByteString.copyFrom((byte[]) value);
+ } else {
+ return (ByteString) value;
+ }
+ }
+
+ /**
+ * Compares two bytes fields. The parameters must be either a byte array or a
+ * ByteString object. They can be of different type though.
+ */
+ private static boolean compareBytes(Object a, Object b) {
+ if (a instanceof byte[] && b instanceof byte[]) {
+ return Arrays.equals((byte[])a, (byte[])b);
+ }
+ return toByteString(a).equals(toByteString(b));
+ }
+
+ /**
+ * Compares two set of fields.
+ * This method is used to implement {@link AbstractMessage#equals(Object)}
+ * and {@link AbstractMutableMessage#equals(Object)}. It takes special care
+ * of bytes fields because immutable messages and mutable messages use
+ * different Java type to reprensent a bytes field and this method should be
+ * able to compare immutable messages, mutable messages and also an immutable
+ * message to a mutable message.
+ */
+ static boolean compareFields(Map<FieldDescriptor, Object> a,
+ Map<FieldDescriptor, Object> b) {
+ if (a.size() != b.size()) {
+ return false;
+ }
+ for (FieldDescriptor descriptor : a.keySet()) {
+ if (!b.containsKey(descriptor)) {
+ return false;
+ }
+ Object value1 = a.get(descriptor);
+ Object value2 = b.get(descriptor);
+ if (descriptor.getType() == FieldDescriptor.Type.BYTES) {
+ if (descriptor.isRepeated()) {
+ List list1 = (List) value1;
+ List list2 = (List) value2;
+ if (list1.size() != list2.size()) {
+ return false;
+ }
+ for (int i = 0; i < list1.size(); i++) {
+ if (!compareBytes(list1.get(i), list2.get(i))) {
+ return false;
+ }
+ }
+ } else {
+ // Compares a singular bytes field.
+ if (!compareBytes(value1, value2)) {
+ return false;
+ }
+ }
+ } else {
+ // Compare non-bytes fields.
+ if (!value1.equals(value2)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /** Get a hash code for given fields and values, using the given seed. */
+ @SuppressWarnings("unchecked")
+ protected static int hashFields(int hash, Map<FieldDescriptor, Object> map) {
+ for (Map.Entry<FieldDescriptor, Object> entry : map.entrySet()) {
+ FieldDescriptor field = entry.getKey();
+ Object value = entry.getValue();
+ hash = (37 * hash) + field.getNumber();
+ if (field.getType() != FieldDescriptor.Type.ENUM){
+ hash = (53 * hash) + value.hashCode();
+ } else if (field.isRepeated()) {
+ List<? extends EnumLite> list = (List<? extends EnumLite>) value;
+ hash = (53 * hash) + Internal.hashEnumList(list);
+ } else {
+ hash = (53 * hash) + Internal.hashEnum((EnumLite) value);
+ }
+ }
+ return hash;
+ }
+
+ /**
+ * Package private helper method for AbstractParser to create
+ * UninitializedMessageException with missing field information.
+ */
+ @Override
+ UninitializedMessageException newUninitializedMessageException() {
+ return Builder.newUninitializedMessageException(this);
+ }
// =================================================================
@@ -187,6 +234,25 @@ public abstract class AbstractMessage extends AbstractMessageLite
@Override
public abstract BuilderType clone();
+ /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+ @Override
+ public boolean hasOneof(OneofDescriptor oneof) {
+ throw new UnsupportedOperationException("hasOneof() is not implemented.");
+ }
+
+ /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+ @Override
+ public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
+ throw new UnsupportedOperationException(
+ "getOneofFieldDescriptor() is not implemented.");
+ }
+
+ /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+ @Override
+ public BuilderType clearOneof(OneofDescriptor oneof) {
+ throw new UnsupportedOperationException("clearOneof() is not implemented.");
+ }
+
public BuilderType clear() {
for (final Map.Entry<FieldDescriptor, Object> entry :
getAllFields().entrySet()) {
@@ -195,6 +261,14 @@ public abstract class AbstractMessage extends AbstractMessageLite
return (BuilderType) this;
}
+ public List<String> findInitializationErrors() {
+ return MessageReflection.findMissingFields(this);
+ }
+
+ public String getInitializationErrorString() {
+ return MessageReflection.delimitWithCommas(findInitializationErrors());
+ }
+
public BuilderType mergeFrom(final Message other) {
if (other.getDescriptorForType() != getDescriptorForType()) {
throw new IllegalArgumentException(
@@ -257,8 +331,13 @@ public abstract class AbstractMessage extends AbstractMessageLite
break;
}
- if (!mergeFieldFrom(input, unknownFields, extensionRegistry,
- this, tag)) {
+ MessageReflection.BuilderAdapter builderAdapter =
+ new MessageReflection.BuilderAdapter(this);
+ if (!MessageReflection.mergeFieldFrom(input, unknownFields,
+ extensionRegistry,
+ getDescriptorForType(),
+ builderAdapter,
+ tag)) {
// end group tag
break;
}
@@ -267,272 +346,6 @@ public abstract class AbstractMessage extends AbstractMessageLite
return (BuilderType) this;
}
- /**
- * Like {@link #mergeFrom(CodedInputStream, UnknownFieldSet.Builder,
- * ExtensionRegistryLite, Message.Builder)}, but parses a single field.
- * Package-private because it is used by GeneratedMessage.ExtendableMessage.
- * @param tag The tag, which should have already been read.
- * @return {@code true} unless the tag is an end-group tag.
- */
- @SuppressWarnings("unchecked")
- static boolean mergeFieldFrom(
- final CodedInputStream input,
- final UnknownFieldSet.Builder unknownFields,
- final ExtensionRegistryLite extensionRegistry,
- final Message.Builder builder,
- final int tag) throws IOException {
- final Descriptor type = builder.getDescriptorForType();
-
- if (type.getOptions().getMessageSetWireFormat() &&
- tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
- mergeMessageSetExtensionFromCodedStream(
- input, unknownFields, extensionRegistry, builder);
- return true;
- }
-
- final int wireType = WireFormat.getTagWireType(tag);
- final int fieldNumber = WireFormat.getTagFieldNumber(tag);
-
- final FieldDescriptor field;
- Message defaultInstance = null;
-
- if (type.isExtensionNumber(fieldNumber)) {
- // extensionRegistry may be either ExtensionRegistry or
- // ExtensionRegistryLite. Since the type we are parsing is a full
- // message, only a full ExtensionRegistry could possibly contain
- // extensions of it. Otherwise we will treat the registry as if it
- // were empty.
- if (extensionRegistry instanceof ExtensionRegistry) {
- final ExtensionRegistry.ExtensionInfo extension =
- ((ExtensionRegistry) extensionRegistry)
- .findExtensionByNumber(type, fieldNumber);
- if (extension == null) {
- field = null;
- } else {
- field = extension.descriptor;
- defaultInstance = extension.defaultInstance;
- if (defaultInstance == null &&
- field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
- throw new IllegalStateException(
- "Message-typed extension lacked default instance: " +
- field.getFullName());
- }
- }
- } else {
- field = null;
- }
- } else {
- field = type.findFieldByNumber(fieldNumber);
- }
-
- boolean unknown = false;
- boolean packed = false;
- if (field == null) {
- unknown = true; // Unknown field.
- } else if (wireType == FieldSet.getWireFormatForFieldType(
- field.getLiteType(),
- false /* isPacked */)) {
- packed = false;
- } else if (field.isPackable() &&
- wireType == FieldSet.getWireFormatForFieldType(
- field.getLiteType(),
- true /* isPacked */)) {
- packed = true;
- } else {
- unknown = true; // Unknown wire type.
- }
-
- if (unknown) { // Unknown field or wrong wire type. Skip.
- return unknownFields.mergeFieldFrom(tag, input);
- }
-
- if (packed) {
- final int length = input.readRawVarint32();
- final int limit = input.pushLimit(length);
- if (field.getLiteType() == WireFormat.FieldType.ENUM) {
- while (input.getBytesUntilLimit() > 0) {
- final int rawValue = input.readEnum();
- final Object value = field.getEnumType().findValueByNumber(rawValue);
- if (value == null) {
- // If the number isn't recognized as a valid value for this
- // enum, drop it (don't even add it to unknownFields).
- return true;
- }
- builder.addRepeatedField(field, value);
- }
- } else {
- while (input.getBytesUntilLimit() > 0) {
- final Object value =
- FieldSet.readPrimitiveField(input, field.getLiteType());
- builder.addRepeatedField(field, value);
- }
- }
- input.popLimit(limit);
- } else {
- final Object value;
- switch (field.getType()) {
- case GROUP: {
- final Message.Builder subBuilder;
- if (defaultInstance != null) {
- subBuilder = defaultInstance.newBuilderForType();
- } else {
- subBuilder = builder.newBuilderForField(field);
- }
- if (!field.isRepeated()) {
- subBuilder.mergeFrom((Message) builder.getField(field));
- }
- input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
- value = subBuilder.build();
- break;
- }
- case MESSAGE: {
- final Message.Builder subBuilder;
- if (defaultInstance != null) {
- subBuilder = defaultInstance.newBuilderForType();
- } else {
- subBuilder = builder.newBuilderForField(field);
- }
- if (!field.isRepeated()) {
- subBuilder.mergeFrom((Message) builder.getField(field));
- }
- input.readMessage(subBuilder, extensionRegistry);
- value = subBuilder.build();
- break;
- }
- case ENUM:
- final int rawValue = input.readEnum();
- value = field.getEnumType().findValueByNumber(rawValue);
- // If the number isn't recognized as a valid value for this enum,
- // drop it.
- if (value == null) {
- unknownFields.mergeVarintField(fieldNumber, rawValue);
- return true;
- }
- break;
- default:
- value = FieldSet.readPrimitiveField(input, field.getLiteType());
- break;
- }
-
- if (field.isRepeated()) {
- builder.addRepeatedField(field, value);
- } else {
- builder.setField(field, value);
- }
- }
-
- return true;
- }
-
- /** Called by {@code #mergeFieldFrom()} to parse a MessageSet extension. */
- private static void mergeMessageSetExtensionFromCodedStream(
- final CodedInputStream input,
- final UnknownFieldSet.Builder unknownFields,
- final ExtensionRegistryLite extensionRegistry,
- final Message.Builder builder) throws IOException {
- final Descriptor type = builder.getDescriptorForType();
-
- // The wire format for MessageSet is:
- // message MessageSet {
- // repeated group Item = 1 {
- // required int32 typeId = 2;
- // required bytes message = 3;
- // }
- // }
- // "typeId" is the extension's field number. The extension can only be
- // a message type, where "message" contains the encoded bytes of that
- // message.
- //
- // In practice, we will probably never see a MessageSet item in which
- // the message appears before the type ID, or where either field does not
- // appear exactly once. However, in theory such cases are valid, so we
- // should be prepared to accept them.
-
- int typeId = 0;
- ByteString rawBytes = null; // If we encounter "message" before "typeId"
- Message.Builder subBuilder = null;
- FieldDescriptor field = null;
-
- while (true) {
- final int tag = input.readTag();
- if (tag == 0) {
- break;
- }
-
- if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
- typeId = input.readUInt32();
- // Zero is not a valid type ID.
- if (typeId != 0) {
- final ExtensionRegistry.ExtensionInfo extension;
-
- // extensionRegistry may be either ExtensionRegistry or
- // ExtensionRegistryLite. Since the type we are parsing is a full
- // message, only a full ExtensionRegistry could possibly contain
- // extensions of it. Otherwise we will treat the registry as if it
- // were empty.
- if (extensionRegistry instanceof ExtensionRegistry) {
- extension = ((ExtensionRegistry) extensionRegistry)
- .findExtensionByNumber(type, typeId);
- } else {
- extension = null;
- }
-
- if (extension != null) {
- field = extension.descriptor;
- subBuilder = extension.defaultInstance.newBuilderForType();
- final Message originalMessage = (Message)builder.getField(field);
- if (originalMessage != null) {
- subBuilder.mergeFrom(originalMessage);
- }
- if (rawBytes != null) {
- // We already encountered the message. Parse it now.
- subBuilder.mergeFrom(
- CodedInputStream.newInstance(rawBytes.newInput()));
- rawBytes = null;
- }
- } else {
- // Unknown extension number. If we already saw data, put it
- // in rawBytes.
- if (rawBytes != null) {
- unknownFields.mergeField(typeId,
- UnknownFieldSet.Field.newBuilder()
- .addLengthDelimited(rawBytes)
- .build());
- rawBytes = null;
- }
- }
- }
- } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
- if (typeId == 0) {
- // We haven't seen a type ID yet, so we have to store the raw bytes
- // for now.
- rawBytes = input.readBytes();
- } else if (subBuilder == null) {
- // We don't know how to parse this. Ignore it.
- unknownFields.mergeField(typeId,
- UnknownFieldSet.Field.newBuilder()
- .addLengthDelimited(input.readBytes())
- .build());
- } else {
- // We already know the type, so we can parse directly from the input
- // with no copying. Hooray!
- input.readMessage(subBuilder, extensionRegistry);
- }
- } else {
- // Unknown tag. Skip it.
- if (!input.skipField(tag)) {
- break; // end of group
- }
- }
- }
-
- input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG);
-
- if (subBuilder != null) {
- builder.setField(field, subBuilder.build());
- }
- }
-
public BuilderType mergeUnknownFields(final UnknownFieldSet unknownFields) {
setUnknownFields(
UnknownFieldSet.newBuilder(getUnknownFields())
@@ -541,78 +354,23 @@ public abstract class AbstractMessage extends AbstractMessageLite
return (BuilderType) this;
}
+ public Message.Builder getFieldBuilder(final FieldDescriptor field) {
+ throw new UnsupportedOperationException(
+ "getFieldBuilder() called on an unsupported message type.");
+ }
+
+ public String toString() {
+ return TextFormat.printToString(this);
+ }
+
/**
* Construct an UninitializedMessageException reporting missing fields in
* the given message.
*/
protected static UninitializedMessageException
newUninitializedMessageException(Message message) {
- return new UninitializedMessageException(findMissingFields(message));
- }
-
- /**
- * Populates {@code this.missingFields} with the full "path" of each
- * missing required field in the given message.
- */
- private static List<String> findMissingFields(final Message message) {
- final List<String> results = new ArrayList<String>();
- findMissingFields(message, "", results);
- return results;
- }
-
- /** Recursive helper implementing {@link #findMissingFields(Message)}. */
- private static void findMissingFields(final Message message,
- final String prefix,
- final List<String> results) {
- for (final FieldDescriptor field :
- message.getDescriptorForType().getFields()) {
- if (field.isRequired() && !message.hasField(field)) {
- results.add(prefix + field.getName());
- }
- }
-
- for (final Map.Entry<FieldDescriptor, Object> entry :
- message.getAllFields().entrySet()) {
- final FieldDescriptor field = entry.getKey();
- final Object value = entry.getValue();
-
- if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
- if (field.isRepeated()) {
- int i = 0;
- for (final Object element : (List) value) {
- findMissingFields((Message) element,
- subMessagePrefix(prefix, field, i++),
- results);
- }
- } else {
- if (message.hasField(field)) {
- findMissingFields((Message) value,
- subMessagePrefix(prefix, field, -1),
- results);
- }
- }
- }
- }
- }
-
- private static String subMessagePrefix(final String prefix,
- final FieldDescriptor field,
- final int index) {
- final StringBuilder result = new StringBuilder(prefix);
- if (field.isExtension()) {
- result.append('(')
- .append(field.getFullName())
- .append(')');
- } else {
- result.append(field.getName());
- }
- if (index != -1) {
- result.append('[')
- .append(index)
- .append(']');
- }
- result.append('.');
- return result.toString();
+ return new UninitializedMessageException(
+ MessageReflection.findMissingFields(message));
}
// ===============================================================
@@ -704,6 +462,5 @@ public abstract class AbstractMessage extends AbstractMessageLite
throws IOException {
return super.mergeDelimitedFrom(input, extensionRegistry);
}
-
}
}
diff --git a/java/src/main/java/com/google/protobuf/AbstractMessageLite.java b/java/src/main/java/com/google/protobuf/AbstractMessageLite.java
index 9210d85..aac4fa7 100644
--- a/java/src/main/java/com/google/protobuf/AbstractMessageLite.java
+++ b/java/src/main/java/com/google/protobuf/AbstractMessageLite.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -44,6 +44,8 @@ import java.util.Collection;
* @author kenton@google.com Kenton Varda
*/
public abstract class AbstractMessageLite implements MessageLite {
+ protected int memoizedHashCode = 0;
+
public ByteString toByteString() {
try {
final ByteString.CodedBuilder out =
@@ -91,6 +93,22 @@ public abstract class AbstractMessageLite implements MessageLite {
codedOutput.flush();
}
+
+ /**
+ * Package private helper method for AbstractParser to create
+ * UninitializedMessageException.
+ */
+ UninitializedMessageException newUninitializedMessageException() {
+ return new UninitializedMessageException(this);
+ }
+
+ protected static void checkByteStringIsUtf8(ByteString byteString)
+ throws IllegalArgumentException {
+ if (!byteString.isValidUtf8()) {
+ throw new IllegalArgumentException("Byte string is not UTF-8.");
+ }
+ }
+
/**
* A partial implementation of the {@link Message.Builder} interface which
* implements as many methods of that interface as possible in terms of
@@ -303,24 +321,35 @@ public abstract class AbstractMessageLite implements MessageLite {
* used by generated code. Users should ignore it.
*
* @throws NullPointerException if any of the elements of {@code values} is
- * null.
+ * null. When that happens, some elements of {@code values} may have already
+ * been added to the result {@code list}.
*/
protected static <T> void addAll(final Iterable<T> values,
final Collection<? super T> list) {
- for (final T value : values) {
- if (value == null) {
- throw new NullPointerException();
- }
- }
- if (values instanceof Collection) {
- @SuppressWarnings("unsafe") final
- Collection<T> collection = (Collection<T>) values;
- list.addAll(collection);
+ if (values instanceof LazyStringList) {
+ // For StringOrByteStringLists, check the underlying elements to avoid
+ // forcing conversions of ByteStrings to Strings.
+ checkForNullValues(((LazyStringList) values).getUnderlyingElements());
+ list.addAll((Collection<T>) values);
+ } else if (values instanceof Collection) {
+ checkForNullValues(values);
+ list.addAll((Collection<T>) values);
} else {
for (final T value : values) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
list.add(value);
}
}
}
+
+ private static void checkForNullValues(final Iterable<?> values) {
+ for (final Object value : values) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ }
+ }
}
}
diff --git a/java/src/main/java/com/google/protobuf/AbstractParser.java b/java/src/main/java/com/google/protobuf/AbstractParser.java
new file mode 100644
index 0000000..1a4c631
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/AbstractParser.java
@@ -0,0 +1,253 @@
+// 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.AbstractMessageLite.Builder.LimitedInputStream;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A partial implementation of the {@link Parser} interface which implements
+ * as many methods of that interface as possible in terms of other methods.
+ *
+ * Note: This class implements all the convenience methods in the
+ * {@link Parser} interface. See {@link Parser} for related javadocs.
+ * Subclasses need to implement
+ * {@link Parser#parsePartialFrom(CodedInputStream, ExtensionRegistryLite)}
+ *
+ * @author liujisi@google.com (Pherl Liu)
+ */
+public abstract class AbstractParser<MessageType extends MessageLite>
+ implements Parser<MessageType> {
+ /**
+ * Creates an UninitializedMessageException for MessageType.
+ */
+ private UninitializedMessageException
+ newUninitializedMessageException(MessageType message) {
+ if (message instanceof AbstractMessageLite) {
+ return ((AbstractMessageLite) message).newUninitializedMessageException();
+ }
+ return new UninitializedMessageException(message);
+ }
+
+ /**
+ * Helper method to check if message is initialized.
+ *
+ * @throws InvalidProtocolBufferException if it is not initialized.
+ * @return The message to check.
+ */
+ private MessageType checkMessageInitialized(MessageType message)
+ throws InvalidProtocolBufferException {
+ if (message != null && !message.isInitialized()) {
+ throw newUninitializedMessageException(message)
+ .asInvalidProtocolBufferException()
+ .setUnfinishedMessage(message);
+ }
+ return message;
+ }
+
+ private static final ExtensionRegistryLite EMPTY_REGISTRY
+ = ExtensionRegistryLite.getEmptyRegistry();
+
+ public MessageType parsePartialFrom(CodedInputStream input)
+ throws InvalidProtocolBufferException {
+ return parsePartialFrom(input, EMPTY_REGISTRY);
+ }
+
+ public MessageType parseFrom(CodedInputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(
+ parsePartialFrom(input, extensionRegistry));
+ }
+
+ public MessageType parseFrom(CodedInputStream input)
+ throws InvalidProtocolBufferException {
+ return parseFrom(input, EMPTY_REGISTRY);
+ }
+
+ public MessageType parsePartialFrom(ByteString data,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ MessageType message;
+ try {
+ CodedInputStream input = data.newCodedInput();
+ message = parsePartialFrom(input, extensionRegistry);
+ try {
+ input.checkLastTagWas(0);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(message);
+ }
+ return message;
+ } catch (InvalidProtocolBufferException e) {
+ throw e;
+ }
+ }
+
+ public MessageType parsePartialFrom(ByteString data)
+ throws InvalidProtocolBufferException {
+ return parsePartialFrom(data, EMPTY_REGISTRY);
+ }
+
+ public MessageType parseFrom(ByteString data,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(parsePartialFrom(data, extensionRegistry));
+ }
+
+ public MessageType parseFrom(ByteString data)
+ throws InvalidProtocolBufferException {
+ return parseFrom(data, EMPTY_REGISTRY);
+ }
+
+ public MessageType parsePartialFrom(byte[] data, int off, int len,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ try {
+ CodedInputStream input = CodedInputStream.newInstance(data, off, len);
+ MessageType message = parsePartialFrom(input, extensionRegistry);
+ try {
+ input.checkLastTagWas(0);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(message);
+ }
+ return message;
+ } catch (InvalidProtocolBufferException e) {
+ throw e;
+ }
+ }
+
+ 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)
+ throws InvalidProtocolBufferException {
+ return parsePartialFrom(data, 0, data.length, extensionRegistry);
+ }
+
+ 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)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(
+ parsePartialFrom(data, off, len, extensionRegistry));
+ }
+
+ 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)
+ throws InvalidProtocolBufferException {
+ return parseFrom(data, 0, data.length, extensionRegistry);
+ }
+
+ public MessageType parseFrom(byte[] data)
+ throws InvalidProtocolBufferException {
+ return parseFrom(data, EMPTY_REGISTRY);
+ }
+
+ public MessageType parsePartialFrom(InputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ CodedInputStream codedInput = CodedInputStream.newInstance(input);
+ MessageType message = parsePartialFrom(codedInput, extensionRegistry);
+ try {
+ codedInput.checkLastTagWas(0);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(message);
+ }
+ return message;
+ }
+
+ public MessageType parsePartialFrom(InputStream input)
+ throws InvalidProtocolBufferException {
+ return parsePartialFrom(input, EMPTY_REGISTRY);
+ }
+
+ public MessageType parseFrom(InputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(
+ parsePartialFrom(input, extensionRegistry));
+ }
+
+ public MessageType parseFrom(InputStream input)
+ throws InvalidProtocolBufferException {
+ return parseFrom(input, EMPTY_REGISTRY);
+ }
+
+ public MessageType parsePartialDelimitedFrom(
+ 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);
+ return parsePartialFrom(limitedInput, extensionRegistry);
+ }
+
+ public MessageType parsePartialDelimitedFrom(InputStream input)
+ throws InvalidProtocolBufferException {
+ return parsePartialDelimitedFrom(input, EMPTY_REGISTRY);
+ }
+
+ public MessageType parseDelimitedFrom(
+ InputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(
+ parsePartialDelimitedFrom(input, extensionRegistry));
+ }
+
+ public MessageType parseDelimitedFrom(InputStream input)
+ throws InvalidProtocolBufferException {
+ return parseDelimitedFrom(input, EMPTY_REGISTRY);
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java b/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java
index 1e81143..d535efb 100644
--- a/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java
+++ b/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/java/src/main/java/com/google/protobuf/BlockingService.java b/java/src/main/java/com/google/protobuf/BlockingService.java
index ecc8009..d01f0b8 100644
--- a/java/src/main/java/com/google/protobuf/BlockingService.java
+++ b/java/src/main/java/com/google/protobuf/BlockingService.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/java/src/main/java/com/google/protobuf/BoundedByteString.java b/java/src/main/java/com/google/protobuf/BoundedByteString.java
new file mode 100644
index 0000000..2828e9c
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/BoundedByteString.java
@@ -0,0 +1,163 @@
+// 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.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);
+ }
+
+ // =================================================================
+ // 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/ByteString.java b/java/src/main/java/com/google/protobuf/ByteString.java
index 5fade03..7da5612 100644
--- a/java/src/main/java/com/google/protobuf/ByteString.java
+++ b/java/src/main/java/com/google/protobuf/ByteString.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -30,140 +30,426 @@
package com.google.protobuf;
-import java.io.InputStream;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.io.FilterOutputStream;
+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.Collection;
+import java.util.Iterator;
import java.util.List;
+import java.util.NoSuchElementException;
/**
- * Immutable array of bytes.
+ * Immutable sequence of bytes. Substring is supported by sharing the reference
+ * to the immutable underlying bytes, as with {@link String}. Concatenation is
+ * likewise supported without copying (long strings) by building a tree of
+ * pieces in {@link RopeByteString}.
+ * <p>
+ * Like {@link String}, the contents of a {@link ByteString} can never be
+ * observed to change, not even in the presence of a data race or incorrect
+ * API usage in the client code.
*
* @author crazybob@google.com Bob Lee
* @author kenton@google.com Kenton Varda
+ * @author carlanton@google.com Carl Haverl
+ * @author martinrb@google.com Martin Buchholz
*/
-public final class ByteString {
- private final byte[] bytes;
+public abstract class ByteString implements Iterable<Byte> {
- private ByteString(final byte[] bytes) {
- this.bytes = bytes;
- }
+ /**
+ * When two strings to be concatenated have a combined length shorter than
+ * this, we just copy their bytes on {@link #concat(ByteString)}.
+ * The trade-off is copy size versus the overhead of creating tree nodes
+ * in {@link RopeByteString}.
+ */
+ static final int CONCATENATE_BY_COPY_SIZE = 128;
+
+ /**
+ * When copying an InputStream into a ByteString with .readFrom(),
+ * the chunks in the underlying rope start at 256 bytes, but double
+ * each iteration up to 8192 bytes.
+ */
+ static final int MIN_READ_FROM_CHUNK_SIZE = 0x100; // 256b
+ static final int MAX_READ_FROM_CHUNK_SIZE = 0x2000; // 8k
/**
- * Gets the byte at the given index.
+ * Empty {@code ByteString}.
+ */
+ public static final ByteString EMPTY = new LiteralByteString(new byte[0]);
+
+ // This constructor is here to prevent subclassing outside of this package,
+ ByteString() {}
+
+ /**
+ * Gets the byte at the given index. This method should be used only for
+ * random access to individual bytes. To access bytes sequentially, use the
+ * {@link ByteIterator} returned by {@link #iterator()}, and call {@link
+ * #substring(int, int)} first if necessary.
*
+ * @param index index of byte
+ * @return the value
* @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size
*/
- public byte byteAt(final int index) {
- return bytes[index];
+ public abstract byte byteAt(int index);
+
+ /**
+ * Return a {@link ByteString.ByteIterator} over the bytes in the ByteString.
+ * To avoid auto-boxing, you may get the iterator manually and call
+ * {@link ByteIterator#nextByte()}.
+ *
+ * @return the iterator
+ */
+ public abstract ByteIterator iterator();
+
+ /**
+ * This interface extends {@code Iterator<Byte>}, so that we can return an
+ * unboxed {@code byte}.
+ */
+ public interface ByteIterator extends Iterator<Byte> {
+ /**
+ * An alternative to {@link Iterator#next()} that returns an
+ * unboxed primitive {@code byte}.
+ *
+ * @return the next {@code byte} in the iteration
+ * @throws NoSuchElementException if the iteration has no more elements
+ */
+ byte nextByte();
}
/**
* Gets the number of bytes.
+ *
+ * @return size in bytes
*/
- public int size() {
- return bytes.length;
- }
+ public abstract int size();
/**
* Returns {@code true} if the size is {@code 0}, {@code false} otherwise.
+ *
+ * @return true if this is zero bytes long
*/
public boolean isEmpty() {
- return bytes.length == 0;
+ return size() == 0;
}
// =================================================================
- // byte[] -> ByteString
+ // ByteString -> substring
+
+ /**
+ * Return the substring from {@code beginIndex}, inclusive, to the end of the
+ * string.
+ *
+ * @param beginIndex start at this index
+ * @return substring sharing underlying data
+ * @throws IndexOutOfBoundsException if {@code beginIndex < 0} or
+ * {@code beginIndex > size()}.
+ */
+ public ByteString substring(int beginIndex) {
+ return substring(beginIndex, size());
+ }
+
+ /**
+ * Return the substring from {@code beginIndex}, inclusive, to {@code
+ * endIndex}, exclusive.
+ *
+ * @param beginIndex start at this index
+ * @param endIndex the last character is the one before this index
+ * @return substring sharing underlying data
+ * @throws IndexOutOfBoundsException if {@code beginIndex < 0},
+ * {@code endIndex > size()}, or {@code beginIndex > endIndex}.
+ */
+ public abstract ByteString substring(int beginIndex, int endIndex);
/**
- * Empty ByteString.
+ * Tests if this bytestring starts with the specified prefix.
+ * Similar to {@link String#startsWith(String)}
+ *
+ * @param prefix the prefix.
+ * @return <code>true</code> if the byte sequence represented by the
+ * argument is a prefix of the byte sequence represented by
+ * this string; <code>false</code> otherwise.
*/
- public static final ByteString EMPTY = new ByteString(new byte[0]);
+ public boolean startsWith(ByteString prefix) {
+ return size() >= prefix.size() &&
+ substring(0, prefix.size()).equals(prefix);
+ }
+
+ /**
+ * Tests if this bytestring ends with the specified suffix.
+ * Similar to {@link String#endsWith(String)}
+ *
+ * @param suffix the suffix.
+ * @return <code>true</code> if the byte sequence represented by the
+ * argument is a suffix of the byte sequence represented by
+ * this string; <code>false</code> otherwise.
+ */
+ public boolean endsWith(ByteString suffix) {
+ return size() >= suffix.size() &&
+ substring(size() - suffix.size()).equals(suffix);
+ }
+
+ // =================================================================
+ // byte[] -> ByteString
/**
* Copies the given bytes into a {@code ByteString}.
+ *
+ * @param bytes source array
+ * @param offset offset in source array
+ * @param size number of bytes to copy
+ * @return new {@code ByteString}
*/
- public static ByteString copyFrom(final byte[] bytes, final int offset,
- final int size) {
- final byte[] copy = new byte[size];
+ public static ByteString copyFrom(byte[] bytes, int offset, int size) {
+ byte[] copy = new byte[size];
System.arraycopy(bytes, offset, copy, 0, size);
- return new ByteString(copy);
+ return new LiteralByteString(copy);
}
/**
* Copies the given bytes into a {@code ByteString}.
+ *
+ * @param bytes to copy
+ * @return new {@code ByteString}
*/
- public static ByteString copyFrom(final byte[] bytes) {
+ public static ByteString copyFrom(byte[] bytes) {
return copyFrom(bytes, 0, bytes.length);
}
/**
- * Copies {@code size} bytes from a {@code java.nio.ByteBuffer} into
+ * Copies the next {@code size} bytes from a {@code java.nio.ByteBuffer} into
* a {@code ByteString}.
+ *
+ * @param bytes source buffer
+ * @param size number of bytes to copy
+ * @return new {@code ByteString}
*/
- public static ByteString copyFrom(final ByteBuffer bytes, final int size) {
- final byte[] copy = new byte[size];
+ public static ByteString copyFrom(ByteBuffer bytes, int size) {
+ byte[] copy = new byte[size];
bytes.get(copy);
- return new ByteString(copy);
+ return new LiteralByteString(copy);
}
/**
* Copies the remaining bytes from a {@code java.nio.ByteBuffer} into
* a {@code ByteString}.
+ *
+ * @param bytes sourceBuffer
+ * @return new {@code ByteString}
*/
- public static ByteString copyFrom(final ByteBuffer bytes) {
+ public static ByteString copyFrom(ByteBuffer bytes) {
return copyFrom(bytes, bytes.remaining());
}
/**
* Encodes {@code text} into a sequence of bytes using the named charset
* and returns the result as a {@code ByteString}.
+ *
+ * @param text source string
+ * @param charsetName encoding to use
+ * @return new {@code ByteString}
+ * @throws UnsupportedEncodingException if the encoding isn't found
*/
- public static ByteString copyFrom(final String text, final String charsetName)
+ public static ByteString copyFrom(String text, String charsetName)
throws UnsupportedEncodingException {
- return new ByteString(text.getBytes(charsetName));
+ return new LiteralByteString(text.getBytes(charsetName));
}
/**
* Encodes {@code text} into a sequence of UTF-8 bytes and returns the
* result as a {@code ByteString}.
+ *
+ * @param text source string
+ * @return new {@code ByteString}
*/
- public static ByteString copyFromUtf8(final String text) {
+ public static ByteString copyFromUtf8(String text) {
try {
- return new ByteString(text.getBytes("UTF-8"));
+ return new LiteralByteString(text.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("UTF-8 not supported?", e);
}
}
+ // =================================================================
+ // InputStream -> ByteString
+
+ /**
+ * Completely reads the given stream's bytes into a
+ * {@code ByteString}, blocking if necessary until all bytes are
+ * read through to the end of the stream.
+ *
+ * <b>Performance notes:</b> The returned {@code ByteString} is an
+ * 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. If the caller knows the precise length of
+ * the stream and wishes to avoid all unnecessary copies and
+ * allocations, consider using the two-argument version of this
+ * method, below.
+ *
+ * @param streamToDrain The source stream, which is read completely
+ * but not closed.
+ * @return A new {@code ByteString} which is made up of chunks of
+ * various sizes, depending on the behavior of the underlying
+ * stream.
+ * @throws IOException IOException is thrown if there is a problem
+ * reading the underlying stream.
+ */
+ public static ByteString readFrom(InputStream streamToDrain)
+ throws IOException {
+ return readFrom(
+ streamToDrain, MIN_READ_FROM_CHUNK_SIZE, MAX_READ_FROM_CHUNK_SIZE);
+ }
+
+ /**
+ * Completely reads the given stream's bytes into a
+ * {@code ByteString}, blocking if necessary until all bytes are
+ * read through to the end of the stream.
+ *
+ * <b>Performance notes:</b> The returned {@code ByteString} is an
+ * immutable tree of byte arrays ("chunks") of the stream data. The
+ * chunkSize parameter sets the size of these byte arrays. In
+ * particular, if the chunkSize is precisely the same as the length
+ * of the stream, unnecessary allocations and copies will be
+ * avoided. Otherwise, the chunks will be of the given size, except
+ * for the last chunk, which will be resized (via a reallocation and
+ * copy) to contain the remainder of the stream.
+ *
+ * @param streamToDrain The source stream, which is read completely
+ * but not closed.
+ * @param chunkSize The size of the chunks in which to read the
+ * stream.
+ * @return A new {@code ByteString} which is made up of chunks of
+ * the given size.
+ * @throws IOException IOException is thrown if there is a problem
+ * reading the underlying stream.
+ */
+ public static ByteString readFrom(InputStream streamToDrain, int chunkSize)
+ throws IOException {
+ return readFrom(streamToDrain, chunkSize, chunkSize);
+ }
+
+ // Helper method that takes the chunk size range as a parameter.
+ public static ByteString readFrom(InputStream streamToDrain, int minChunkSize,
+ int maxChunkSize) throws IOException {
+ Collection<ByteString> results = new ArrayList<ByteString>();
+
+ // copy the inbound bytes into a list of chunks; the chunk size
+ // grows exponentially to support both short and long streams.
+ int chunkSize = minChunkSize;
+ while (true) {
+ ByteString chunk = readChunk(streamToDrain, chunkSize);
+ if (chunk == null) {
+ break;
+ }
+ results.add(chunk);
+ chunkSize = Math.min(chunkSize * 2, maxChunkSize);
+ }
+
+ return ByteString.copyFrom(results);
+ }
+
+ /**
+ * Blocks until a chunk of the given size can be made from the
+ * stream, or EOF is reached. Calls read() repeatedly in case the
+ * given stream implementation doesn't completely fill the given
+ * buffer in one read() call.
+ *
+ * @return A chunk of the desired size, or else a chunk as large as
+ * was available when end of stream was reached. Returns null if the
+ * given stream had no more data in it.
+ */
+ private static ByteString readChunk(InputStream in, final int chunkSize)
+ throws IOException {
+ final byte[] buf = new byte[chunkSize];
+ int bytesRead = 0;
+ while (bytesRead < chunkSize) {
+ final int count = in.read(buf, bytesRead, chunkSize - bytesRead);
+ if (count == -1) {
+ break;
+ }
+ bytesRead += count;
+ }
+
+ if (bytesRead == 0) {
+ return null;
+ } else {
+ return ByteString.copyFrom(buf, 0, bytesRead);
+ }
+ }
+
+ // =================================================================
+ // Multiple ByteStrings -> One ByteString
+
+ /**
+ * Concatenate the given {@code ByteString} to this one. Short concatenations,
+ * of total size smaller than {@link ByteString#CONCATENATE_BY_COPY_SIZE}, are
+ * produced by copying the underlying bytes (as per Rope.java, <a
+ * href="http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf">
+ * BAP95 </a>. In general, the concatenate involves no copying.
+ *
+ * @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) {
+ throw new IllegalArgumentException("ByteString would be too long: " +
+ thisSize + "+" + otherSize);
+ }
+
+ return RopeByteString.concatenate(this, other);
+ }
+
/**
- * Concatenates all byte strings in the list and returns the result.
+ * Concatenates all byte strings in the iterable and returns the result.
+ * This is designed to run in O(list size), not O(total bytes).
*
* <p>The returned {@code ByteString} is not necessarily a unique object.
* If the list is empty, the returned object is the singleton empty
* {@code ByteString}. If the list has only one element, that
* {@code ByteString} will be returned without copying.
+ *
+ * @param byteStrings strings to be concatenated
+ * @return new {@code ByteString}
*/
- public static ByteString copyFrom(List<ByteString> list) {
- if (list.size() == 0) {
- return EMPTY;
- } else if (list.size() == 1) {
- return list.get(0);
+ public static ByteString copyFrom(Iterable<ByteString> byteStrings) {
+ Collection<ByteString> collection;
+ if (!(byteStrings instanceof Collection)) {
+ collection = new ArrayList<ByteString>();
+ for (ByteString byteString : byteStrings) {
+ collection.add(byteString);
+ }
+ } else {
+ collection = (Collection<ByteString>) byteStrings;
}
-
- int size = 0;
- for (ByteString str : list) {
- size += str.size();
+ ByteString result;
+ if (collection.isEmpty()) {
+ result = EMPTY;
+ } else {
+ result = balancedConcat(collection.iterator(), collection.size());
}
- byte[] bytes = new byte[size];
- int pos = 0;
- for (ByteString str : list) {
- System.arraycopy(str.bytes, 0, bytes, pos, str.size());
- pos += str.size();
+ return result;
+ }
+
+ // 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) {
+ assert length >= 1;
+ ByteString result;
+ if (length == 1) {
+ result = iterator.next();
+ } else {
+ int halfLength = length >>> 1;
+ ByteString left = balancedConcat(iterator, halfLength);
+ ByteString right = balancedConcat(iterator, length - halfLength);
+ result = left.concat(right);
}
- return new ByteString(bytes);
+ return result;
}
// =================================================================
@@ -174,194 +460,493 @@ public final class ByteString {
*
* @param target buffer to copy into
* @param offset in the target buffer
+ * @throws IndexOutOfBoundsException if the offset is negative or too large
*/
- public void copyTo(final byte[] target, final int offset) {
- System.arraycopy(bytes, 0, target, offset, bytes.length);
+ public void copyTo(byte[] target, int offset) {
+ copyTo(target, 0, offset, size());
}
/**
* Copies bytes into a buffer.
*
- * @param target buffer to copy into
+ * @param target buffer to copy into
* @param sourceOffset offset within these bytes
* @param targetOffset offset within the target buffer
- * @param size number of bytes to copy
+ * @param numberToCopy number of bytes to copy
+ * @throws IndexOutOfBoundsException if an offset or size is negative or too
+ * large
*/
- public void copyTo(final byte[] target, final int sourceOffset,
- final int targetOffset,
- final int size) {
- System.arraycopy(bytes, sourceOffset, target, targetOffset, size);
+ public 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));
+ }
+ if (numberToCopy > 0) {
+ copyToInternal(target, sourceOffset, targetOffset, numberToCopy);
+ }
}
/**
+ * Internal (package private) implementation of
+ * @link{#copyTo(byte[],int,int,int}.
+ * It assumes that all error checking has already been performed and that
+ * @code{numberToCopy > 0}.
+ */
+ protected abstract void copyToInternal(byte[] target, int sourceOffset,
+ int targetOffset, int numberToCopy);
+
+ /**
+ * Copies bytes into a ByteBuffer.
+ *
+ * @param target ByteBuffer to copy into.
+ * @throws java.nio.ReadOnlyBufferException if the {@code target} is read-only
+ * @throws java.nio.BufferOverflowException if the {@code target}'s
+ * remaining() space is not large enough to hold the data.
+ */
+ public abstract void copyTo(ByteBuffer target);
+
+ /**
* Copies bytes to a {@code byte[]}.
+ *
+ * @return copied bytes
*/
public byte[] toByteArray() {
- final int size = bytes.length;
- final byte[] copy = new byte[size];
- System.arraycopy(bytes, 0, copy, 0, size);
- return copy;
+ int size = size();
+ if (size == 0) {
+ return Internal.EMPTY_BYTE_ARRAY;
+ }
+ byte[] result = new byte[size];
+ copyToInternal(result, 0, 0, size);
+ return result;
}
/**
- * Constructs a new read-only {@code java.nio.ByteBuffer} with the
- * same backing byte array.
+ * Writes the complete 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.
*/
- public ByteBuffer asReadOnlyByteBuffer() {
- final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
- return byteBuffer.asReadOnlyBuffer();
+ public abstract void writeTo(OutputStream out) throws IOException;
+
+ /**
+ * Writes a specified part of this byte string to an output stream.
+ *
+ * @param out the output stream to which to write the data.
+ * @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
+ */
+ 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));
+ }
+ 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;
+
+ /**
+ * Constructs a read-only {@code java.nio.ByteBuffer} whose content
+ * is equal to the contents of this byte string.
+ * The result uses the same backing array as the byte string, if possible.
+ *
+ * @return wrapped bytes
+ */
+ public abstract ByteBuffer asReadOnlyByteBuffer();
+
+ /**
+ * Constructs a list of read-only {@code java.nio.ByteBuffer} objects
+ * such that the concatenation of their contents is equal to the contents
+ * of this byte string. The result uses the same backing arrays as the
+ * byte string.
+ * <p>
+ * By returning a list, implementations of this method may be able to avoid
+ * copying even when there are multiple backing arrays.
+ *
+ * @return a list of wrapped bytes
+ */
+ public abstract List<ByteBuffer> asReadOnlyByteBufferList();
+
+ /**
* Constructs a new {@code String} by decoding the bytes using the
* specified charset.
+ *
+ * @param charsetName encode using this charset
+ * @return new string
+ * @throws UnsupportedEncodingException if charset isn't recognized
*/
- public String toString(final String charsetName)
- throws UnsupportedEncodingException {
- return new String(bytes, charsetName);
- }
+ public abstract String toString(String charsetName)
+ throws UnsupportedEncodingException;
+
+ // =================================================================
+ // UTF-8 decoding
/**
* Constructs a new {@code String} by decoding the bytes as UTF-8.
+ *
+ * @return new string using UTF-8 encoding
*/
public String toStringUtf8() {
try {
- return new String(bytes, "UTF-8");
+ return toString("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("UTF-8 not supported?", e);
}
}
+ /**
+ * Tells whether this {@code ByteString} represents a well-formed UTF-8
+ * byte sequence, such that the original bytes can be converted to a
+ * String object and then round tripped back to bytes without loss.
+ *
+ * <p>More precisely, returns {@code true} whenever: <pre> {@code
+ * Arrays.equals(byteString.toByteArray(),
+ * new String(byteString.toByteArray(), "UTF-8").getBytes("UTF-8"))
+ * }</pre>
+ *
+ * <p>This method returns {@code false} for "overlong" byte sequences,
+ * as well as for 3-byte sequences that would map to a surrogate
+ * character, in accordance with the restricted definition of UTF-8
+ * introduced in Unicode 3.1. 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
+ * character byte sequences.
+ *
+ * <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>.
+ *
+ * @return whether the bytes in this {@code ByteString} are a
+ * well-formed UTF-8 byte sequence
+ */
+ public abstract boolean isValidUtf8();
+
+ /**
+ * Tells whether the given byte sequence is a well-formed, malformed, or
+ * incomplete UTF-8 byte sequence. This method accepts and returns a partial
+ * state result, allowing the bytes for a complete UTF-8 byte sequence to be
+ * composed from multiple {@code ByteString} segments.
+ *
+ * @param state either {@code 0} (if this is the initial decoding operation)
+ * or the value returned from a call to a partial decoding method for the
+ * previous bytes
+ * @param offset offset of the first byte to check
+ * @param length number of bytes to check
+ *
+ * @return {@code -1} if the partial byte sequence is definitely malformed,
+ * {@code 0} 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.
+ */
+ protected abstract int partialIsValidUtf8(int state, int offset, int length);
+
// =================================================================
// equals() and hashCode()
@Override
- public boolean equals(final Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof ByteString)) {
- return false;
- }
-
- final ByteString other = (ByteString) o;
- final int size = bytes.length;
- if (size != other.bytes.length) {
- return false;
- }
-
- final byte[] thisBytes = bytes;
- final byte[] otherBytes = other.bytes;
- for (int i = 0; i < size; i++) {
- if (thisBytes[i] != otherBytes[i]) {
- return false;
- }
- }
-
- return true;
- }
-
- private volatile int hash = 0;
+ public abstract boolean equals(Object o);
+ /**
+ * Return a non-zero hashCode depending only on the sequence of bytes
+ * in this ByteString.
+ *
+ * @return hashCode value for this object
+ */
@Override
- public int hashCode() {
- int h = hash;
-
- if (h == 0) {
- final byte[] thisBytes = bytes;
- final int size = bytes.length;
-
- h = size;
- for (int i = 0; i < size; i++) {
- h = h * 31 + thisBytes[i];
- }
- if (h == 0) {
- h = 1;
- }
-
- hash = h;
- }
-
- return h;
- }
+ public abstract int hashCode();
// =================================================================
// Input stream
/**
* Creates an {@code InputStream} which can be used to read the bytes.
+ * <p>
+ * The {@link InputStream} returned by this method is guaranteed to be
+ * completely non-blocking. The method {@link InputStream#available()}
+ * returns the number of bytes remaining in the stream. The methods
+ * {@link InputStream#read(byte[]), {@link InputStream#read(byte[],int,int)}
+ * and {@link InputStream#skip(long)} will read/skip as many bytes as are
+ * available.
+ * <p>
+ * The methods in the returned {@link InputStream} might <b>not</b> be
+ * thread safe.
+ *
+ * @return an input stream that returns the bytes of this byte string.
*/
- public InputStream newInput() {
- return new ByteArrayInputStream(bytes);
- }
+ public abstract InputStream newInput();
/**
* Creates a {@link CodedInputStream} which can be used to read the bytes.
- * Using this is more efficient than creating a {@link CodedInputStream}
- * wrapping the result of {@link #newInput()}.
+ * Using this is often more efficient than creating a {@link CodedInputStream}
+ * that wraps the result of {@link #newInput()}.
+ *
+ * @return stream based on wrapped data
*/
- public CodedInputStream newCodedInput() {
- // We trust CodedInputStream not to modify the bytes, or to give anyone
- // else access to them.
- return CodedInputStream.newInstance(bytes);
- }
+ public abstract CodedInputStream newCodedInput();
// =================================================================
// Output stream
/**
- * Creates a new {@link Output} with the given initial capacity.
+ * Creates a new {@link Output} with the given initial capacity. Call {@link
+ * Output#toByteString()} to create the {@code ByteString} instance.
+ * <p>
+ * A {@link ByteString.Output} offers the same functionality as a
+ * {@link ByteArrayOutputStream}, except that it returns a {@link ByteString}
+ * rather than a {@code byte} array.
+ *
+ * @param initialCapacity estimate of number of bytes to be written
+ * @return {@code OutputStream} for building a {@code ByteString}
*/
- public static Output newOutput(final int initialCapacity) {
- return new Output(new ByteArrayOutputStream(initialCapacity));
+ public static Output newOutput(int initialCapacity) {
+ return new Output(initialCapacity);
}
/**
- * Creates a new {@link Output}.
+ * Creates a new {@link Output}. Call {@link Output#toByteString()} to create
+ * the {@code ByteString} instance.
+ * <p>
+ * A {@link ByteString.Output} offers the same functionality as a
+ * {@link ByteArrayOutputStream}, except that it returns a {@link ByteString}
+ * rather than a {@code byte array}.
+ *
+ * @return {@code OutputStream} for building a {@code ByteString}
*/
public static Output newOutput() {
- return newOutput(32);
+ return new Output(CONCATENATE_BY_COPY_SIZE);
}
/**
* Outputs to a {@code ByteString} instance. Call {@link #toByteString()} to
* create the {@code ByteString} instance.
*/
- public static final class Output extends FilterOutputStream {
- private final ByteArrayOutputStream bout;
+ public static final class Output extends OutputStream {
+ // Implementation note.
+ // The public methods of this class must be synchronized. ByteStrings
+ // are guaranteed to be immutable. Without some sort of locking, it could
+ // be possible for one thread to call toByteSring(), while another thread
+ // is still modifying the underlying byte array.
+
+ private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+ // argument passed by user, indicating initial capacity.
+ private final int initialCapacity;
+ // ByteStrings to be concatenated to create the result
+ private final ArrayList<ByteString> flushedBuffers;
+ // Total number of bytes in the ByteStrings of flushedBuffers
+ private int flushedBuffersTotalBytes;
+ // Current buffer to which we are writing
+ private byte[] buffer;
+ // Location in buffer[] to which we write the next byte.
+ private int bufferPos;
/**
- * Constructs a new output with the given initial capacity.
+ * Creates a new ByteString output stream with the specified
+ * initial capacity.
+ *
+ * @param initialCapacity the initial capacity of the output stream.
*/
- private Output(final ByteArrayOutputStream bout) {
- super(bout);
- this.bout = bout;
+ Output(int initialCapacity) {
+ if (initialCapacity < 0) {
+ throw new IllegalArgumentException("Buffer size < 0");
+ }
+ this.initialCapacity = initialCapacity;
+ this.flushedBuffers = new ArrayList<ByteString>();
+ this.buffer = new byte[initialCapacity];
+ }
+
+ @Override
+ public synchronized void write(int b) {
+ if (bufferPos == buffer.length) {
+ flushFullBuffer(1);
+ }
+ buffer[bufferPos++] = (byte)b;
+ }
+
+ @Override
+ public synchronized void write(byte[] b, int offset, int length) {
+ if (length <= buffer.length - bufferPos) {
+ // The bytes can fit into the current buffer.
+ System.arraycopy(b, offset, buffer, bufferPos, length);
+ bufferPos += length;
+ } else {
+ // Use up the current buffer
+ int copySize = buffer.length - bufferPos;
+ System.arraycopy(b, offset, buffer, bufferPos, copySize);
+ offset += copySize;
+ length -= copySize;
+ // Flush the buffer, and get a new buffer at least big enough to cover
+ // what we still need to output
+ flushFullBuffer(length);
+ System.arraycopy(b, offset, buffer, 0 /* count */, length);
+ bufferPos = length;
+ }
}
/**
- * Creates a {@code ByteString} instance from this {@code Output}.
+ * Creates a byte string. Its size is the current size of this output
+ * stream and its output has been copied to it.
+ *
+ * @return the current contents of this output stream, as a byte string.
*/
- public ByteString toByteString() {
- final byte[] byteArray = bout.toByteArray();
- return new ByteString(byteArray);
+ public synchronized ByteString toByteString() {
+ flushLastBuffer();
+ return ByteString.copyFrom(flushedBuffers);
+ }
+
+ /**
+ * Implement java.util.Arrays.copyOf() for jdk 1.5.
+ */
+ private byte[] copyArray(byte[] buffer, int length) {
+ byte[] result = new byte[length];
+ System.arraycopy(buffer, 0, result, 0, Math.min(buffer.length, length));
+ return result;
+ }
+
+ /**
+ * Writes the complete contents of this byte array output stream 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.
+ */
+ public void writeTo(OutputStream out) throws IOException {
+ ByteString[] cachedFlushBuffers;
+ byte[] cachedBuffer;
+ int cachedBufferPos;
+ synchronized (this) {
+ // Copy the information we need into local variables so as to hold
+ // the lock for as short a time as possible.
+ cachedFlushBuffers =
+ flushedBuffers.toArray(new ByteString[flushedBuffers.size()]);
+ cachedBuffer = buffer;
+ cachedBufferPos = bufferPos;
+ }
+ for (ByteString byteString : cachedFlushBuffers) {
+ byteString.writeTo(out);
+ }
+
+ out.write(copyArray(cachedBuffer, cachedBufferPos));
+ }
+
+ /**
+ * Returns the current size of the output stream.
+ *
+ * @return the current size of the output stream
+ */
+ public synchronized int size() {
+ return flushedBuffersTotalBytes + bufferPos;
+ }
+
+ /**
+ * Resets this stream, so that all currently accumulated output in the
+ * output stream is discarded. The output stream can be used again,
+ * reusing the already allocated buffer space.
+ */
+ public synchronized void reset() {
+ flushedBuffers.clear();
+ flushedBuffersTotalBytes = 0;
+ bufferPos = 0;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("<ByteString.Output@%s size=%d>",
+ Integer.toHexString(System.identityHashCode(this)), size());
+ }
+
+ /**
+ * Internal function used by writers. The current buffer is full, and the
+ * writer needs a new buffer whose size is at least the specified minimum
+ * size.
+ */
+ private void flushFullBuffer(int minSize) {
+ flushedBuffers.add(new LiteralByteString(buffer));
+ flushedBuffersTotalBytes += buffer.length;
+ // We want to increase our total capacity by 50%, but as a minimum,
+ // the new buffer should also at least be >= minSize and
+ // >= initial Capacity.
+ int newSize = Math.max(initialCapacity,
+ Math.max(minSize, flushedBuffersTotalBytes >>> 1));
+ buffer = new byte[newSize];
+ bufferPos = 0;
+ }
+
+ /**
+ * Internal function used by {@link #toByteString()}. The current buffer may
+ * or may not be full, but it needs to be flushed.
+ */
+ private void flushLastBuffer() {
+ if (bufferPos < buffer.length) {
+ if (bufferPos > 0) {
+ byte[] bufferCopy = copyArray(buffer, bufferPos);
+ flushedBuffers.add(new LiteralByteString(bufferCopy));
+ }
+ // We reuse this buffer for further writes.
+ } else {
+ // Buffer is completely full. Huzzah.
+ flushedBuffers.add(new LiteralByteString(buffer));
+ // 99% of the time, we're not going to use this OutputStream again.
+ // We set buffer to an empty byte stream so that we're handling this
+ // case without wasting space. In the rare case that more writes
+ // *do* occur, this empty buffer will be flushed and an appropriately
+ // sized new buffer will be created.
+ buffer = EMPTY_BYTE_ARRAY;
+ }
+ flushedBuffersTotalBytes += bufferPos;
+ bufferPos = 0;
}
}
/**
- * Constructs a new ByteString builder, which allows you to efficiently
- * construct a {@code ByteString} by writing to a {@link CodedOutputStream}.
- * Using this is much more efficient than calling {@code newOutput()} and
- * wrapping that in a {@code CodedOutputStream}.
+ * Constructs a new {@code ByteString} builder, which allows you to
+ * efficiently construct a {@code ByteString} by writing to a {@link
+ * CodedOutputStream}. Using this is much more efficient than calling {@code
+ * newOutput()} and wrapping that in a {@code CodedOutputStream}.
*
* <p>This is package-private because it's a somewhat confusing interface.
* Users can call {@link Message#toByteString()} instead of calling this
* directly.
*
- * @param size The target byte size of the {@code ByteString}. You must
- * write exactly this many bytes before building the result.
+ * @param size The target byte size of the {@code ByteString}. You must write
+ * exactly this many bytes before building the result.
+ * @return the builder
*/
- static CodedBuilder newCodedBuilder(final int size) {
+ static CodedBuilder newCodedBuilder(int size) {
return new CodedBuilder(size);
}
@@ -370,7 +955,7 @@ public final class ByteString {
private final CodedOutputStream output;
private final byte[] buffer;
- private CodedBuilder(final int size) {
+ private CodedBuilder(int size) {
buffer = new byte[size];
output = CodedOutputStream.newInstance(buffer);
}
@@ -381,11 +966,57 @@ public final class ByteString {
// We can be confident that the CodedOutputStream will not modify the
// underlying bytes anymore because it already wrote all of them. So,
// no need to make a copy.
- return new ByteString(buffer);
+ return new LiteralByteString(buffer);
}
public CodedOutputStream getCodedOutput() {
return output;
}
}
+
+ // =================================================================
+ // Methods {@link RopeByteString} needs on instances, which aren't part of the
+ // public API.
+
+ /**
+ * Return the depth of the tree representing this {@code ByteString}, if any,
+ * whose root is this node. If this is a leaf node, return 0.
+ *
+ * @return tree depth or zero
+ */
+ protected abstract int getTreeDepth();
+
+ /**
+ * Return {@code true} if this ByteString is literal (a leaf node) or a
+ * flat-enough tree in the sense of {@link RopeByteString}.
+ *
+ * @return true if the tree is flat enough
+ */
+ protected abstract boolean isBalanced();
+
+ /**
+ * Return the cached hash code if available.
+ *
+ * @return value of cached hash code or 0 if not computed yet
+ */
+ protected abstract int peekCachedHashCode();
+
+ /**
+ * Compute the hash across the value bytes starting with the given hash, and
+ * return the result. This is used to compute the hash across strings
+ * represented as a set of pieces by allowing the hash computation to be
+ * continued from piece to piece.
+ *
+ * @param h starting hash value
+ * @param offset offset into this value to start looking at data values
+ * @param length number of data values to include in the hash computation
+ * @return ending hash value
+ */
+ protected abstract int partialHash(int h, int offset, int length);
+
+ @Override
+ public String toString() {
+ return String.format("<ByteString@%s size=%d>",
+ Integer.toHexString(System.identityHashCode(this)), size());
+ }
}
diff --git a/java/src/main/java/com/google/protobuf/CodedInputStream.java b/java/src/main/java/com/google/protobuf/CodedInputStream.java
index 22995e9..a00ae86 100644
--- a/java/src/main/java/com/google/protobuf/CodedInputStream.java
+++ b/java/src/main/java/com/google/protobuf/CodedInputStream.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -30,9 +30,12 @@
package com.google.protobuf;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
@@ -67,7 +70,72 @@ public final class CodedInputStream {
*/
public static CodedInputStream newInstance(final byte[] buf, final int off,
final int len) {
- return new CodedInputStream(buf, off, len);
+ CodedInputStream result = new CodedInputStream(buf, off, len);
+ 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(len);
+ } 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;
+ }
+
+ /**
+ * Create a new CodedInputStream wrapping the given ByteBuffer. The data
+ * starting from the ByteBuffer's current position to its limit will be read.
+ * The returned CodedInputStream may or may not share the underlying data
+ * in the ByteBuffer, therefore the ByteBuffer cannot be changed while the
+ * CodedInputStream is in use.
+ * Note that the ByteBuffer's position won't be changed by this function.
+ * Concurrent calls with the same ByteBuffer object are safe if no other
+ * thread is trying to alter the ByteBuffer's status.
+ */
+ public static CodedInputStream newInstance(ByteBuffer buf) {
+ if (buf.hasArray()) {
+ return newInstance(buf.array(), buf.arrayOffset() + buf.position(),
+ buf.remaining());
+ } else {
+ ByteBuffer temp = buf.duplicate();
+ byte[] buffer = new byte[temp.remaining()];
+ temp.get(buffer);
+ return newInstance(buffer);
+ }
+ }
+
+ /**
+ * 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;
}
// -----------------------------------------------------------------
@@ -107,6 +175,10 @@ public final class CodedInputStream {
}
}
+ public int getLastTag() {
+ return lastTag;
+ }
+
/**
* Reads and discards a single field, given its tag value.
*
@@ -116,10 +188,10 @@ public final class CodedInputStream {
public boolean skipField(final int tag) throws IOException {
switch (WireFormat.getTagWireType(tag)) {
case WireFormat.WIRETYPE_VARINT:
- readInt32();
+ skipRawVarint();
return true;
case WireFormat.WIRETYPE_FIXED64:
- readRawLittleEndian64();
+ skipRawBytes(8);
return true;
case WireFormat.WIRETYPE_LENGTH_DELIMITED:
skipRawBytes(readRawVarint32());
@@ -133,7 +205,7 @@ public final class CodedInputStream {
case WireFormat.WIRETYPE_END_GROUP:
return false;
case WireFormat.WIRETYPE_FIXED32:
- readRawLittleEndian32();
+ skipRawBytes(4);
return true;
default:
throw InvalidProtocolBufferException.invalidWireType();
@@ -141,6 +213,57 @@ public final class CodedInputStream {
}
/**
+ * Reads a single field and writes it to output in wire format,
+ * given its tag value.
+ *
+ * @return {@code false} if the tag is an endgroup tag, in which case
+ * nothing is skipped. Otherwise, returns {@code true}.
+ */
+ public boolean skipField(final int tag, final CodedOutputStream output)
+ throws IOException {
+ switch (WireFormat.getTagWireType(tag)) {
+ case WireFormat.WIRETYPE_VARINT: {
+ long value = readInt64();
+ output.writeRawVarint32(tag);
+ output.writeUInt64NoTag(value);
+ return true;
+ }
+ case WireFormat.WIRETYPE_FIXED64: {
+ long value = readRawLittleEndian64();
+ output.writeRawVarint32(tag);
+ output.writeFixed64NoTag(value);
+ return true;
+ }
+ case WireFormat.WIRETYPE_LENGTH_DELIMITED: {
+ ByteString value = readBytes();
+ output.writeRawVarint32(tag);
+ output.writeBytesNoTag(value);
+ return true;
+ }
+ case WireFormat.WIRETYPE_START_GROUP: {
+ output.writeRawVarint32(tag);
+ skipMessage(output);
+ int endtag = WireFormat.makeTag(WireFormat.getTagFieldNumber(tag),
+ WireFormat.WIRETYPE_END_GROUP);
+ checkLastTagWas(endtag);
+ output.writeRawVarint32(endtag);
+ return true;
+ }
+ case WireFormat.WIRETYPE_END_GROUP: {
+ return false;
+ }
+ case WireFormat.WIRETYPE_FIXED32: {
+ int value = readRawLittleEndian32();
+ output.writeRawVarint32(tag);
+ output.writeFixed32NoTag(value);
+ return true;
+ }
+ default:
+ throw InvalidProtocolBufferException.invalidWireType();
+ }
+ }
+
+ /**
* Reads and discards an entire message. This will read either until EOF
* or until an endgroup tag, whichever comes first.
*/
@@ -153,6 +276,51 @@ public final class CodedInputStream {
}
}
+ /**
+ * Reads an entire message and writes it to output in wire format.
+ * This will read either until EOF or until an endgroup tag,
+ * whichever comes first.
+ */
+ public void skipMessage(CodedOutputStream output) throws IOException {
+ while (true) {
+ final int tag = readTag();
+ if (tag == 0 || !skipField(tag, output)) {
+ return;
+ }
+ }
+ }
+
+ /**
+ * Collects the bytes skipped and returns the data in a ByteBuffer.
+ */
+ private class SkippedDataSink implements RefillCallback {
+ private int lastPos = bufferPos;
+ private ByteArrayOutputStream byteArrayStream;
+
+ @Override
+ public void onRefill() {
+ if (byteArrayStream == null) {
+ byteArrayStream = new ByteArrayOutputStream();
+ }
+ byteArrayStream.write(buffer, lastPos, bufferPos - lastPos);
+ lastPos = 0;
+ }
+
+ /**
+ * Gets skipped data in a ByteBuffer. This method should only be
+ * called once.
+ */
+ ByteBuffer getSkippedData() {
+ if (byteArrayStream == null) {
+ return ByteBuffer.wrap(buffer, lastPos, bufferPos - lastPos);
+ } else {
+ byteArrayStream.write(buffer, lastPos, bufferPos);
+ return ByteBuffer.wrap(byteArrayStream.toByteArray());
+ }
+ }
+ }
+
+
// -----------------------------------------------------------------
/** Read a {@code double} field value from the stream. */
@@ -192,10 +360,14 @@ public final class CodedInputStream {
/** Read a {@code bool} field value from the stream. */
public boolean readBool() throws IOException {
- return readRawVarint32() != 0;
+ return readRawVarint64() != 0;
}
- /** Read a {@code string} field value from the stream. */
+ /**
+ * Read a {@code string} field value from the stream.
+ * If the stream contains malformed UTF-8,
+ * replace the offending bytes with the standard UTF-8 replacement character.
+ */
public String readString() throws IOException {
final int size = readRawVarint32();
if (size <= (bufferSize - bufferPos) && size > 0) {
@@ -204,10 +376,40 @@ public final class CodedInputStream {
final String result = new String(buffer, bufferPos, size, "UTF-8");
bufferPos += size;
return result;
+ } else if (size == 0) {
+ return "";
} else {
// Slow path: Build a byte array first then copy it.
- return new String(readRawBytes(size), "UTF-8");
+ return new String(readRawBytesSlowPath(size), "UTF-8");
+ }
+ }
+
+ /**
+ * Read a {@code string} field value from the stream.
+ * If the stream contains malformed UTF-8,
+ * throw exception {@link InvalidProtocolBufferException}.
+ */
+ public String readStringRequireUtf8() throws IOException {
+ final int size = readRawVarint32();
+ final byte[] bytes;
+ int pos = bufferPos;
+ if (size <= (bufferSize - pos) && size > 0) {
+ // Fast path: We already have the bytes in a contiguous buffer, so
+ // just copy directly from it.
+ bytes = buffer;
+ bufferPos = pos + size;
+ } else if (size == 0) {
+ return "";
+ } else {
+ // Slow path: Build a byte array first then copy it.
+ bytes = readRawBytesSlowPath(size);
+ pos = 0;
+ }
+ // TODO(martinrb): We could save a pass by validating while decoding.
+ if (!Utf8.isValidUtf8(bytes, pos, pos + size)) {
+ throw InvalidProtocolBufferException.invalidUtf8();
}
+ return new String(bytes, pos, size, "UTF-8");
}
/** Read a {@code group} field value from the stream. */
@@ -225,6 +427,24 @@ public final class CodedInputStream {
--recursionDepth;
}
+
+ /** Read a {@code group} field value from the stream. */
+ public <T extends MessageLite> T readGroup(
+ final int fieldNumber,
+ final Parser<T> parser,
+ final ExtensionRegistryLite extensionRegistry)
+ throws IOException {
+ if (recursionDepth >= recursionLimit) {
+ throw InvalidProtocolBufferException.recursionLimitExceeded();
+ }
+ ++recursionDepth;
+ T result = parser.parsePartialFrom(this, extensionRegistry);
+ checkLastTagWas(
+ WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
+ --recursionDepth;
+ return result;
+ }
+
/**
* Reads a {@code group} field value from the stream and merges it into the
* given {@link UnknownFieldSet}.
@@ -260,18 +480,80 @@ public final class CodedInputStream {
popLimit(oldLimit);
}
+
+ /** Read an embedded message field value from the stream. */
+ public <T extends MessageLite> T readMessage(
+ final Parser<T> parser,
+ final ExtensionRegistryLite extensionRegistry)
+ throws IOException {
+ int length = readRawVarint32();
+ if (recursionDepth >= recursionLimit) {
+ throw InvalidProtocolBufferException.recursionLimitExceeded();
+ }
+ final int oldLimit = pushLimit(length);
+ ++recursionDepth;
+ T result = parser.parsePartialFrom(this, extensionRegistry);
+ checkLastTagWas(0);
+ --recursionDepth;
+ popLimit(oldLimit);
+ return result;
+ }
+
/** Read a {@code bytes} field value from the stream. */
public ByteString readBytes() throws IOException {
final int size = readRawVarint32();
if (size <= (bufferSize - bufferPos) && size > 0) {
// Fast path: We already have the bytes in a contiguous buffer, so
// just copy directly from it.
- final ByteString result = ByteString.copyFrom(buffer, bufferPos, size);
+ final ByteString result = bufferIsImmutable && enableAliasing
+ ? new BoundedByteString(buffer, bufferPos, size)
+ : ByteString.copyFrom(buffer, bufferPos, size);
bufferPos += size;
return result;
+ } else if (size == 0) {
+ return ByteString.EMPTY;
} else {
// Slow path: Build a byte array first then copy it.
- return ByteString.copyFrom(readRawBytes(size));
+ return new LiteralByteString(readRawBytesSlowPath(size));
+ }
+ }
+
+ /** Read a {@code bytes} field value from the stream. */
+ public byte[] readByteArray() throws IOException {
+ final int size = readRawVarint32();
+ if (size <= (bufferSize - bufferPos) && size > 0) {
+ // Fast path: We already have the bytes in a contiguous buffer, so
+ // just copy directly from it.
+ final byte[] result =
+ Arrays.copyOfRange(buffer, bufferPos, bufferPos + size);
+ bufferPos += size;
+ return result;
+ } else {
+ // Slow path: Build a byte array first then copy it.
+ return readRawBytesSlowPath(size);
+ }
+ }
+
+ /** Read a {@code bytes} field value from the stream. */
+ public ByteBuffer readByteBuffer() throws IOException {
+ final int size = readRawVarint32();
+ if (size <= (bufferSize - bufferPos) && size > 0) {
+ // Fast path: We already have the bytes in a contiguous buffer.
+ // When aliasing is enabled, we can return a ByteBuffer pointing directly
+ // into the underlying byte array without copy if the CodedInputStream is
+ // constructed from a byte array. If aliasing is disabled or the input is
+ // from an InputStream or ByteString, we have to make a copy of the bytes.
+ ByteBuffer result = input == null && !bufferIsImmutable && enableAliasing
+ ? ByteBuffer.wrap(buffer, bufferPos, size).slice()
+ : ByteBuffer.wrap(Arrays.copyOfRange(
+ buffer, bufferPos, bufferPos + size));
+ bufferPos += size;
+ return result;
+ } else if (size == 0) {
+ return Internal.EMPTY_BYTE_BUFFER;
+ } else {
+ // Slow path: Build a byte array first then copy it.
+ return ByteBuffer.wrap(readRawBytesSlowPath(size));
}
}
@@ -315,37 +597,67 @@ public final class CodedInputStream {
* upper bits.
*/
public int readRawVarint32() throws IOException {
- byte tmp = readRawByte();
- if (tmp >= 0) {
- return tmp;
- }
- int result = tmp & 0x7f;
- if ((tmp = readRawByte()) >= 0) {
- result |= tmp << 7;
- } else {
- result |= (tmp & 0x7f) << 7;
- if ((tmp = readRawByte()) >= 0) {
- result |= tmp << 14;
+ // See implementation notes for readRawVarint64
+ fastpath: {
+ int pos = bufferPos;
+
+ if (bufferSize == pos) {
+ break fastpath;
+ }
+
+ final byte[] buffer = this.buffer;
+ int x;
+ if ((x = buffer[pos++]) >= 0) {
+ bufferPos = pos;
+ return x;
+ } else if (bufferSize - pos < 9) {
+ break fastpath;
+ } else if ((x ^= (buffer[pos++] << 7)) < 0L) {
+ x ^= (~0L << 7);
+ } else if ((x ^= (buffer[pos++] << 14)) >= 0L) {
+ x ^= (~0L << 7) ^ (~0L << 14);
+ } else if ((x ^= (buffer[pos++] << 21)) < 0L) {
+ x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21);
} else {
- result |= (tmp & 0x7f) << 14;
- if ((tmp = readRawByte()) >= 0) {
- result |= tmp << 21;
- } else {
- result |= (tmp & 0x7f) << 21;
- result |= (tmp = readRawByte()) << 28;
- if (tmp < 0) {
- // Discard upper 32 bits.
- for (int i = 0; i < 5; i++) {
- if (readRawByte() >= 0) {
- return result;
- }
- }
- throw InvalidProtocolBufferException.malformedVarint();
- }
+ int y = buffer[pos++];
+ x ^= y << 28;
+ x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
+ if (y < 0 &&
+ buffer[pos++] < 0 &&
+ buffer[pos++] < 0 &&
+ buffer[pos++] < 0 &&
+ buffer[pos++] < 0 &&
+ buffer[pos++] < 0) {
+ break fastpath; // Will throw malformedVarint()
}
}
+ bufferPos = pos;
+ return x;
}
- return result;
+ return (int) readRawVarint64SlowPath();
+ }
+
+ private void skipRawVarint() throws IOException {
+ if (bufferSize - bufferPos >= 10) {
+ final byte[] buffer = this.buffer;
+ int pos = bufferPos;
+ for (int i = 0; i < 10; i++) {
+ if (buffer[pos++] >= 0) {
+ bufferPos = pos;
+ return;
+ }
+ }
+ }
+ skipRawVarintSlowPath();
+ }
+
+ private void skipRawVarintSlowPath() throws IOException {
+ for (int i = 0; i < 10; i++) {
+ if (readRawByte() >= 0) {
+ return;
+ }
+ }
+ throw InvalidProtocolBufferException.malformedVarint();
}
/**
@@ -368,8 +680,8 @@ public final class CodedInputStream {
* has already read one byte. This allows the caller to determine if EOF
* has been reached before attempting to read.
*/
- static int readRawVarint32(final int firstByte,
- final InputStream input) throws IOException {
+ public static int readRawVarint32(
+ final int firstByte, final InputStream input) throws IOException {
if ((firstByte & 0x80) == 0) {
return firstByte;
}
@@ -401,49 +713,115 @@ public final class CodedInputStream {
/** Read a raw Varint from the stream. */
public long readRawVarint64() throws IOException {
- int shift = 0;
+ // Implementation notes:
+ //
+ // Optimized for one-byte values, expected to be common.
+ // The particular code below was selected from various candidates
+ // empirically, by winning VarintBenchmark.
+ //
+ // Sign extension of (signed) Java bytes is usually a nuisance, but
+ // we exploit it here to more easily obtain the sign of bytes read.
+ // Instead of cleaning up the sign extension bits by masking eagerly,
+ // we delay until we find the final (positive) byte, when we clear all
+ // accumulated bits with one xor. We depend on javac to constant fold.
+ fastpath: {
+ int pos = bufferPos;
+
+ if (bufferSize == pos) {
+ break fastpath;
+ }
+
+ final byte[] buffer = this.buffer;
+ long x;
+ int y;
+ if ((y = buffer[pos++]) >= 0) {
+ bufferPos = pos;
+ return y;
+ } else if (bufferSize - pos < 9) {
+ break fastpath;
+ } else if ((x = y ^ (buffer[pos++] << 7)) < 0L) {
+ x ^= (~0L << 7);
+ } else if ((x ^= (buffer[pos++] << 14)) >= 0L) {
+ x ^= (~0L << 7) ^ (~0L << 14);
+ } else if ((x ^= (buffer[pos++] << 21)) < 0L) {
+ x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21);
+ } else if ((x ^= ((long) buffer[pos++] << 28)) >= 0L) {
+ x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
+ } else if ((x ^= ((long) buffer[pos++] << 35)) < 0L) {
+ x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
+ } else if ((x ^= ((long) buffer[pos++] << 42)) >= 0L) {
+ x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
+ } else if ((x ^= ((long) buffer[pos++] << 49)) < 0L) {
+ x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42)
+ ^ (~0L << 49);
+ } else {
+ x ^= ((long) buffer[pos++] << 56);
+ x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42)
+ ^ (~0L << 49) ^ (~0L << 56);
+ if (x < 0L) {
+ if (buffer[pos++] < 0L) {
+ break fastpath; // Will throw malformedVarint()
+ }
+ }
+ }
+ bufferPos = pos;
+ return x;
+ }
+ return readRawVarint64SlowPath();
+ }
+
+ /** Variant of readRawVarint64 for when uncomfortably close to the limit. */
+ /* Visible for testing */
+ long readRawVarint64SlowPath() throws IOException {
long result = 0;
- while (shift < 64) {
+ for (int shift = 0; shift < 64; shift += 7) {
final byte b = readRawByte();
- result |= (long)(b & 0x7F) << shift;
+ result |= (long) (b & 0x7F) << shift;
if ((b & 0x80) == 0) {
return result;
}
- shift += 7;
}
throw InvalidProtocolBufferException.malformedVarint();
}
/** Read a 32-bit little-endian integer from the stream. */
public int readRawLittleEndian32() throws IOException {
- final byte b1 = readRawByte();
- final byte b2 = readRawByte();
- final byte b3 = readRawByte();
- final byte b4 = readRawByte();
- return (((int)b1 & 0xff) ) |
- (((int)b2 & 0xff) << 8) |
- (((int)b3 & 0xff) << 16) |
- (((int)b4 & 0xff) << 24);
+ int pos = bufferPos;
+
+ // hand-inlined ensureAvailable(4);
+ if (bufferSize - pos < 4) {
+ refillBuffer(4);
+ pos = bufferPos;
+ }
+
+ final byte[] buffer = this.buffer;
+ bufferPos = pos + 4;
+ return (((buffer[pos] & 0xff)) |
+ ((buffer[pos + 1] & 0xff) << 8) |
+ ((buffer[pos + 2] & 0xff) << 16) |
+ ((buffer[pos + 3] & 0xff) << 24));
}
/** Read a 64-bit little-endian integer from the stream. */
public long readRawLittleEndian64() throws IOException {
- final byte b1 = readRawByte();
- final byte b2 = readRawByte();
- final byte b3 = readRawByte();
- final byte b4 = readRawByte();
- final byte b5 = readRawByte();
- final byte b6 = readRawByte();
- final byte b7 = readRawByte();
- final byte b8 = readRawByte();
- return (((long)b1 & 0xff) ) |
- (((long)b2 & 0xff) << 8) |
- (((long)b3 & 0xff) << 16) |
- (((long)b4 & 0xff) << 24) |
- (((long)b5 & 0xff) << 32) |
- (((long)b6 & 0xff) << 40) |
- (((long)b7 & 0xff) << 48) |
- (((long)b8 & 0xff) << 56);
+ int pos = bufferPos;
+
+ // hand-inlined ensureAvailable(8);
+ if (bufferSize - pos < 8) {
+ refillBuffer(8);
+ pos = bufferPos;
+ }
+
+ final byte[] buffer = this.buffer;
+ bufferPos = pos + 8;
+ return ((((long) buffer[pos] & 0xffL)) |
+ (((long) buffer[pos + 1] & 0xffL) << 8) |
+ (((long) buffer[pos + 2] & 0xffL) << 16) |
+ (((long) buffer[pos + 3] & 0xffL) << 24) |
+ (((long) buffer[pos + 4] & 0xffL) << 32) |
+ (((long) buffer[pos + 5] & 0xffL) << 40) |
+ (((long) buffer[pos + 6] & 0xffL) << 48) |
+ (((long) buffer[pos + 7] & 0xffL) << 56));
}
/**
@@ -477,11 +855,13 @@ public final class CodedInputStream {
// -----------------------------------------------------------------
private final byte[] buffer;
+ private final boolean bufferIsImmutable;
private int bufferSize;
private int bufferSizeAfterLimit;
private int bufferPos;
private final InputStream input;
private int lastTag;
+ private boolean enableAliasing = false;
/**
* The total number of bytes read before the current buffer. The total
@@ -512,6 +892,7 @@ public final class CodedInputStream {
bufferPos = off;
totalBytesRetired = -off;
input = null;
+ bufferIsImmutable = false;
}
private CodedInputStream(final InputStream input) {
@@ -520,6 +901,20 @@ public final class CodedInputStream {
bufferPos = 0;
totalBytesRetired = 0;
this.input = input;
+ 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;
}
/**
@@ -581,7 +976,7 @@ public final class CodedInputStream {
* refreshing its buffer. If you need to prevent reading past a certain
* point in the underlying {@code InputStream} (e.g. because you expect it to
* contain more data after the end of the message which you need to handle
- * differently) then you must place a wrapper around you {@code InputStream}
+ * differently) then you must place a wrapper around your {@code InputStream}
* which limits the amount of data that can be read from it.
*
* @return the old limit.
@@ -643,7 +1038,7 @@ public final class CodedInputStream {
* if the stream has reached a limit created using {@link #pushLimit(int)}.
*/
public boolean isAtEnd() throws IOException {
- return bufferPos == bufferSize && !refillBuffer(false);
+ return bufferPos == bufferSize && !tryRefillBuffer(1);
}
/**
@@ -654,53 +1049,93 @@ public final class CodedInputStream {
return totalBytesRetired + bufferPos;
}
+ private interface RefillCallback {
+ void onRefill();
+ }
+
+ 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.
+ *
+ * @throws InvalidProtocolBufferException The end of the stream or the current
+ * limit was reached.
+ */
+ private void refillBuffer(int n) throws IOException {
+ if (!tryRefillBuffer(n)) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+ }
+
/**
- * Called with {@code this.buffer} is empty to read more bytes from the
- * input. If {@code mustSucceed} is true, refillBuffer() gurantees that
- * either there will be at least one byte in the buffer when it returns
- * or it will throw an exception. If {@code mustSucceed} is false,
- * refillBuffer() returns false if no more bytes were available.
+ * Tries to read 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.
+ *
+ * @return {@code true} if the bytes could be made available; {@code false}
+ * if the end of the stream or the current limit was reached.
*/
- private boolean refillBuffer(final boolean mustSucceed) throws IOException {
- if (bufferPos < bufferSize) {
+ private boolean tryRefillBuffer(int n) throws IOException {
+ if (bufferPos + n <= bufferSize) {
throw new IllegalStateException(
- "refillBuffer() called when buffer wasn't empty.");
+ "refillBuffer() called when " + n +
+ " bytes were already available in buffer");
}
- if (totalBytesRetired + bufferSize == currentLimit) {
+ if (totalBytesRetired + bufferPos + n > currentLimit) {
// Oops, we hit a limit.
- if (mustSucceed) {
- throw InvalidProtocolBufferException.truncatedMessage();
- } else {
- return false;
- }
+ return false;
}
- totalBytesRetired += bufferSize;
-
- bufferPos = 0;
- bufferSize = (input == null) ? -1 : input.read(buffer);
- if (bufferSize == 0 || bufferSize < -1) {
- throw new IllegalStateException(
- "InputStream#read(byte[]) returned invalid result: " + bufferSize +
- "\nThe InputStream implementation is buggy.");
+ if (refillCallback != null) {
+ refillCallback.onRefill();
}
- if (bufferSize == -1) {
- bufferSize = 0;
- if (mustSucceed) {
- throw InvalidProtocolBufferException.truncatedMessage();
- } else {
- return false;
+
+ if (input != null) {
+ int pos = bufferPos;
+ if (pos > 0) {
+ if (bufferSize > pos) {
+ System.arraycopy(buffer, pos, buffer, 0, bufferSize - pos);
+ }
+ totalBytesRetired += pos;
+ bufferSize -= pos;
+ bufferPos = 0;
}
- } else {
- recomputeBufferSizeAfterLimit();
- final int totalBytesRead =
- totalBytesRetired + bufferSize + bufferSizeAfterLimit;
- if (totalBytesRead > sizeLimit || totalBytesRead < 0) {
- throw InvalidProtocolBufferException.sizeLimitExceeded();
+
+ int bytesRead = input.read(buffer, bufferSize, buffer.length - bufferSize);
+ if (bytesRead == 0 || bytesRead < -1 || bytesRead > buffer.length) {
+ throw new IllegalStateException(
+ "InputStream#read(byte[]) returned invalid result: " + bytesRead +
+ "\nThe InputStream implementation is buggy.");
+ }
+ if (bytesRead > 0) {
+ bufferSize += bytesRead;
+ // Integer-overflow-conscious check against sizeLimit
+ if (totalBytesRetired + n - sizeLimit > 0) {
+ throw InvalidProtocolBufferException.sizeLimitExceeded();
+ }
+ recomputeBufferSizeAfterLimit();
+ return (bufferSize >= n) ? true : tryRefillBuffer(n);
}
- return true;
}
+
+ return false;
}
/**
@@ -711,7 +1146,7 @@ public final class CodedInputStream {
*/
public byte readRawByte() throws IOException {
if (bufferPos == bufferSize) {
- refillBuffer(true);
+ refillBuffer(1);
}
return buffer[bufferPos++];
}
@@ -723,8 +1158,26 @@ public final class CodedInputStream {
* limit was reached.
*/
public byte[] readRawBytes(final int size) throws IOException {
- if (size < 0) {
- throw InvalidProtocolBufferException.negativeSize();
+ final int pos = bufferPos;
+ if (size <= (bufferSize - pos) && size > 0) {
+ bufferPos = pos + size;
+ return Arrays.copyOfRange(buffer, pos, pos + size);
+ } else {
+ return readRawBytesSlowPath(size);
+ }
+ }
+
+ /**
+ * Exactly like readRawBytes, but caller must have already checked the fast
+ * path: (size <= (bufferSize - pos) && size > 0)
+ */
+ private byte[] readRawBytesSlowPath(final int size) throws IOException {
+ if (size <= 0) {
+ if (size == 0) {
+ return Internal.EMPTY_BYTE_ARRAY;
+ } else {
+ throw InvalidProtocolBufferException.negativeSize();
+ }
}
if (totalBytesRetired + bufferPos + size > currentLimit) {
@@ -734,13 +1187,7 @@ public final class CodedInputStream {
throw InvalidProtocolBufferException.truncatedMessage();
}
- if (size <= bufferSize - bufferPos) {
- // We have all the bytes we need already.
- final byte[] bytes = new byte[size];
- System.arraycopy(buffer, bufferPos, bytes, 0, size);
- bufferPos += size;
- return bytes;
- } else if (size < BUFFER_SIZE) {
+ 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.
@@ -750,18 +1197,10 @@ public final class CodedInputStream {
System.arraycopy(buffer, bufferPos, bytes, 0, pos);
bufferPos = bufferSize;
- // We want to use refillBuffer() and then copy from the buffer into our
+ // 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.
- refillBuffer(true);
-
- while (size - pos > bufferSize) {
- System.arraycopy(buffer, 0, bytes, pos, bufferSize);
- pos += bufferSize;
- bufferPos = bufferSize;
- refillBuffer(true);
- }
-
+ ensureAvailable(size - pos);
System.arraycopy(buffer, 0, bytes, pos, size - pos);
bufferPos = size - pos;
@@ -830,6 +1269,19 @@ public final class CodedInputStream {
* limit was reached.
*/
public void skipRawBytes(final int size) throws IOException {
+ if (size <= (bufferSize - bufferPos) && size >= 0) {
+ // We have all the bytes we need already.
+ bufferPos += size;
+ } else {
+ skipRawBytesSlowPath(size);
+ }
+ }
+
+ /**
+ * Exactly like skipRawBytes, but caller must have already checked the fast
+ * path: (size <= (bufferSize - pos) && size >= 0)
+ */
+ private void skipRawBytesSlowPath(final int size) throws IOException {
if (size < 0) {
throw InvalidProtocolBufferException.negativeSize();
}
@@ -841,25 +1293,19 @@ public final class CodedInputStream {
throw InvalidProtocolBufferException.truncatedMessage();
}
- if (size <= bufferSize - bufferPos) {
- // We have all the bytes we need already.
- bufferPos += size;
- } else {
- // Skipping more bytes than are in the buffer. First skip what we have.
- int pos = bufferSize - bufferPos;
- totalBytesRetired += bufferSize;
- bufferPos = 0;
- bufferSize = 0;
+ // Skipping more bytes than are in the buffer. First skip what we have.
+ int pos = bufferSize - bufferPos;
+ bufferPos = bufferSize;
- // Then skip directly from the InputStream for the rest.
- while (pos < size) {
- final int n = (input == null) ? -1 : (int) input.skip(size - pos);
- if (n <= 0) {
- throw InvalidProtocolBufferException.truncatedMessage();
- }
- pos += n;
- totalBytesRetired += n;
- }
+ // Keep refilling the buffer until we get to the point we wanted to skip to.
+ // This has the side effect of ensuring the limits are updated correctly.
+ refillBuffer(1);
+ while (size - pos > bufferSize) {
+ pos += bufferSize;
+ bufferPos = bufferSize;
+ refillBuffer(1);
}
+
+ bufferPos = size - pos;
}
}
diff --git a/java/src/main/java/com/google/protobuf/CodedOutputStream.java b/java/src/main/java/com/google/protobuf/CodedOutputStream.java
index 58dd150..fafe035 100644
--- a/java/src/main/java/com/google/protobuf/CodedOutputStream.java
+++ b/java/src/main/java/com/google/protobuf/CodedOutputStream.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -30,9 +30,10 @@
package com.google.protobuf;
-import java.io.OutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
/**
* Encodes and writes protocol message fields.
@@ -52,6 +53,7 @@ public final class CodedOutputStream {
private final byte[] buffer;
private final int limit;
private int position;
+ private int totalBytesWritten = 0;
private final OutputStream output;
@@ -128,6 +130,38 @@ public final class CodedOutputStream {
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. */
@@ -201,6 +235,7 @@ public final class CodedOutputStream {
writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
}
+
/**
* Write a group represented by an {@link UnknownFieldSet}.
*
@@ -221,6 +256,7 @@ public final class CodedOutputStream {
writeMessageNoTag(value);
}
+
/** Write a {@code bytes} field, including tag, to the stream. */
public void writeBytes(final int fieldNumber, final ByteString value)
throws IOException {
@@ -228,6 +264,39 @@ public final class CodedOutputStream {
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 {
@@ -361,6 +430,7 @@ public final class CodedOutputStream {
value.writeTo(this);
}
+
/**
* Write a group represented by an {@link UnknownFieldSet}.
*
@@ -379,11 +449,39 @@ public final class CodedOutputStream {
value.writeTo(this);
}
+
/** Write a {@code bytes} field to the stream. */
public void writeBytesNoTag(final ByteString value) throws IOException {
- final byte[] bytes = value.toByteArray();
- writeRawVarint32(bytes.length);
- writeRawBytes(bytes);
+ 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. */
@@ -396,7 +494,7 @@ public final class CodedOutputStream {
* for converting the enum value to its numeric value.
*/
public void writeEnumNoTag(final int value) throws IOException {
- writeRawVarint32(value);
+ writeInt32NoTag(value);
}
/** Write an {@code sfixed32} field to the stream. */
@@ -541,6 +639,33 @@ public final class CodedOutputStream {
/**
* 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) {
@@ -614,6 +739,18 @@ public final class CodedOutputStream {
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);
+ }
+
// -----------------------------------------------------------------
/**
@@ -730,6 +867,15 @@ public final class CodedOutputStream {
}
/**
+ * 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.
*/
@@ -740,6 +886,22 @@ public final class CodedOutputStream {
/**
* 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) {
@@ -751,7 +913,7 @@ public final class CodedOutputStream {
* Caller is responsible for converting the enum value to its numeric value.
*/
public static int computeEnumSizeNoTag(final int value) {
- return computeRawVarint32Size(value);
+ return computeInt32SizeNoTag(value);
}
/**
@@ -856,6 +1018,15 @@ public final class CodedOutputStream {
}
}
+ /**
+ * 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) {
@@ -863,6 +1034,7 @@ public final class CodedOutputStream {
}
buffer[position++] = value;
+ ++totalBytesWritten;
}
/** Write a single byte, represented by an integer value. */
@@ -870,11 +1042,71 @@ public final class CodedOutputStream {
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 {
@@ -882,6 +1114,7 @@ public final class CodedOutputStream {
// 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.
@@ -890,6 +1123,7 @@ public final class CodedOutputStream {
offset += bytesWritten;
length -= bytesWritten;
position = limit;
+ totalBytesWritten += bytesWritten;
refreshBuffer();
// Now deal with the rest.
@@ -903,6 +1137,40 @@ public final class CodedOutputStream {
// 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;
}
}
diff --git a/java/src/main/java/com/google/protobuf/Descriptors.java b/java/src/main/java/com/google/protobuf/Descriptors.java
index c5e9a04..caae0f7 100644
--- a/java/src/main/java/com/google/protobuf/Descriptors.java
+++ b/java/src/main/java/com/google/protobuf/Descriptors.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,11 +32,15 @@ package com.google.protobuf;
import com.google.protobuf.DescriptorProtos.*;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
import java.io.UnsupportedEncodingException;
/**
@@ -46,6 +50,11 @@ import java.io.UnsupportedEncodingException;
* its fields and other information about a type. You can get a message
* type's descriptor by calling {@code MessageType.getDescriptor()}, or
* (given a message object of the type) {@code message.getDescriptorForType()}.
+ * Furthermore, each message is associated with a {@link FileDescriptor} for
+ * a relevant {@code .proto} file. You can obtain it by calling
+ * {@code Descriptor.getFile()}. A {@link FileDescriptor} contains descriptors
+ * for all the messages defined in that file, and file descriptors for all the
+ * imported {@code .proto} files.
*
* Descriptors are built from DescriptorProtos, as defined in
* {@code google/protobuf/descriptor.proto}.
@@ -53,16 +62,27 @@ import java.io.UnsupportedEncodingException;
* @author kenton@google.com Kenton Varda
*/
public final class Descriptors {
+ private static final Logger logger =
+ Logger.getLogger(Descriptors.class.getName());
/**
* Describes a {@code .proto} file, including everything defined within.
+ * That includes, in particular, descriptors for all the messages and
+ * file descriptors for all other imported {@code .proto} files
+ * (dependencies).
*/
- public static final class FileDescriptor {
+ public static final class FileDescriptor extends GenericDescriptor {
/** Convert the descriptor to its protocol message representation. */
public FileDescriptorProto toProto() { return proto; }
/** Get the file name. */
public String getName() { return proto.getName(); }
+ /** Returns this object. */
+ public FileDescriptor getFile() { return this; }
+
+ /** Returns the same as getName(). */
+ public String getFullName() { return proto.getName(); }
+
/**
* Get the proto package name. This is the package name given by the
* {@code package} statement in the {@code .proto} file, which differs
@@ -98,6 +118,11 @@ public final class Descriptors {
return Collections.unmodifiableList(Arrays.asList(dependencies));
}
+ /** Get a list of this file's public dependencies (public imports). */
+ public List<FileDescriptor> getPublicDependencies() {
+ return Collections.unmodifiableList(Arrays.asList(publicDependencies));
+ }
+
/**
* Find a message type in the file by name. Does not find nested types.
*
@@ -198,8 +223,7 @@ public final class Descriptors {
*
* @param proto The protocol message form of the FileDescriptor.
* @param dependencies {@code FileDescriptor}s corresponding to all of
- * the file's dependencies, in the exact order listed
- * in {@code proto}.
+ * the file's dependencies.
* @throws DescriptorValidationException {@code proto} is not a valid
* descriptor. This can occur for a number of reasons, e.g.
* because a field has an undefined type or because two messages
@@ -208,7 +232,29 @@ public final class Descriptors {
public static FileDescriptor buildFrom(final FileDescriptorProto proto,
final FileDescriptor[] dependencies)
throws DescriptorValidationException {
- // Building decsriptors involves two steps: translating and linking.
+ return buildFrom(proto, dependencies, false);
+ }
+
+
+ /**
+ * Construct a {@code FileDescriptor}.
+ *
+ * @param proto The protocol message form of the FileDescriptor.
+ * @param dependencies {@code FileDescriptor}s corresponding to all of
+ * the file's dependencies.
+ * @param allowUnknownDependencies If true, non-exist dependenncies will be
+ * ignored and undefined message types will be replaced with a
+ * placeholder type.
+ * @throws DescriptorValidationException {@code proto} is not a valid
+ * descriptor. This can occur for a number of reasons, e.g.
+ * because a field has an undefined type or because two messages
+ * were defined with the same name.
+ */
+ private static FileDescriptor buildFrom(
+ final FileDescriptorProto proto, final FileDescriptor[] dependencies,
+ final boolean allowUnknownDependencies)
+ throws DescriptorValidationException {
+ // Building descriptors involves two steps: translating and linking.
// In the translation step (implemented by FileDescriptor's
// constructor), we build an object tree mirroring the
// FileDescriptorProto's tree and put all of the descriptors into the
@@ -217,23 +263,10 @@ public final class Descriptors {
// FieldDescriptor for an embedded message contains a pointer directly
// to the Descriptor for that message's type. We also detect undefined
// types in the linking step.
- final DescriptorPool pool = new DescriptorPool(dependencies);
- final FileDescriptor result =
- new FileDescriptor(proto, dependencies, pool);
-
- if (dependencies.length != proto.getDependencyCount()) {
- throw new DescriptorValidationException(result,
- "Dependencies passed to FileDescriptor.buildFrom() don't match " +
- "those listed in the FileDescriptorProto.");
- }
- for (int i = 0; i < proto.getDependencyCount(); i++) {
- if (!dependencies[i].getName().equals(proto.getDependency(i))) {
- throw new DescriptorValidationException(result,
- "Dependencies passed to FileDescriptor.buildFrom() don't match " +
- "those listed in the FileDescriptorProto.");
- }
- }
-
+ final DescriptorPool pool = new DescriptorPool(
+ dependencies, allowUnknownDependencies);
+ final FileDescriptor result = new FileDescriptor(
+ proto, dependencies, pool, allowUnknownDependencies);
result.crossLink();
return result;
}
@@ -281,7 +314,9 @@ public final class Descriptors {
final FileDescriptor result;
try {
- result = buildFrom(proto, dependencies);
+ // When building descriptors for generated code, we allow unknown
+ // dependencies by default.
+ result = buildFrom(proto, dependencies, true);
} catch (DescriptorValidationException e) {
throw new IllegalArgumentException(
"Invalid embedded descriptor for \"" + proto.getName() + "\".", e);
@@ -305,16 +340,66 @@ public final class Descriptors {
}
/**
+ * This method is to be called by generated code only. It uses Java
+ * reflection to load the dependencies' descriptors.
+ */
+ public static void internalBuildGeneratedFileFrom(
+ final String[] descriptorDataParts,
+ final Class<?> descriptorOuterClass,
+ final String[] dependencies,
+ final String[] dependencyFileNames,
+ final InternalDescriptorAssigner descriptorAssigner) {
+ List<FileDescriptor> descriptors = new ArrayList<FileDescriptor>();
+ for (int i = 0; i < dependencies.length; i++) {
+ try {
+ Class<?> clazz =
+ descriptorOuterClass.getClassLoader().loadClass(dependencies[i]);
+ descriptors.add(
+ (FileDescriptor) clazz.getField("descriptor").get(null));
+ } catch (Exception e) {
+ // We allow unknown dependencies by default. If a dependency cannot
+ // be found we only generate a warning.
+ logger.warning("Descriptors for \"" + dependencyFileNames[i] +
+ "\" can not be found.");
+ }
+ }
+ FileDescriptor[] descriptorArray = new FileDescriptor[descriptors.size()];
+ descriptors.toArray(descriptorArray);
+ internalBuildGeneratedFileFrom(
+ descriptorDataParts, descriptorArray, descriptorAssigner);
+ }
+
+ /**
+ * This method is to be called by generated code only. It is used to
+ * update the FileDescriptorProto associated with the descriptor by
+ * parsing it again with the given ExtensionRegistry. This is needed to
+ * recognize custom options.
+ */
+ public static void internalUpdateFileDescriptor(
+ final FileDescriptor descriptor,
+ final ExtensionRegistry registry) {
+ ByteString bytes = descriptor.proto.toByteString();
+ FileDescriptorProto proto;
+ try {
+ proto = FileDescriptorProto.parseFrom(bytes, registry);
+ } catch (InvalidProtocolBufferException e) {
+ throw new IllegalArgumentException(
+ "Failed to parse protocol buffer descriptor for generated code.", e);
+ }
+ descriptor.setProto(proto);
+ }
+
+ /**
* This class should be used by generated code only. When calling
* {@link FileDescriptor#internalBuildGeneratedFileFrom}, the caller
* provides a callback implementing this interface. The callback is called
* after the FileDescriptor has been constructed, in order to assign all
- * the global variales defined in the generated code which point at parts
+ * the global variables defined in the generated code which point at parts
* of the FileDescriptor. The callback returns an ExtensionRegistry which
* contains any extensions which might be used in the descriptor -- that
* is, extensions of the various "Options" messages defined in
* descriptor.proto. The callback may also return null to indicate that
- * no extensions are used in the decsriptor.
+ * no extensions are used in the descriptor.
*/
public interface InternalDescriptorAssigner {
ExtensionRegistry assignDescriptors(FileDescriptor root);
@@ -326,15 +411,43 @@ public final class Descriptors {
private final ServiceDescriptor[] services;
private final FieldDescriptor[] extensions;
private final FileDescriptor[] dependencies;
+ private final FileDescriptor[] publicDependencies;
private final DescriptorPool pool;
private FileDescriptor(final FileDescriptorProto proto,
final FileDescriptor[] dependencies,
- final DescriptorPool pool)
+ final DescriptorPool pool,
+ boolean allowUnknownDependencies)
throws DescriptorValidationException {
this.pool = pool;
this.proto = proto;
this.dependencies = dependencies.clone();
+ HashMap<String, FileDescriptor> nameToFileMap =
+ new HashMap<String, FileDescriptor>();
+ for (FileDescriptor file : dependencies) {
+ nameToFileMap.put(file.getName(), file);
+ }
+ List<FileDescriptor> publicDependencies = new ArrayList<FileDescriptor>();
+ for (int i = 0; i < proto.getPublicDependencyCount(); i++) {
+ int index = proto.getPublicDependency(i);
+ if (index < 0 || index >= proto.getDependencyCount()) {
+ throw new DescriptorValidationException(this,
+ "Invalid public dependency index.");
+ }
+ String name = proto.getDependency(index);
+ FileDescriptor file = nameToFileMap.get(name);
+ if (file == null) {
+ if (!allowUnknownDependencies) {
+ throw new DescriptorValidationException(this,
+ "Invalid public dependency: " + name);
+ }
+ // Ignore unknown dependencies.
+ } else {
+ publicDependencies.add(file);
+ }
+ }
+ this.publicDependencies = new FileDescriptor[publicDependencies.size()];
+ publicDependencies.toArray(this.publicDependencies);
pool.addPackage(getPackage(), this);
@@ -360,6 +473,27 @@ public final class Descriptors {
proto.getExtension(i), this, null, i, true);
}
}
+
+ /**
+ * Create a placeholder FileDescriptor for a message Descriptor.
+ */
+ FileDescriptor(String packageName, Descriptor message)
+ throws DescriptorValidationException {
+ this.pool = new DescriptorPool(new FileDescriptor[0], true);
+ this.proto = FileDescriptorProto.newBuilder()
+ .setName(message.getFullName() + ".placeholder.proto")
+ .setPackage(packageName).addMessageType(message.toProto()).build();
+ this.dependencies = new FileDescriptor[0];
+ this.publicDependencies = new FileDescriptor[0];
+
+ messageTypes = new Descriptor[] {message};
+ enumTypes = new EnumDescriptor[0];
+ services = new ServiceDescriptor[0];
+ extensions = new FieldDescriptor[0];
+
+ pool.addPackage(packageName, this);
+ pool.addSymbol(message);
+ }
/** Look up and cross-link all field types, etc. */
private void crossLink() throws DescriptorValidationException {
@@ -382,7 +516,7 @@ public final class Descriptors {
* in the original. This method is needed for bootstrapping when a file
* defines custom options. The options may be defined in the file itself,
* so we can't actually parse them until we've constructed the descriptors,
- * but to construct the decsriptors we have to have parsed the descriptor
+ * but to construct the descriptors we have to have parsed the descriptor
* protos. So, we have to parse the descriptor protos a second time after
* constructing the descriptors.
*/
@@ -410,7 +544,7 @@ public final class Descriptors {
// =================================================================
/** Describes a message type. */
- public static final class Descriptor implements GenericDescriptor {
+ public static final class Descriptor extends GenericDescriptor {
/**
* Get the index of this descriptor within its parent. In other words,
* given a {@link FileDescriptor} {@code file}, the following is true:
@@ -459,6 +593,11 @@ public final class Descriptors {
return Collections.unmodifiableList(Arrays.asList(fields));
}
+ /** Get a list of this message type's oneofs. */
+ public List<OneofDescriptor> getOneofs() {
+ return Collections.unmodifiableList(Arrays.asList(oneofs));
+ }
+
/** Get a list of this message type's extensions. */
public List<FieldDescriptor> getExtensions() {
return Collections.unmodifiableList(Arrays.asList(extensions));
@@ -486,6 +625,14 @@ public final class Descriptors {
}
/**
+ * Indicates whether the message can be extended. That is, whether it has
+ * any "extensions x to y" ranges declared on it.
+ */
+ public boolean isExtendable() {
+ return proto.getExtensionRangeList().size() != 0;
+ }
+
+ /**
* Finds a field by name.
* @param name The unqualified name of the field (e.g. "foo").
* @return The field's descriptor, or {@code null} if not found.
@@ -549,6 +696,33 @@ public final class Descriptors {
private final EnumDescriptor[] enumTypes;
private final FieldDescriptor[] fields;
private final FieldDescriptor[] extensions;
+ private final OneofDescriptor[] oneofs;
+
+ // Used to create a placeholder when the type cannot be found.
+ Descriptor(final String fullname) throws DescriptorValidationException {
+ String name = fullname;
+ String packageName = "";
+ int pos = fullname.lastIndexOf('.');
+ if (pos != -1) {
+ name = fullname.substring(pos + 1);
+ packageName = fullname.substring(0, pos);
+ }
+ this.index = 0;
+ this.proto = DescriptorProto.newBuilder().setName(name).addExtensionRange(
+ DescriptorProto.ExtensionRange.newBuilder().setStart(1)
+ .setEnd(536870912).build()).build();
+ this.fullName = fullname;
+ this.containingType = null;
+
+ this.nestedTypes = new Descriptor[0];
+ this.enumTypes = new EnumDescriptor[0];
+ this.fields = new FieldDescriptor[0];
+ this.extensions = new FieldDescriptor[0];
+ this.oneofs = new OneofDescriptor[0];
+
+ // Create a placeholder FileDescriptor to hold this message.
+ this.file = new FileDescriptor(packageName, this);
+ }
private Descriptor(final DescriptorProto proto,
final FileDescriptor file,
@@ -561,6 +735,12 @@ public final class Descriptors {
this.file = file;
containingType = parent;
+ oneofs = new OneofDescriptor[proto.getOneofDeclCount()];
+ for (int i = 0; i < proto.getOneofDeclCount(); i++) {
+ oneofs[i] = new OneofDescriptor(
+ proto.getOneofDecl(i), file, this, i);
+ }
+
nestedTypes = new Descriptor[proto.getNestedTypeCount()];
for (int i = 0; i < proto.getNestedTypeCount(); i++) {
nestedTypes[i] = new Descriptor(
@@ -585,6 +765,17 @@ public final class Descriptors {
proto.getExtension(i), file, this, i, true);
}
+ for (int i = 0; i < proto.getOneofDeclCount(); i++) {
+ oneofs[i].fields = new FieldDescriptor[oneofs[i].getFieldCount()];
+ oneofs[i].fieldCount = 0;
+ }
+ for (int i = 0; i < proto.getFieldCount(); i++) {
+ OneofDescriptor oneofDescriptor = fields[i].getContainingOneof();
+ if (oneofDescriptor != null) {
+ oneofDescriptor.fields[oneofDescriptor.fieldCount++] = fields[i];
+ }
+ }
+
file.pool.addSymbol(this);
}
@@ -629,11 +820,12 @@ public final class Descriptors {
/** Describes a field of a message type. */
public static final class FieldDescriptor
- implements GenericDescriptor, Comparable<FieldDescriptor>,
+ extends GenericDescriptor
+ implements Comparable<FieldDescriptor>,
FieldSet.FieldDescriptorLite<FieldDescriptor> {
/**
* Get the index of this descriptor within its parent.
- * @see Descriptor#getIndex()
+ * @see Descriptors.Descriptor#getIndex()
*/
public int getIndex() { return index; }
@@ -648,7 +840,7 @@ public final class Descriptors {
/**
* Get the field's fully-qualified name.
- * @see Descriptor#getFullName()
+ * @see Descriptors.Descriptor#getFullName()
*/
public String getFullName() { return fullName; }
@@ -673,6 +865,12 @@ public final class Descriptors {
public WireFormat.FieldType getLiteType() {
return table[type.ordinal()];
}
+
+ /** For internal use only. */
+ public boolean needsUtf8Check() {
+ return (type == Type.STRING) && (getFile().getOptions().getJavaStringCheckUtf8());
+ }
+
// I'm pretty sure values() constructs a new array every time, since there
// is nothing stopping the caller from mutating the array. Therefore we
// make a static copy here.
@@ -734,6 +932,9 @@ public final class Descriptors {
*/
public Descriptor getContainingType() { return containingType; }
+ /** Get the field's containing oneof. */
+ public OneofDescriptor getContainingOneof() { return containingOneof; }
+
/**
* For extensions defined nested within message types, gets the outer
* type. Not valid for non-extension fields. For example, consider
@@ -811,6 +1012,7 @@ public final class Descriptors {
private Type type;
private Descriptor containingType;
private Descriptor messageType;
+ private OneofDescriptor containingOneof;
private EnumDescriptor enumType;
private Object defaultValue;
@@ -901,13 +1103,6 @@ public final class Descriptors {
"Field numbers must be positive integers.");
}
- // Only repeated primitive fields may be packed.
- if (proto.getOptions().getPacked() && !isPackable()) {
- throw new DescriptorValidationException(this,
- "[packed = true] can only be specified for repeated primitive " +
- "fields.");
- }
-
if (isExtension) {
if (!proto.hasExtendee()) {
throw new DescriptorValidationException(this,
@@ -919,12 +1114,31 @@ public final class Descriptors {
} else {
extensionScope = null;
}
+
+ if (proto.hasOneofIndex()) {
+ throw new DescriptorValidationException(this,
+ "FieldDescriptorProto.oneof_index set for extension field.");
+ }
+ containingOneof = null;
} else {
if (proto.hasExtendee()) {
throw new DescriptorValidationException(this,
"FieldDescriptorProto.extendee set for non-extension field.");
}
containingType = parent;
+
+ if (proto.hasOneofIndex()) {
+ if (proto.getOneofIndex() < 0 ||
+ proto.getOneofIndex() >= parent.toProto().getOneofDeclCount()) {
+ throw new DescriptorValidationException(this,
+ "FieldDescriptorProto.oneof_index is out of range for type "
+ + parent.getName());
+ }
+ containingOneof = parent.getOneofs().get(proto.getOneofIndex());
+ containingOneof.fieldCount++;
+ } else {
+ containingOneof = null;
+ }
extensionScope = null;
}
@@ -935,7 +1149,8 @@ public final class Descriptors {
private void crossLink() throws DescriptorValidationException {
if (proto.hasExtendee()) {
final GenericDescriptor extendee =
- file.pool.lookupSymbol(proto.getExtendee(), this);
+ file.pool.lookupSymbol(proto.getExtendee(), this,
+ DescriptorPool.SearchFilter.TYPES_ONLY);
if (!(extendee instanceof Descriptor)) {
throw new DescriptorValidationException(this,
'\"' + proto.getExtendee() + "\" is not a message type.");
@@ -952,7 +1167,8 @@ public final class Descriptors {
if (proto.hasTypeName()) {
final GenericDescriptor typeDescriptor =
- file.pool.lookupSymbol(proto.getTypeName(), this);
+ file.pool.lookupSymbol(proto.getTypeName(), this,
+ DescriptorPool.SearchFilter.TYPES_ONLY);
if (!proto.hasType()) {
// Choose field type based on symbol.
@@ -995,6 +1211,13 @@ public final class Descriptors {
}
}
+ // Only repeated primitive fields may be packed.
+ if (proto.getOptions().getPacked() && !isPackable()) {
+ throw new DescriptorValidationException(this,
+ "[packed = true] can only be specified for repeated primitive " +
+ "fields.");
+ }
+
// We don't attempt to parse the default value until here because for
// enums we need the enum type's descriptor.
if (proto.hasDefaultValue()) {
@@ -1132,16 +1355,17 @@ public final class Descriptors {
// down-cast and call mergeFrom directly.
return ((Message.Builder) to).mergeFrom((Message) from);
}
+
}
// =================================================================
/** Describes an enum type. */
- public static final class EnumDescriptor
- implements GenericDescriptor, Internal.EnumLiteMap<EnumValueDescriptor> {
+ public static final class EnumDescriptor extends GenericDescriptor
+ implements Internal.EnumLiteMap<EnumValueDescriptor> {
/**
* Get the index of this descriptor within its parent.
- * @see Descriptor#getIndex()
+ * @see Descriptors.Descriptor#getIndex()
*/
public int getIndex() { return index; }
@@ -1153,7 +1377,7 @@ public final class Descriptors {
/**
* Get the type's fully-qualified name.
- * @see Descriptor#getFullName()
+ * @see Descriptors.Descriptor#getFullName()
*/
public String getFullName() { return fullName; }
@@ -1174,7 +1398,7 @@ public final class Descriptors {
/**
* Find an enum value by name.
* @param name The unqualified name of the value (e.g. "FOO").
- * @return the value's decsriptor, or {@code null} if not found.
+ * @return the value's descriptor, or {@code null} if not found.
*/
public EnumValueDescriptor findValueByName(final String name) {
final GenericDescriptor result =
@@ -1190,7 +1414,7 @@ public final class Descriptors {
* Find an enum value by number. If multiple enum values have the same
* number, this returns the first defined value with that number.
* @param number The value's number.
- * @return the value's decsriptor, or {@code null} if not found.
+ * @return the value's descriptor, or {@code null} if not found.
*/
public EnumValueDescriptor findValueByNumber(final int number) {
return file.pool.enumValuesByNumber.get(
@@ -1249,11 +1473,11 @@ public final class Descriptors {
* with the same number after the first become aliases of the first.
* However, they still have independent EnumValueDescriptors.
*/
- public static final class EnumValueDescriptor
- implements GenericDescriptor, Internal.EnumLite {
+ public static final class EnumValueDescriptor extends GenericDescriptor
+ implements Internal.EnumLite {
/**
* Get the index of this descriptor within its parent.
- * @see Descriptor#getIndex()
+ * @see Descriptors.Descriptor#getIndex()
*/
public int getIndex() { return index; }
@@ -1265,10 +1489,13 @@ public final class Descriptors {
/** Get the value's number. */
public int getNumber() { return proto.getNumber(); }
+
+ @Override
+ public String toString() { return proto.getName(); }
/**
* Get the value's fully-qualified name.
- * @see Descriptor#getFullName()
+ * @see Descriptors.Descriptor#getFullName()
*/
public String getFullName() { return fullName; }
@@ -1314,7 +1541,7 @@ public final class Descriptors {
// =================================================================
/** Describes a service type. */
- public static final class ServiceDescriptor implements GenericDescriptor {
+ public static final class ServiceDescriptor extends GenericDescriptor {
/**
* Get the index of this descriptor within its parent.
* * @see Descriptors.Descriptor#getIndex()
@@ -1329,7 +1556,7 @@ public final class Descriptors {
/**
* Get the type's fully-qualified name.
- * @see Descriptor#getFullName()
+ * @see Descriptors.Descriptor#getFullName()
*/
public String getFullName() { return fullName; }
@@ -1347,7 +1574,7 @@ public final class Descriptors {
/**
* Find a method by name.
* @param name The unqualified name of the method (e.g. "Foo").
- * @return the method's decsriptor, or {@code null} if not found.
+ * @return the method's descriptor, or {@code null} if not found.
*/
public MethodDescriptor findMethodByName(final String name) {
final GenericDescriptor result =
@@ -1404,7 +1631,7 @@ public final class Descriptors {
/**
* Describes one method within a service type.
*/
- public static final class MethodDescriptor implements GenericDescriptor {
+ public static final class MethodDescriptor extends GenericDescriptor {
/**
* Get the index of this descriptor within its parent.
* * @see Descriptors.Descriptor#getIndex()
@@ -1419,7 +1646,7 @@ public final class Descriptors {
/**
* Get the method's fully-qualified name.
- * @see Descriptor#getFullName()
+ * @see Descriptors.Descriptor#getFullName()
*/
public String getFullName() { return fullName; }
@@ -1467,7 +1694,8 @@ public final class Descriptors {
private void crossLink() throws DescriptorValidationException {
final GenericDescriptor input =
- file.pool.lookupSymbol(proto.getInputType(), this);
+ file.pool.lookupSymbol(proto.getInputType(), this,
+ DescriptorPool.SearchFilter.TYPES_ONLY);
if (!(input instanceof Descriptor)) {
throw new DescriptorValidationException(this,
'\"' + proto.getInputType() + "\" is not a message type.");
@@ -1475,7 +1703,8 @@ public final class Descriptors {
inputType = (Descriptor)input;
final GenericDescriptor output =
- file.pool.lookupSymbol(proto.getOutputType(), this);
+ file.pool.lookupSymbol(proto.getOutputType(), this,
+ DescriptorPool.SearchFilter.TYPES_ONLY);
if (!(output instanceof Descriptor)) {
throw new DescriptorValidationException(this,
'\"' + proto.getOutputType() + "\" is not a message type.");
@@ -1506,14 +1735,18 @@ public final class Descriptors {
// =================================================================
/**
- * All descriptors except {@code FileDescriptor} implement this to make
- * {@code DescriptorPool}'s life easier.
+ * All descriptors implement this to make it easier to implement tools like
+ * {@code DescriptorPool}.<p>
+ *
+ * This class is public so that the methods it exposes can be called from
+ * outside of this package. However, it should only be subclassed from
+ * nested classes of Descriptors.
*/
- private interface GenericDescriptor {
- Message toProto();
- String getName();
- String getFullName();
- FileDescriptor getFile();
+ public abstract static class GenericDescriptor {
+ public abstract Message toProto();
+ public abstract String getName();
+ public abstract String getFullName();
+ public abstract FileDescriptor getFile();
}
/**
@@ -1527,7 +1760,7 @@ public final class Descriptors {
public String getProblemSymbolName() { return name; }
/**
- * Gets the the protocol message representation of the invalid descriptor.
+ * Gets the protocol message representation of the invalid descriptor.
*/
public Message getProblemProto() { return proto; }
@@ -1582,14 +1815,24 @@ public final class Descriptors {
* descriptors defined in a particular file.
*/
private static final class DescriptorPool {
- DescriptorPool(final FileDescriptor[] dependencies) {
- this.dependencies = new DescriptorPool[dependencies.length];
+
+ /** Defines what subclass of descriptors to search in the descriptor pool.
+ */
+ enum SearchFilter {
+ TYPES_ONLY, AGGREGATES_ONLY, ALL_SYMBOLS
+ }
+
+ DescriptorPool(final FileDescriptor[] dependencies,
+ boolean allowUnknownDependencies) {
+ this.dependencies = new HashSet<FileDescriptor>();
+ this.allowUnknownDependencies = allowUnknownDependencies;
- for (int i = 0; i < dependencies.length; i++) {
- this.dependencies[i] = dependencies[i].pool;
+ for (int i = 0; i < dependencies.length; i++) {
+ this.dependencies.add(dependencies[i]);
+ importPublicDependencies(dependencies[i]);
}
- for (final FileDescriptor dependency : dependencies) {
+ for (final FileDescriptor dependency : this.dependencies) {
try {
addPackage(dependency.getPackage(), dependency);
} catch (DescriptorValidationException e) {
@@ -1601,7 +1844,17 @@ public final class Descriptors {
}
}
- private final DescriptorPool[] dependencies;
+ /** Find and put public dependencies of the file into dependencies set.*/
+ private void importPublicDependencies(final FileDescriptor file) {
+ for (FileDescriptor dependency : file.getPublicDependencies()) {
+ if (dependencies.add(dependency)) {
+ importPublicDependencies(dependency);
+ }
+ }
+ }
+
+ private final Set<FileDescriptor> dependencies;
+ private boolean allowUnknownDependencies;
private final Map<String, GenericDescriptor> descriptorsByName =
new HashMap<String, GenericDescriptor>();
@@ -1612,39 +1865,83 @@ public final class Descriptors {
/** Find a generic descriptor by fully-qualified name. */
GenericDescriptor findSymbol(final String fullName) {
+ return findSymbol(fullName, SearchFilter.ALL_SYMBOLS);
+ }
+
+ /** Find a descriptor by fully-qualified name and given option to only
+ * search valid field type descriptors.
+ */
+ GenericDescriptor findSymbol(final String fullName,
+ final SearchFilter filter) {
GenericDescriptor result = descriptorsByName.get(fullName);
if (result != null) {
- return result;
+ if ((filter==SearchFilter.ALL_SYMBOLS) ||
+ ((filter==SearchFilter.TYPES_ONLY) && isType(result)) ||
+ ((filter==SearchFilter.AGGREGATES_ONLY) && isAggregate(result))) {
+ return result;
+ }
}
- for (final DescriptorPool dependency : dependencies) {
- result = dependency.descriptorsByName.get(fullName);
+ for (final FileDescriptor dependency : dependencies) {
+ result = dependency.pool.descriptorsByName.get(fullName);
if (result != null) {
- return result;
+ if ((filter==SearchFilter.ALL_SYMBOLS) ||
+ ((filter==SearchFilter.TYPES_ONLY) && isType(result)) ||
+ ((filter==SearchFilter.AGGREGATES_ONLY) && isAggregate(result))) {
+ return result;
+ }
}
}
return null;
}
+ /** Checks if the descriptor is a valid type for a message field. */
+ boolean isType(GenericDescriptor descriptor) {
+ return (descriptor instanceof Descriptor) ||
+ (descriptor instanceof EnumDescriptor);
+ }
+
+ /** Checks if the descriptor is a valid namespace type. */
+ boolean isAggregate(GenericDescriptor descriptor) {
+ return (descriptor instanceof Descriptor) ||
+ (descriptor instanceof EnumDescriptor) ||
+ (descriptor instanceof PackageDescriptor) ||
+ (descriptor instanceof ServiceDescriptor);
+ }
+
/**
- * Look up a descriptor by name, relative to some other descriptor.
+ * Look up a type descriptor by name, relative to some other descriptor.
* The name may be fully-qualified (with a leading '.'),
* partially-qualified, or unqualified. C++-like name lookup semantics
* are used to search for the matching descriptor.
*/
GenericDescriptor lookupSymbol(final String name,
- final GenericDescriptor relativeTo)
+ final GenericDescriptor relativeTo,
+ final DescriptorPool.SearchFilter filter)
throws DescriptorValidationException {
// TODO(kenton): This could be optimized in a number of ways.
GenericDescriptor result;
+ String fullname;
if (name.startsWith(".")) {
// Fully-qualified name.
- result = findSymbol(name.substring(1));
+ fullname = name.substring(1);
+ result = findSymbol(fullname, filter);
} else {
// If "name" is a compound identifier, we want to search for the
// first component of it, then search within it for the rest.
+ // If name is something like "Foo.Bar.baz", and symbols named "Foo" are
+ // defined in multiple parent scopes, we only want to find "Bar.baz" in
+ // the innermost one. E.g., the following should produce an error:
+ // message Bar { message Baz {} }
+ // message Foo {
+ // message Bar {
+ // }
+ // optional Bar.Baz baz = 1;
+ // }
+ // So, we look for just "Foo" first, then look for "Bar.baz" within it
+ // if found.
final int firstPartLength = name.indexOf('.');
final String firstPart;
if (firstPartLength == -1) {
@@ -1662,14 +1959,16 @@ public final class Descriptors {
// Chop off the last component of the scope.
final int dotpos = scopeToTry.lastIndexOf(".");
if (dotpos == -1) {
- result = findSymbol(name);
+ fullname = name;
+ result = findSymbol(name, filter);
break;
} else {
scopeToTry.setLength(dotpos + 1);
- // Append firstPart and try to find.
+ // Append firstPart and try to find
scopeToTry.append(firstPart);
- result = findSymbol(scopeToTry.toString());
+ result = findSymbol(scopeToTry.toString(),
+ DescriptorPool.SearchFilter.AGGREGATES_ONLY);
if (result != null) {
if (firstPartLength != -1) {
@@ -1678,8 +1977,9 @@ public final class Descriptors {
// searching parent scopes.
scopeToTry.setLength(dotpos + 1);
scopeToTry.append(name);
- result = findSymbol(scopeToTry.toString());
+ result = findSymbol(scopeToTry.toString(), filter);
}
+ fullname = scopeToTry.toString();
break;
}
@@ -1690,8 +1990,24 @@ public final class Descriptors {
}
if (result == null) {
- throw new DescriptorValidationException(relativeTo,
- '\"' + name + "\" is not defined.");
+ if (allowUnknownDependencies && filter == SearchFilter.TYPES_ONLY) {
+ logger.warning("The descriptor for message type \"" + name +
+ "\" can not be found and a placeholder is created for it");
+ // We create a dummy message descriptor here regardless of the
+ // expected type. If the type should be message, this dummy
+ // descriptor will work well and if the type should be enum, a
+ // DescriptorValidationException will be thrown latter. In either
+ // case, the code works as expected: we allow unknown message types
+ // but not unknwon enum types.
+ result = new Descriptor(fullname);
+ // Add the placeholder file as a dependency so we can find the
+ // placeholder symbol when resolving other references.
+ this.dependencies.add(result.getFile());
+ return result;
+ } else {
+ throw new DescriptorValidationException(relativeTo,
+ '\"' + name + "\" is not defined.");
+ }
} else {
return result;
}
@@ -1735,7 +2051,7 @@ public final class Descriptors {
* just as placeholders so that someone cannot define, say, a message type
* that has the same name as an existing package.
*/
- private static final class PackageDescriptor implements GenericDescriptor {
+ private static final class PackageDescriptor extends GenericDescriptor {
public Message toProto() { return file.toProto(); }
public String getName() { return name; }
public String getFullName() { return fullName; }
@@ -1809,7 +2125,7 @@ public final class Descriptors {
/**
* Adds a field to the fieldsByNumber table. Throws an exception if a
- * field with hte same containing type and number already exists.
+ * field with the same containing type and number already exists.
*/
void addFieldByNumber(final FieldDescriptor field)
throws DescriptorValidationException {
@@ -1820,7 +2136,7 @@ public final class Descriptors {
fieldsByNumber.put(key, old);
throw new DescriptorValidationException(field,
"Field number " + field.getNumber() +
- "has already been used in \"" +
+ " has already been used in \"" +
field.getContainingType().getFullName() +
"\" by field \"" + old.getName() + "\".");
}
@@ -1876,4 +2192,47 @@ public final class Descriptors {
}
}
}
+
+ /** Describes an oneof of a message type. */
+ public static final class OneofDescriptor {
+ /** Get the index of this descriptor within its parent. */
+ public int getIndex() { return index; }
+
+ public String getName() { return proto.getName(); }
+
+ public FileDescriptor getFile() { return file; }
+
+ public String getFullName() { return fullName; }
+
+ public Descriptor getContainingType() { return containingType; }
+
+ public int getFieldCount() { return fieldCount; }
+
+ public FieldDescriptor getField(int index) {
+ return fields[index];
+ }
+
+ private OneofDescriptor(final OneofDescriptorProto proto,
+ final FileDescriptor file,
+ final Descriptor parent,
+ final int index)
+ throws DescriptorValidationException {
+ this.proto = proto;
+ fullName = computeFullName(file, parent, proto.getName());
+ this.file = file;
+ this.index = index;
+
+ containingType = parent;
+ fieldCount = 0;
+ }
+
+ private final int index;
+ private OneofDescriptorProto proto;
+ private final String fullName;
+ private final FileDescriptor file;
+
+ private Descriptor containingType;
+ private int fieldCount;
+ private FieldDescriptor[] fields;
+ }
}
diff --git a/java/src/main/java/com/google/protobuf/DynamicMessage.java b/java/src/main/java/com/google/protobuf/DynamicMessage.java
index c106b66..c9ce667 100644
--- a/java/src/main/java/com/google/protobuf/DynamicMessage.java
+++ b/java/src/main/java/com/google/protobuf/DynamicMessage.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -31,10 +31,14 @@
package com.google.protobuf;
import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.OneofDescriptor;
import java.io.InputStream;
import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
/**
@@ -46,16 +50,25 @@ import java.util.Map;
public final class DynamicMessage extends AbstractMessage {
private final Descriptor type;
private final FieldSet<FieldDescriptor> fields;
+ private final FieldDescriptor[] oneofCases;
private final UnknownFieldSet unknownFields;
private int memoizedSize = -1;
/**
* Construct a {@code DynamicMessage} using the given {@code FieldSet}.
+ * oneofCases stores the FieldDescriptor for each oneof to indicate
+ * which field is set. Caller should make sure the array is immutable.
+ *
+ * This contructor is package private and will be used in
+ * {@code DynamicMutableMessage} to convert a mutable message to an immutable
+ * message.
*/
- private DynamicMessage(Descriptor type, FieldSet<FieldDescriptor> fields,
- UnknownFieldSet unknownFields) {
+ DynamicMessage(Descriptor type, FieldSet<FieldDescriptor> fields,
+ FieldDescriptor[] oneofCases,
+ UnknownFieldSet unknownFields) {
this.type = type;
this.fields = fields;
+ this.oneofCases = oneofCases;
this.unknownFields = unknownFields;
}
@@ -64,10 +77,14 @@ public final class DynamicMessage extends AbstractMessage {
* given type.
*/
public static DynamicMessage getDefaultInstance(Descriptor type) {
+ int oneofDeclCount = type.toProto().getOneofDeclCount();
+ FieldDescriptor[] oneofCases = new FieldDescriptor[oneofDeclCount];
return new DynamicMessage(type, FieldSet.<FieldDescriptor>emptySet(),
+ oneofCases,
UnknownFieldSet.getDefaultInstance());
}
+
/** Parse a message of the given type from the given input stream. */
public static DynamicMessage parseFrom(Descriptor type,
CodedInputStream input)
@@ -151,6 +168,20 @@ public final class DynamicMessage extends AbstractMessage {
return fields.getAllFields();
}
+ public boolean hasOneof(OneofDescriptor oneof) {
+ verifyOneofContainingType(oneof);
+ FieldDescriptor field = oneofCases[oneof.getIndex()];
+ if (field == null) {
+ return false;
+ }
+ return true;
+ }
+
+ public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
+ verifyOneofContainingType(oneof);
+ return oneofCases[oneof.getIndex()];
+ }
+
public boolean hasField(FieldDescriptor field) {
verifyContainingType(field);
return fields.hasField(field);
@@ -160,7 +191,9 @@ public final class DynamicMessage extends AbstractMessage {
verifyContainingType(field);
Object result = fields.getField(field);
if (result == null) {
- if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (field.isRepeated()) {
+ result = Collections.emptyList();
+ } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
result = getDefaultInstance(field.getMessageType());
} else {
result = field.getDefaultValue();
@@ -183,8 +216,8 @@ public final class DynamicMessage extends AbstractMessage {
return unknownFields;
}
- private static boolean isInitialized(Descriptor type,
- FieldSet<FieldDescriptor> fields) {
+ static boolean isInitialized(Descriptor type,
+ FieldSet<FieldDescriptor> fields) {
// Check that all required fields are present.
for (final FieldDescriptor field : type.getFields()) {
if (field.isRequired()) {
@@ -198,10 +231,12 @@ public final class DynamicMessage extends AbstractMessage {
return fields.isInitialized();
}
+ @Override
public boolean isInitialized() {
return isInitialized(type, fields);
}
+ @Override
public void writeTo(CodedOutputStream output) throws IOException {
if (type.getOptions().getMessageSetWireFormat()) {
fields.writeMessageSetTo(output);
@@ -212,6 +247,7 @@ public final class DynamicMessage extends AbstractMessage {
}
}
+ @Override
public int getSerializedSize() {
int size = memoizedSize;
if (size != -1) return size;
@@ -236,6 +272,26 @@ public final class DynamicMessage extends AbstractMessage {
return newBuilderForType().mergeFrom(this);
}
+ public Parser<DynamicMessage> getParserForType() {
+ return new AbstractParser<DynamicMessage>() {
+ public DynamicMessage parsePartialFrom(
+ CodedInputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ Builder builder = newBuilder(type);
+ try {
+ builder.mergeFrom(input, extensionRegistry);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(builder.buildPartial());
+ } catch (IOException e) {
+ throw new InvalidProtocolBufferException(e.getMessage())
+ .setUnfinishedMessage(builder.buildPartial());
+ }
+ return builder.buildPartial();
+ }
+ };
+ }
+
/** Verifies that the field is a field of this message. */
private void verifyContainingType(FieldDescriptor field) {
if (field.getContainingType() != type) {
@@ -244,6 +300,14 @@ public final class DynamicMessage extends AbstractMessage {
}
}
+ /** Verifies that the oneof is an oneof of this message. */
+ private void verifyOneofContainingType(OneofDescriptor oneof) {
+ if (oneof.getContainingType() != type) {
+ throw new IllegalArgumentException(
+ "OneofDescriptor does not match message type.");
+ }
+ }
+
// =================================================================
/**
@@ -252,6 +316,7 @@ public final class DynamicMessage extends AbstractMessage {
public static final class Builder extends AbstractMessage.Builder<Builder> {
private final Descriptor type;
private FieldSet<FieldDescriptor> fields;
+ private final FieldDescriptor[] oneofCases;
private UnknownFieldSet unknownFields;
/** Construct a {@code Builder} for the given type. */
@@ -259,19 +324,24 @@ public final class DynamicMessage extends AbstractMessage {
this.type = type;
this.fields = FieldSet.newFieldSet();
this.unknownFields = UnknownFieldSet.getDefaultInstance();
+ this.oneofCases = new FieldDescriptor[type.toProto().getOneofDeclCount()];
}
// ---------------------------------------------------------------
// Implementation of Message.Builder interface.
+ @Override
public Builder clear() {
- if (fields == null) {
- throw new IllegalStateException("Cannot call clear() after build().");
+ if (fields.isImmutable()) {
+ fields = FieldSet.newFieldSet();
+ } else {
+ fields.clear();
}
- fields.clear();
+ unknownFields = UnknownFieldSet.getDefaultInstance();
return this;
}
+ @Override
public Builder mergeFrom(Message other) {
if (other instanceof DynamicMessage) {
// This should be somewhat faster than calling super.mergeFrom().
@@ -280,8 +350,20 @@ public final class DynamicMessage extends AbstractMessage {
throw new IllegalArgumentException(
"mergeFrom(Message) can only merge messages of the same type.");
}
+ ensureIsMutable();
fields.mergeFrom(otherDynamicMessage.fields);
mergeUnknownFields(otherDynamicMessage.unknownFields);
+ for (int i = 0; i < oneofCases.length; i++) {
+ if (oneofCases[i] == null) {
+ oneofCases[i] = otherDynamicMessage.oneofCases[i];
+ } else {
+ if ((otherDynamicMessage.oneofCases[i] != null)
+ && (oneofCases[i] != otherDynamicMessage.oneofCases[i])) {
+ fields.clearField(oneofCases[i]);
+ oneofCases[i] = otherDynamicMessage.oneofCases[i];
+ }
+ }
+ }
return this;
} else {
return super.mergeFrom(other);
@@ -289,10 +371,10 @@ public final class DynamicMessage extends AbstractMessage {
}
public DynamicMessage build() {
- // If fields == null, we'll throw an appropriate exception later.
- if (fields != null && !isInitialized()) {
+ if (!isInitialized()) {
throw newUninitializedMessageException(
- new DynamicMessage(type, fields, unknownFields));
+ new DynamicMessage(type, fields,
+ java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields));
}
return buildPartial();
}
@@ -305,28 +387,27 @@ public final class DynamicMessage extends AbstractMessage {
private DynamicMessage buildParsed() throws InvalidProtocolBufferException {
if (!isInitialized()) {
throw newUninitializedMessageException(
- new DynamicMessage(type, fields, unknownFields))
+ new DynamicMessage(type, fields,
+ java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields))
.asInvalidProtocolBufferException();
}
return buildPartial();
}
public DynamicMessage buildPartial() {
- if (fields == null) {
- throw new IllegalStateException(
- "build() has already been called on this Builder.");
- }
fields.makeImmutable();
DynamicMessage result =
- new DynamicMessage(type, fields, unknownFields);
- fields = null;
- unknownFields = null;
+ new DynamicMessage(type, fields,
+ java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields);
return result;
}
+ @Override
public Builder clone() {
Builder result = new Builder(type);
result.fields.mergeFrom(fields);
+ result.mergeUnknownFields(unknownFields);
+ System.arraycopy(oneofCases, 0, result.oneofCases, 0 , oneofCases.length);
return result;
}
@@ -357,6 +438,29 @@ public final class DynamicMessage extends AbstractMessage {
return new Builder(field.getMessageType());
}
+ public boolean hasOneof(OneofDescriptor oneof) {
+ verifyOneofContainingType(oneof);
+ FieldDescriptor field = oneofCases[oneof.getIndex()];
+ if (field == null) {
+ return false;
+ }
+ return true;
+ }
+
+ public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
+ verifyOneofContainingType(oneof);
+ return oneofCases[oneof.getIndex()];
+ }
+
+ public Builder clearOneof(OneofDescriptor oneof) {
+ verifyOneofContainingType(oneof);
+ FieldDescriptor field = oneofCases[oneof.getIndex()];
+ if (field != null) {
+ clearField(field);
+ }
+ return this;
+ }
+
public boolean hasField(FieldDescriptor field) {
verifyContainingType(field);
return fields.hasField(field);
@@ -366,7 +470,9 @@ public final class DynamicMessage extends AbstractMessage {
verifyContainingType(field);
Object result = fields.getField(field);
if (result == null) {
- if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (field.isRepeated()) {
+ result = Collections.emptyList();
+ } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
result = getDefaultInstance(field.getMessageType());
} else {
result = field.getDefaultValue();
@@ -377,12 +483,38 @@ public final class DynamicMessage extends AbstractMessage {
public Builder setField(FieldDescriptor field, Object value) {
verifyContainingType(field);
+ ensureIsMutable();
+ // TODO(xiaofeng): This check should really be put in FieldSet.setField()
+ // where all other such checks are done. However, currently
+ // FieldSet.setField() permits Integer value for enum fields probably
+ // because of some internal features we support. Should figure it out
+ // and move this check to a more appropriate place.
+ if (field.getType() == FieldDescriptor.Type.ENUM) {
+ ensureEnumValueDescriptor(field, value);
+ }
+ OneofDescriptor oneofDescriptor = field.getContainingOneof();
+ if (oneofDescriptor != null) {
+ int index = oneofDescriptor.getIndex();
+ FieldDescriptor oldField = oneofCases[index];
+ if ((oldField != null) && (oldField != field)) {
+ fields.clearField(oldField);
+ }
+ oneofCases[index] = field;
+ }
fields.setField(field, value);
return this;
}
public Builder clearField(FieldDescriptor field) {
verifyContainingType(field);
+ ensureIsMutable();
+ OneofDescriptor oneofDescriptor = field.getContainingOneof();
+ if (oneofDescriptor != null) {
+ int index = oneofDescriptor.getIndex();
+ if (oneofCases[index] == field) {
+ oneofCases[index] = null;
+ }
+ }
fields.clearField(field);
return this;
}
@@ -400,12 +532,14 @@ public final class DynamicMessage extends AbstractMessage {
public Builder setRepeatedField(FieldDescriptor field,
int index, Object value) {
verifyContainingType(field);
+ ensureIsMutable();
fields.setRepeatedField(field, index, value);
return this;
}
public Builder addRepeatedField(FieldDescriptor field, Object value) {
verifyContainingType(field);
+ ensureIsMutable();
fields.addRepeatedField(field, value);
return this;
}
@@ -419,6 +553,7 @@ public final class DynamicMessage extends AbstractMessage {
return this;
}
+ @Override
public Builder mergeUnknownFields(UnknownFieldSet unknownFields) {
this.unknownFields =
UnknownFieldSet.newBuilder(this.unknownFields)
@@ -434,5 +569,54 @@ public final class DynamicMessage extends AbstractMessage {
"FieldDescriptor does not match message type.");
}
}
+
+ /** Verifies that the oneof is an oneof of this message. */
+ private void verifyOneofContainingType(OneofDescriptor oneof) {
+ if (oneof.getContainingType() != type) {
+ throw new IllegalArgumentException(
+ "OneofDescriptor does not match message type.");
+ }
+ }
+
+ /** Verifies that the value is EnumValueDescriptor and matches Enum Type. */
+ private void ensureSingularEnumValueDescriptor(
+ FieldDescriptor field, Object value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ if (!(value instanceof EnumValueDescriptor)) {
+ throw new IllegalArgumentException(
+ "DynamicMessage should use EnumValueDescriptor to set Enum Value.");
+ }
+ if (field.getEnumType() != ((EnumValueDescriptor) value).getType()) {
+ throw new IllegalArgumentException(
+ "EnumValueDescriptor doesn't much Enum Field.");
+ }
+ }
+
+ /** Verifies the value for an enum field. */
+ private void ensureEnumValueDescriptor(
+ FieldDescriptor field, Object value) {
+ if (field.isRepeated()) {
+ for (Object item : (List) value) {
+ ensureSingularEnumValueDescriptor(field, item);
+ }
+ } else {
+ ensureSingularEnumValueDescriptor(field, value);
+ }
+ }
+
+ private void ensureIsMutable() {
+ if (fields.isImmutable()) {
+ fields = fields.clone();
+ }
+ }
+
+ @Override
+ public com.google.protobuf.Message.Builder getFieldBuilder(FieldDescriptor field) {
+ // TODO(xiangl): need implementation for dynamic message
+ throw new UnsupportedOperationException(
+ "getFieldBuilder() called on a dynamic message type.");
+ }
}
}
diff --git a/java/src/main/java/com/google/protobuf/Extension.java b/java/src/main/java/com/google/protobuf/Extension.java
new file mode 100644
index 0000000..0baa22b
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/Extension.java
@@ -0,0 +1,96 @@
+// 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;
+
+/**
+ * Interface that generated extensions implement.
+ *
+ * @author liujisi@google.com (Jisi Liu)
+ */
+public abstract class Extension<ContainingType extends MessageLite, Type> {
+ /** Returns the field number of the extension. */
+ public abstract int getNumber();
+
+ /** Returns the type of the field. */
+ public abstract WireFormat.FieldType getLiteType();
+
+ /** Returns whether it is a repeated field. */
+ public abstract boolean isRepeated();
+
+ /** Returns the descriptor of the extension. */
+ public abstract Descriptors.FieldDescriptor getDescriptor();
+
+ /** Returns the default value of the extension field. */
+ public abstract Type getDefaultValue();
+
+ /**
+ * Returns the default instance of the extension field, if it's a message
+ * extension.
+ */
+ public abstract MessageLite getMessageDefaultInstance();
+
+ // All the methods below are extension implementation details.
+
+ /**
+ * The API type that the extension is used for.
+ */
+ protected enum ExtensionType {
+ IMMUTABLE,
+ MUTABLE,
+ PROTO1,
+ }
+
+ protected ExtensionType getExtensionType() {
+ // TODO(liujisi): make this abstract after we fix proto1.
+ return ExtensionType.IMMUTABLE;
+ }
+
+ /**
+ * Type of a message extension.
+ */
+ public enum MessageType {
+ PROTO1,
+ PROTO2,
+ }
+
+ /**
+ * If the extension is a message extension (i.e., getLiteType() == MESSAGE),
+ * returns the type of the message, otherwise undefined.
+ */
+ public MessageType getMessageType() {
+ return MessageType.PROTO2;
+ }
+
+ protected abstract Object fromReflectionType(Object value);
+ protected abstract Object singularFromReflectionType(Object value);
+ protected abstract Object toReflectionType(Object value);
+ protected abstract Object singularToReflectionType(Object value);
+}
diff --git a/java/src/main/java/com/google/protobuf/ExtensionRegistry.java b/java/src/main/java/com/google/protobuf/ExtensionRegistry.java
index d4f6ba9..0067392 100644
--- a/java/src/main/java/com/google/protobuf/ExtensionRegistry.java
+++ b/java/src/main/java/com/google/protobuf/ExtensionRegistry.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,9 +33,12 @@ package com.google.protobuf;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
/**
* A table of known extensions, searchable by name or field number. When
@@ -90,7 +93,7 @@ import java.util.Map;
*
* @author kenton@google.com Kenton Varda
*/
-public final class ExtensionRegistry extends ExtensionRegistryLite {
+public class ExtensionRegistry extends ExtensionRegistryLite {
/** Construct a new, empty instance. */
public static ExtensionRegistry newInstance() {
return new ExtensionRegistry();
@@ -101,6 +104,7 @@ public final class ExtensionRegistry extends ExtensionRegistryLite {
return EMPTY;
}
+
/** Returns an unmodifiable view of the registry. */
@Override
public ExtensionRegistry getUnmodifiable() {
@@ -130,42 +134,127 @@ public final class ExtensionRegistry extends ExtensionRegistryLite {
}
/**
- * Find an extension by fully-qualified field name, in the proto namespace.
- * I.e. {@code result.descriptor.fullName()} will match {@code fullName} if
- * a match is found.
+ * Deprecated. Use {@link #findImmutableExtensionByName(String)} instead.
+ */
+ public ExtensionInfo findExtensionByName(final String fullName) {
+ return findImmutableExtensionByName(fullName);
+ }
+
+ /**
+ * Find an extension for immutable APIs by fully-qualified field name,
+ * in the proto namespace. i.e. {@code result.descriptor.fullName()} will
+ * match {@code fullName} if a match is found.
*
* @return Information about the extension if found, or {@code null}
* otherwise.
*/
- public ExtensionInfo findExtensionByName(final String fullName) {
- return extensionsByName.get(fullName);
+ public ExtensionInfo findImmutableExtensionByName(final String fullName) {
+ return immutableExtensionsByName.get(fullName);
+ }
+
+ /**
+ * Find an extension for mutable APIs by fully-qualified field name,
+ * in the proto namespace. i.e. {@code result.descriptor.fullName()} will
+ * match {@code fullName} if a match is found.
+ *
+ * @return Information about the extension if found, or {@code null}
+ * otherwise.
+ */
+ public ExtensionInfo findMutableExtensionByName(final String fullName) {
+ return mutableExtensionsByName.get(fullName);
}
/**
- * Find an extension by containing type and field number.
+ * Deprecated. Use {@link #findImmutableExtensionByNumber(
+ * Descriptors.Descriptor, int)}
+ */
+ public ExtensionInfo findExtensionByNumber(
+ final Descriptor containingType, final int fieldNumber) {
+ return findImmutableExtensionByNumber(containingType, fieldNumber);
+ }
+
+ /**
+ * Find an extension by containing type and field number for immutable APIs.
*
* @return Information about the extension if found, or {@code null}
* otherwise.
*/
- public ExtensionInfo findExtensionByNumber(final Descriptor containingType,
- final int fieldNumber) {
- return extensionsByNumber.get(
+ public ExtensionInfo findImmutableExtensionByNumber(
+ final Descriptor containingType, final int fieldNumber) {
+ return immutableExtensionsByNumber.get(
new DescriptorIntPair(containingType, fieldNumber));
}
+ /**
+ * Find an extension by containing type and field number for mutable APIs.
+ *
+ * @return Information about the extension if found, or {@code null}
+ * otherwise.
+ */
+ public ExtensionInfo findMutableExtensionByNumber(
+ final Descriptor containingType, final int fieldNumber) {
+ return mutableExtensionsByNumber.get(
+ new DescriptorIntPair(containingType, fieldNumber));
+ }
+
+ /**
+ * Find all extensions for mutable APIs by fully-qualified name of
+ * extended class. Note that this method is more computationally expensive
+ * than getting a single extension by name or number.
+ *
+ * @return Information about the extensions found, or {@code null} if there
+ * are none.
+ */
+ public Set<ExtensionInfo> getAllMutableExtensionsByExtendedType(final String fullName) {
+ HashSet<ExtensionInfo> extensions = new HashSet<ExtensionInfo>();
+ for (DescriptorIntPair pair : mutableExtensionsByNumber.keySet()) {
+ if (pair.descriptor.getFullName().equals(fullName)) {
+ extensions.add(mutableExtensionsByNumber.get(pair));
+ }
+ }
+ return extensions;
+ }
+
+ /**
+ * Find all extensions for immutable APIs by fully-qualified name of
+ * extended class. Note that this method is more computationally expensive
+ * than getting a single extension by name or number.
+ *
+ * @return Information about the extensions found, or {@code null} if there
+ * are none.
+ */
+ public Set<ExtensionInfo> getAllImmutableExtensionsByExtendedType(final String fullName) {
+ HashSet<ExtensionInfo> extensions = new HashSet<ExtensionInfo>();
+ for (DescriptorIntPair pair : immutableExtensionsByNumber.keySet()) {
+ if (pair.descriptor.getFullName().equals(fullName)) {
+ extensions.add(immutableExtensionsByNumber.get(pair));
+ }
+ }
+ return extensions;
+ }
+
/** Add an extension from a generated file to the registry. */
- public void add(final GeneratedMessage.GeneratedExtension<?, ?> extension) {
+ public void add(final Extension<?, ?> extension) {
+ if (extension.getExtensionType() != Extension.ExtensionType.IMMUTABLE &&
+ extension.getExtensionType() != Extension.ExtensionType.MUTABLE) {
+ // do not support other extension types. ignore
+ return;
+ }
+ add(newExtensionInfo(extension), extension.getExtensionType());
+ }
+
+ static ExtensionInfo newExtensionInfo(final Extension<?, ?> extension) {
if (extension.getDescriptor().getJavaType() ==
FieldDescriptor.JavaType.MESSAGE) {
if (extension.getMessageDefaultInstance() == null) {
throw new IllegalStateException(
"Registered message-type extension had null default instance: " +
- extension.getDescriptor().getFullName());
+ extension.getDescriptor().getFullName());
}
- add(new ExtensionInfo(extension.getDescriptor(),
- extension.getMessageDefaultInstance()));
+ return new ExtensionInfo(extension.getDescriptor(),
+ (Message) extension.getMessageDefaultInstance());
} else {
- add(new ExtensionInfo(extension.getDescriptor(), null));
+ return new ExtensionInfo(extension.getDescriptor(), null);
}
}
@@ -176,7 +265,9 @@ public final class ExtensionRegistry extends ExtensionRegistryLite {
"ExtensionRegistry.add() must be provided a default instance when " +
"adding an embedded message extension.");
}
- add(new ExtensionInfo(type, null));
+ ExtensionInfo info = new ExtensionInfo(type, null);
+ add(info, Extension.ExtensionType.IMMUTABLE);
+ add(info, Extension.ExtensionType.MUTABLE);
}
/** Add a message-type extension to the registry by descriptor. */
@@ -186,40 +277,75 @@ public final class ExtensionRegistry extends ExtensionRegistryLite {
"ExtensionRegistry.add() provided a default instance for a " +
"non-message extension.");
}
- add(new ExtensionInfo(type, defaultInstance));
+ add(new ExtensionInfo(type, defaultInstance),
+ Extension.ExtensionType.IMMUTABLE);
}
// =================================================================
// Private stuff.
private ExtensionRegistry() {
- this.extensionsByName = new HashMap<String, ExtensionInfo>();
- this.extensionsByNumber = new HashMap<DescriptorIntPair, ExtensionInfo>();
+ this.immutableExtensionsByName = new HashMap<String, ExtensionInfo>();
+ this.mutableExtensionsByName = new HashMap<String, ExtensionInfo>();
+ this.immutableExtensionsByNumber =
+ new HashMap<DescriptorIntPair, ExtensionInfo>();
+ this.mutableExtensionsByNumber =
+ new HashMap<DescriptorIntPair, ExtensionInfo>();
}
private ExtensionRegistry(ExtensionRegistry other) {
super(other);
- this.extensionsByName = Collections.unmodifiableMap(other.extensionsByName);
- this.extensionsByNumber =
- Collections.unmodifiableMap(other.extensionsByNumber);
+ this.immutableExtensionsByName =
+ Collections.unmodifiableMap(other.immutableExtensionsByName);
+ this.mutableExtensionsByName =
+ Collections.unmodifiableMap(other.mutableExtensionsByName);
+ this.immutableExtensionsByNumber =
+ Collections.unmodifiableMap(other.immutableExtensionsByNumber);
+ this.mutableExtensionsByNumber =
+ Collections.unmodifiableMap(other.mutableExtensionsByNumber);
}
- private final Map<String, ExtensionInfo> extensionsByName;
- private final Map<DescriptorIntPair, ExtensionInfo> extensionsByNumber;
+ private final Map<String, ExtensionInfo> immutableExtensionsByName;
+ private final Map<String, ExtensionInfo> mutableExtensionsByName;
+ private final Map<DescriptorIntPair, ExtensionInfo> immutableExtensionsByNumber;
+ private final Map<DescriptorIntPair, ExtensionInfo> mutableExtensionsByNumber;
- private ExtensionRegistry(boolean empty) {
+ ExtensionRegistry(boolean empty) {
super(ExtensionRegistryLite.getEmptyRegistry());
- this.extensionsByName = Collections.<String, ExtensionInfo>emptyMap();
- this.extensionsByNumber =
+ this.immutableExtensionsByName =
+ Collections.<String, ExtensionInfo>emptyMap();
+ this.mutableExtensionsByName =
+ Collections.<String, ExtensionInfo>emptyMap();
+ this.immutableExtensionsByNumber =
Collections.<DescriptorIntPair, ExtensionInfo>emptyMap();
+ this.mutableExtensionsByNumber =
+ Collections.<DescriptorIntPair, ExtensionInfo>emptyMap();
}
private static final ExtensionRegistry EMPTY = new ExtensionRegistry(true);
- private void add(final ExtensionInfo extension) {
+ private void add(
+ final ExtensionInfo extension,
+ final Extension.ExtensionType extensionType) {
if (!extension.descriptor.isExtension()) {
throw new IllegalArgumentException(
- "ExtensionRegistry.add() was given a FieldDescriptor for a regular " +
- "(non-extension) field.");
+ "ExtensionRegistry.add() was given a FieldDescriptor for a regular " +
+ "(non-extension) field.");
+ }
+
+ Map<String, ExtensionInfo> extensionsByName;
+ Map<DescriptorIntPair, ExtensionInfo> extensionsByNumber;
+ switch (extensionType) {
+ case IMMUTABLE:
+ extensionsByName = immutableExtensionsByName;
+ extensionsByNumber = immutableExtensionsByNumber;
+ break;
+ case MUTABLE:
+ extensionsByName = mutableExtensionsByName;
+ extensionsByNumber = mutableExtensionsByNumber;
+ break;
+ default:
+ // Ignore the unknown supported type.
+ return;
}
extensionsByName.put(extension.descriptor.getFullName(), extension);
diff --git a/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java b/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
index d5288dd..65cf738 100644
--- a/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
+++ b/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -43,7 +43,7 @@ import java.util.Map;
* make sense to mix the two, since if you have any regular types in your
* program, you then require the full runtime and lose all the benefits of
* the lite runtime, so you might as well make all your types be regular types.
- * However, in some cases (e.g. when depending on multiple third-patry libraries
+ * However, in some cases (e.g. when depending on multiple third-party libraries
* where one uses lite types and one uses regular), you may find yourself
* wanting to mix the two. In this case things get more complicated.
* <p>
@@ -71,6 +71,22 @@ import java.util.Map;
* @author kenton@google.com Kenton Varda
*/
public class ExtensionRegistryLite {
+
+ // Set true to enable lazy parsing feature for MessageSet.
+ //
+ // TODO(xiangl): Now we use a global flag to control whether enable lazy
+ // parsing feature for MessageSet, which may be too crude for some
+ // applications. Need to support this feature on smaller granularity.
+ private static volatile boolean eagerlyParseMessageSets = false;
+
+ public static boolean isEagerlyParseMessageSets() {
+ return eagerlyParseMessageSets;
+ }
+
+ public static void setEagerlyParseMessageSets(boolean isEagerlyParse) {
+ eagerlyParseMessageSets = isEagerlyParse;
+ }
+
/** Construct a new, empty instance. */
public static ExtensionRegistryLite newInstance() {
return new ExtensionRegistryLite();
diff --git a/java/src/main/java/com/google/protobuf/FieldSet.java b/java/src/main/java/com/google/protobuf/FieldSet.java
index 93e55f2..392f4ef 100644
--- a/java/src/main/java/com/google/protobuf/FieldSet.java
+++ b/java/src/main/java/com/google/protobuf/FieldSet.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -30,13 +30,14 @@
package com.google.protobuf;
+import com.google.protobuf.LazyField.LazyIterator;
+
+import java.io.IOException;
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.io.IOException;
/**
* A class which represents an arbitrary set of fields of some message type.
@@ -67,16 +68,13 @@ final class FieldSet<FieldDescriptorType extends
MessageLite.Builder to, MessageLite from);
}
- private Map<FieldDescriptorType, Object> fields;
+ private final SmallSortedMap<FieldDescriptorType, Object> fields;
+ private boolean isImmutable;
+ private boolean hasLazyField = false;
/** Construct a new FieldSet. */
private FieldSet() {
- // Use a TreeMap because fields need to be in canonical order when
- // serializing.
- // TODO(kenton): Maybe use some sort of sparse array instead? It would
- // even make sense to store the first 16 or so tags in a flat array
- // to make DynamicMessage faster.
- fields = new TreeMap<FieldDescriptorType, Object>();
+ this.fields = SmallSortedMap.newFieldMap(16);
}
/**
@@ -84,7 +82,8 @@ final class FieldSet<FieldDescriptorType extends
* DEFAULT_INSTANCE.
*/
private FieldSet(final boolean dummy) {
- this.fields = Collections.emptyMap();
+ this.fields = SmallSortedMap.newFieldMap(0);
+ makeImmutable();
}
/** Construct a new FieldSet. */
@@ -99,41 +98,106 @@ final class FieldSet<FieldDescriptorType extends
FieldSet<T> emptySet() {
return DEFAULT_INSTANCE;
}
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("rawtypes")
private static final FieldSet DEFAULT_INSTANCE = new FieldSet(true);
/** Make this FieldSet immutable from this point forward. */
@SuppressWarnings("unchecked")
public void makeImmutable() {
- for (final Map.Entry<FieldDescriptorType, Object> entry:
- fields.entrySet()) {
- if (entry.getKey().isRepeated()) {
- final List value = (List)entry.getValue();
- fields.put(entry.getKey(), Collections.unmodifiableList(value));
- }
+ if (isImmutable) {
+ return;
+ }
+ fields.makeImmutable();
+ isImmutable = true;
+ }
+
+ /**
+ * Returns whether the FieldSet is immutable. This is true if it is the
+ * {@link #emptySet} or if {@link #makeImmutable} were called.
+ *
+ * @return whether the FieldSet is immutable.
+ */
+ public boolean isImmutable() {
+ return isImmutable;
+ }
+
+ /**
+ * Clones the FieldSet. The returned FieldSet will be mutable even if the
+ * original FieldSet was immutable.
+ *
+ * @return the newly cloned FieldSet
+ */
+ @Override
+ public FieldSet<FieldDescriptorType> clone() {
+ // We can't just call fields.clone because List objects in the map
+ // should not be shared.
+ FieldSet<FieldDescriptorType> clone = FieldSet.newFieldSet();
+ for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+ Map.Entry<FieldDescriptorType, Object> entry = fields.getArrayEntryAt(i);
+ FieldDescriptorType descriptor = entry.getKey();
+ clone.setField(descriptor, entry.getValue());
+ }
+ for (Map.Entry<FieldDescriptorType, Object> entry :
+ fields.getOverflowEntries()) {
+ FieldDescriptorType descriptor = entry.getKey();
+ clone.setField(descriptor, entry.getValue());
}
- fields = Collections.unmodifiableMap(fields);
+ clone.hasLazyField = hasLazyField;
+ return clone;
}
+
// =================================================================
/** See {@link Message.Builder#clear()}. */
public void clear() {
fields.clear();
+ hasLazyField = false;
}
/**
* Get a simple map containing all the fields.
*/
public Map<FieldDescriptorType, Object> getAllFields() {
- return Collections.unmodifiableMap(fields);
+ if (hasLazyField) {
+ SmallSortedMap<FieldDescriptorType, Object> result =
+ SmallSortedMap.newFieldMap(16);
+ for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+ cloneFieldEntry(result, fields.getArrayEntryAt(i));
+ }
+ for (Map.Entry<FieldDescriptorType, Object> entry :
+ fields.getOverflowEntries()) {
+ cloneFieldEntry(result, entry);
+ }
+ if (fields.isImmutable()) {
+ result.makeImmutable();
+ }
+ return result;
+ }
+ return fields.isImmutable() ? fields : Collections.unmodifiableMap(fields);
+ }
+
+ private void cloneFieldEntry(Map<FieldDescriptorType, Object> map,
+ Map.Entry<FieldDescriptorType, Object> entry) {
+ FieldDescriptorType key = entry.getKey();
+ Object value = entry.getValue();
+ if (value instanceof LazyField) {
+ map.put(key, ((LazyField) value).getValue());
+ } else {
+ map.put(key, value);
+ }
}
/**
- * Get an iterator to the field map. This iterator should not be leaked
- * out of the protobuf library as it is not protected from mutation.
+ * Get an iterator to the field map. This iterator should not be leaked out
+ * of the protobuf library as it is not protected from mutation when fields
+ * is not immutable.
*/
public Iterator<Map.Entry<FieldDescriptorType, Object>> iterator() {
+ if (hasLazyField) {
+ return new LazyIterator<FieldDescriptorType>(
+ fields.entrySet().iterator());
+ }
return fields.entrySet().iterator();
}
@@ -157,14 +221,18 @@ final class FieldSet<FieldDescriptorType extends
* to the caller to fetch the field's default value.
*/
public Object getField(final FieldDescriptorType descriptor) {
- return fields.get(descriptor);
+ Object o = fields.get(descriptor);
+ if (o instanceof LazyField) {
+ return ((LazyField) o).getValue();
+ }
+ return o;
}
/**
* Useful for implementing
* {@link Message.Builder#setField(Descriptors.FieldDescriptor,Object)}.
*/
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({"unchecked", "rawtypes"})
public void setField(final FieldDescriptorType descriptor,
Object value) {
if (descriptor.isRepeated()) {
@@ -176,7 +244,7 @@ final class FieldSet<FieldDescriptorType extends
// Wrap the contents in a new list so that the caller cannot change
// the list's contents after setting it.
final List newList = new ArrayList();
- newList.addAll((List)value);
+ newList.addAll((List) value);
for (final Object element : newList) {
verifyType(descriptor.getLiteType(), element);
}
@@ -185,6 +253,9 @@ final class FieldSet<FieldDescriptorType extends
verifyType(descriptor.getLiteType(), value);
}
+ if (value instanceof LazyField) {
+ hasLazyField = true;
+ }
fields.put(descriptor, value);
}
@@ -194,6 +265,9 @@ final class FieldSet<FieldDescriptorType extends
*/
public void clearField(final FieldDescriptorType descriptor) {
fields.remove(descriptor);
+ if (fields.isEmpty()) {
+ hasLazyField = false;
+ }
}
/**
@@ -206,11 +280,11 @@ final class FieldSet<FieldDescriptorType extends
"getRepeatedField() can only be called on repeated fields.");
}
- final Object value = fields.get(descriptor);
+ final Object value = getField(descriptor);
if (value == null) {
return 0;
} else {
- return ((List) value).size();
+ return ((List<?>) value).size();
}
}
@@ -225,12 +299,12 @@ final class FieldSet<FieldDescriptorType extends
"getRepeatedField() can only be called on repeated fields.");
}
- final Object value = fields.get(descriptor);
+ final Object value = getField(descriptor);
if (value == null) {
throw new IndexOutOfBoundsException();
} else {
- return ((List) value).get(index);
+ return ((List<?>) value).get(index);
}
}
@@ -247,13 +321,13 @@ final class FieldSet<FieldDescriptorType extends
"getRepeatedField() can only be called on repeated fields.");
}
- final Object list = fields.get(descriptor);
+ final Object list = getField(descriptor);
if (list == null) {
throw new IndexOutOfBoundsException();
}
verifyType(descriptor.getLiteType(), value);
- ((List) list).set(index, value);
+ ((List<Object>) list).set(index, value);
}
/**
@@ -270,13 +344,13 @@ final class FieldSet<FieldDescriptorType extends
verifyType(descriptor.getLiteType(), value);
- final Object existingValue = fields.get(descriptor);
- List list;
+ final Object existingValue = getField(descriptor);
+ List<Object> list;
if (existingValue == null) {
- list = new ArrayList();
+ list = new ArrayList<Object>();
fields.put(descriptor, list);
} else {
- list = (List) existingValue;
+ list = (List<Object>) existingValue;
}
list.add(value);
@@ -303,14 +377,18 @@ final class FieldSet<FieldDescriptorType extends
case DOUBLE: isValid = value instanceof Double ; break;
case BOOLEAN: isValid = value instanceof Boolean ; break;
case STRING: isValid = value instanceof String ; break;
- case BYTE_STRING: isValid = value instanceof ByteString; break;
+ case BYTE_STRING:
+ isValid = value instanceof ByteString || value instanceof byte[];
+ break;
case ENUM:
// TODO(kenton): Caller must do type checking here, I guess.
- isValid = value instanceof Internal.EnumLite;
+ isValid =
+ (value instanceof Integer || value instanceof Internal.EnumLite);
break;
case MESSAGE:
// TODO(kenton): Caller must do type checking here, I guess.
- isValid = value instanceof MessageLite;
+ isValid =
+ (value instanceof MessageLite) || (value instanceof LazyField);
break;
}
@@ -336,27 +414,47 @@ final class FieldSet<FieldDescriptorType extends
* aren't actually present in the set, it is up to the caller to check
* that all required fields are present.
*/
- @SuppressWarnings("unchecked")
public boolean isInitialized() {
- for (final Map.Entry<FieldDescriptorType, Object> entry:
- fields.entrySet()) {
- final FieldDescriptorType descriptor = entry.getKey();
- if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {
- if (descriptor.isRepeated()) {
- for (final MessageLite element:
- (List<MessageLite>) entry.getValue()) {
- if (!element.isInitialized()) {
- return false;
- }
+ for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+ if (!isInitialized(fields.getArrayEntryAt(i))) {
+ return false;
+ }
+ }
+ for (final Map.Entry<FieldDescriptorType, Object> entry :
+ fields.getOverflowEntries()) {
+ if (!isInitialized(entry)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ private boolean isInitialized(
+ final Map.Entry<FieldDescriptorType, Object> entry) {
+ final FieldDescriptorType descriptor = entry.getKey();
+ if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {
+ if (descriptor.isRepeated()) {
+ for (final MessageLite element:
+ (List<MessageLite>) entry.getValue()) {
+ if (!element.isInitialized()) {
+ return false;
}
- } else {
- if (!((MessageLite) entry.getValue()).isInitialized()) {
+ }
+ } else {
+ Object value = entry.getValue();
+ if (value instanceof MessageLite) {
+ if (!((MessageLite) value).isInitialized()) {
return false;
}
+ } else if (value instanceof LazyField) {
+ return true;
+ } else {
+ throw new IllegalArgumentException(
+ "Wrong object type used with protocol message reflection.");
}
}
}
-
return true;
}
@@ -376,41 +474,62 @@ final class FieldSet<FieldDescriptorType extends
}
/**
- * Like {@link #mergeFrom(Message)}, but merges from another {@link FieldSet}.
+ * Like {@link Message.Builder#mergeFrom(Message)}, but merges from another
+ * {@link FieldSet}.
*/
- @SuppressWarnings("unchecked")
public void mergeFrom(final FieldSet<FieldDescriptorType> other) {
- for (final Map.Entry<FieldDescriptorType, Object> entry:
- other.fields.entrySet()) {
- final FieldDescriptorType descriptor = entry.getKey();
- final Object otherValue = entry.getValue();
+ for (int i = 0; i < other.fields.getNumArrayEntries(); i++) {
+ mergeFromField(other.fields.getArrayEntryAt(i));
+ }
+ for (final Map.Entry<FieldDescriptorType, Object> entry :
+ other.fields.getOverflowEntries()) {
+ mergeFromField(entry);
+ }
+ }
- if (descriptor.isRepeated()) {
- Object value = fields.get(descriptor);
- if (value == null) {
- // Our list is empty, but we still need to make a defensive copy of
- // the other list since we don't know if the other FieldSet is still
- // mutable.
- fields.put(descriptor, new ArrayList((List) otherValue));
- } else {
- // Concatenate the lists.
- ((List) value).addAll((List) otherValue);
- }
- } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {
- Object value = fields.get(descriptor);
- if (value == null) {
- fields.put(descriptor, otherValue);
- } else {
- // Merge the messages.
- fields.put(descriptor,
- descriptor.internalMergeFrom(
- ((MessageLite) value).toBuilder(), (MessageLite) otherValue)
- .build());
- }
+ private Object cloneIfMutable(Object value) {
+ if (value instanceof byte[]) {
+ byte[] bytes = (byte[]) value;
+ byte[] copy = new byte[bytes.length];
+ System.arraycopy(bytes, 0, copy, 0, bytes.length);
+ return copy;
+ } else {
+ return value;
+ }
+ }
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ private void mergeFromField(
+ final Map.Entry<FieldDescriptorType, Object> entry) {
+ final FieldDescriptorType descriptor = entry.getKey();
+ Object otherValue = entry.getValue();
+ if (otherValue instanceof LazyField) {
+ otherValue = ((LazyField) otherValue).getValue();
+ }
+ if (descriptor.isRepeated()) {
+ Object value = getField(descriptor);
+ if (value == null) {
+ value = new ArrayList();
+ }
+ for (Object element : (List) otherValue) {
+ ((List) value).add(cloneIfMutable(element));
+ }
+ fields.put(descriptor, value);
+ } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {
+ Object value = getField(descriptor);
+ if (value == null) {
+ fields.put(descriptor, cloneIfMutable(otherValue));
} else {
- fields.put(descriptor, otherValue);
+ // Merge the messages.
+ value = descriptor.internalMergeFrom(
+ ((MessageLite) value).toBuilder(), (MessageLite) otherValue)
+ .build();
+
+ fields.put(descriptor, value);
}
+ } else {
+ fields.put(descriptor, cloneIfMutable(otherValue));
}
}
@@ -418,11 +537,13 @@ final class FieldSet<FieldDescriptorType extends
// other class. Probably WireFormat.
/**
- * Read a field of any primitive type from a CodedInputStream. Enums,
- * groups, and embedded messages are not handled by this method.
+ * Read a field of any primitive type for immutable messages from a
+ * CodedInputStream. Enums, groups, and embedded messages are not handled by
+ * this method.
*
* @param input The stream from which to read.
* @param type Declared type of the field.
+ * @param checkUtf8 When true, check that the input is valid utf8.
* @return An object representing the field's value, of the exact
* type which would be returned by
* {@link Message#getField(Descriptors.FieldDescriptor)} for
@@ -430,7 +551,8 @@ final class FieldSet<FieldDescriptorType extends
*/
public static Object readPrimitiveField(
CodedInputStream input,
- final WireFormat.FieldType type) throws IOException {
+ final WireFormat.FieldType type,
+ boolean checkUtf8) throws IOException {
switch (type) {
case DOUBLE : return input.readDouble ();
case FLOAT : return input.readFloat ();
@@ -440,7 +562,11 @@ final class FieldSet<FieldDescriptorType extends
case FIXED64 : return input.readFixed64 ();
case FIXED32 : return input.readFixed32 ();
case BOOL : return input.readBool ();
- case STRING : return input.readString ();
+ case STRING : if (checkUtf8) {
+ return input.readStringRequireUtf8();
+ } else {
+ return input.readString();
+ }
case BYTES : return input.readBytes ();
case UINT32 : return input.readUInt32 ();
case SFIXED32: return input.readSFixed32();
@@ -465,11 +591,17 @@ final class FieldSet<FieldDescriptorType extends
"There is no way to get here, but the compiler thinks otherwise.");
}
+
/** See {@link Message#writeTo(CodedOutputStream)}. */
public void writeTo(final CodedOutputStream output)
throws IOException {
- for (final Map.Entry<FieldDescriptorType, Object> entry:
- fields.entrySet()) {
+ for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+ final Map.Entry<FieldDescriptorType, Object> entry =
+ fields.getArrayEntryAt(i);
+ writeField(entry.getKey(), entry.getValue(), output);
+ }
+ for (final Map.Entry<FieldDescriptorType, Object> entry :
+ fields.getOverflowEntries()) {
writeField(entry.getKey(), entry.getValue(), output);
}
}
@@ -479,16 +611,29 @@ final class FieldSet<FieldDescriptorType extends
*/
public void writeMessageSetTo(final CodedOutputStream output)
throws IOException {
- for (final Map.Entry<FieldDescriptorType, Object> entry:
- fields.entrySet()) {
- final FieldDescriptorType descriptor = entry.getKey();
- if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE &&
- !descriptor.isRepeated() && !descriptor.isPacked()) {
- output.writeMessageSetExtension(entry.getKey().getNumber(),
- (MessageLite) entry.getValue());
- } else {
- writeField(descriptor, entry.getValue(), output);
+ for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+ writeMessageSetTo(fields.getArrayEntryAt(i), output);
+ }
+ for (final Map.Entry<FieldDescriptorType, Object> entry :
+ fields.getOverflowEntries()) {
+ writeMessageSetTo(entry, output);
+ }
+ }
+
+ private void writeMessageSetTo(
+ final Map.Entry<FieldDescriptorType, Object> entry,
+ final CodedOutputStream output) throws IOException {
+ final FieldDescriptorType descriptor = entry.getKey();
+ if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE &&
+ !descriptor.isRepeated() && !descriptor.isPacked()) {
+ Object value = entry.getValue();
+ if (value instanceof LazyField) {
+ value = ((LazyField) value).getValue();
}
+ output.writeMessageSetExtension(entry.getKey().getNumber(),
+ (MessageLite) value);
+ } else {
+ writeField(descriptor, entry.getValue(), output);
}
}
@@ -510,7 +655,7 @@ final class FieldSet<FieldDescriptorType extends
// Special case for groups, which need a start and end tag; other fields
// can just use writeTag() and writeFieldNoTag().
if (type == WireFormat.FieldType.GROUP) {
- output.writeGroup(number, (MessageLite) value);
+ output.writeGroup(number, (MessageLite) value);
} else {
output.writeTag(number, getWireFormatForFieldType(type, false));
writeElementNoTag(output, type, value);
@@ -543,7 +688,13 @@ final class FieldSet<FieldDescriptorType extends
case STRING : output.writeStringNoTag ((String ) value); break;
case GROUP : output.writeGroupNoTag ((MessageLite) value); break;
case MESSAGE : output.writeMessageNoTag ((MessageLite) value); break;
- case BYTES : output.writeBytesNoTag ((ByteString ) value); break;
+ case BYTES:
+ if (value instanceof ByteString) {
+ output.writeBytesNoTag((ByteString) value);
+ } else {
+ output.writeByteArrayNoTag((byte[]) value);
+ }
+ break;
case UINT32 : output.writeUInt32NoTag ((Integer ) value); break;
case SFIXED32: output.writeSFixed32NoTag((Integer ) value); break;
case SFIXED64: output.writeSFixed64NoTag((Long ) value); break;
@@ -551,7 +702,11 @@ final class FieldSet<FieldDescriptorType extends
case SINT64 : output.writeSInt64NoTag ((Long ) value); break;
case ENUM:
- output.writeEnumNoTag(((Internal.EnumLite) value).getNumber());
+ if (value instanceof Internal.EnumLite) {
+ output.writeEnumNoTag(((Internal.EnumLite) value).getNumber());
+ } else {
+ output.writeEnumNoTag(((Integer) value).intValue());
+ }
break;
}
}
@@ -564,7 +719,7 @@ final class FieldSet<FieldDescriptorType extends
WireFormat.FieldType type = descriptor.getLiteType();
int number = descriptor.getNumber();
if (descriptor.isRepeated()) {
- final List valueList = (List)value;
+ final List<?> valueList = (List<?>)value;
if (descriptor.isPacked()) {
output.writeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED);
// Compute the total data size so the length can be written.
@@ -583,7 +738,11 @@ final class FieldSet<FieldDescriptorType extends
}
}
} else {
- writeElement(output, type, number, value);
+ if (value instanceof LazyField) {
+ writeElement(output, type, number, ((LazyField) value).getValue());
+ } else {
+ writeElement(output, type, number, value);
+ }
}
}
@@ -593,8 +752,13 @@ final class FieldSet<FieldDescriptorType extends
*/
public int getSerializedSize() {
int size = 0;
- for (final Map.Entry<FieldDescriptorType, Object> entry:
- fields.entrySet()) {
+ for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+ final Map.Entry<FieldDescriptorType, Object> entry =
+ fields.getArrayEntryAt(i);
+ size += computeFieldSize(entry.getKey(), entry.getValue());
+ }
+ for (final Map.Entry<FieldDescriptorType, Object> entry :
+ fields.getOverflowEntries()) {
size += computeFieldSize(entry.getKey(), entry.getValue());
}
return size;
@@ -605,18 +769,32 @@ final class FieldSet<FieldDescriptorType extends
*/
public int getMessageSetSerializedSize() {
int size = 0;
- for (final Map.Entry<FieldDescriptorType, Object> entry:
- fields.entrySet()) {
- final FieldDescriptorType descriptor = entry.getKey();
- if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE &&
- !descriptor.isRepeated() && !descriptor.isPacked()) {
- size += CodedOutputStream.computeMessageSetExtensionSize(
- entry.getKey().getNumber(), (MessageLite) entry.getValue());
+ for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+ size += getMessageSetSerializedSize(fields.getArrayEntryAt(i));
+ }
+ for (final Map.Entry<FieldDescriptorType, Object> entry :
+ fields.getOverflowEntries()) {
+ size += getMessageSetSerializedSize(entry);
+ }
+ return size;
+ }
+
+ private int getMessageSetSerializedSize(
+ final Map.Entry<FieldDescriptorType, Object> entry) {
+ final FieldDescriptorType descriptor = entry.getKey();
+ Object value = entry.getValue();
+ if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE
+ && !descriptor.isRepeated() && !descriptor.isPacked()) {
+ if (value instanceof LazyField) {
+ return CodedOutputStream.computeLazyFieldMessageSetExtensionSize(
+ entry.getKey().getNumber(), (LazyField) value);
} else {
- size += computeFieldSize(descriptor, entry.getValue());
+ return CodedOutputStream.computeMessageSetExtensionSize(
+ entry.getKey().getNumber(), (MessageLite) value);
}
+ } else {
+ return computeFieldSize(descriptor, value);
}
- return size;
}
/**
@@ -635,7 +813,9 @@ final class FieldSet<FieldDescriptorType extends
final int number, final Object value) {
int tagSize = CodedOutputStream.computeTagSize(number);
if (type == WireFormat.FieldType.GROUP) {
- tagSize *= 2;
+ // Only count the end group tag for proto2 messages as for proto1 the end
+ // group tag will be counted as a part of getSerializedSize().
+ tagSize *= 2;
}
return tagSize + computeElementSizeNoTag(type, value);
}
@@ -665,17 +845,32 @@ final class FieldSet<FieldDescriptorType extends
case BOOL : return CodedOutputStream.computeBoolSizeNoTag ((Boolean )value);
case STRING : return CodedOutputStream.computeStringSizeNoTag ((String )value);
case GROUP : return CodedOutputStream.computeGroupSizeNoTag ((MessageLite)value);
- case MESSAGE : return CodedOutputStream.computeMessageSizeNoTag ((MessageLite)value);
- case BYTES : return CodedOutputStream.computeBytesSizeNoTag ((ByteString )value);
+ case BYTES :
+ if (value instanceof ByteString) {
+ return CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
+ } else {
+ return CodedOutputStream.computeByteArraySizeNoTag((byte[]) value);
+ }
case UINT32 : return CodedOutputStream.computeUInt32SizeNoTag ((Integer )value);
case SFIXED32: return CodedOutputStream.computeSFixed32SizeNoTag((Integer )value);
case SFIXED64: return CodedOutputStream.computeSFixed64SizeNoTag((Long )value);
case SINT32 : return CodedOutputStream.computeSInt32SizeNoTag ((Integer )value);
case SINT64 : return CodedOutputStream.computeSInt64SizeNoTag ((Long )value);
+ case MESSAGE:
+ if (value instanceof LazyField) {
+ return CodedOutputStream.computeLazyFieldSizeNoTag((LazyField) value);
+ } else {
+ return CodedOutputStream.computeMessageSizeNoTag((MessageLite) value);
+ }
+
case ENUM:
- return CodedOutputStream.computeEnumSizeNoTag(
- ((Internal.EnumLite) value).getNumber());
+ if (value instanceof Internal.EnumLite) {
+ return CodedOutputStream.computeEnumSizeNoTag(
+ ((Internal.EnumLite) value).getNumber());
+ } else {
+ return CodedOutputStream.computeEnumSizeNoTag((Integer) value);
+ }
}
throw new RuntimeException(
@@ -692,7 +887,7 @@ final class FieldSet<FieldDescriptorType extends
if (descriptor.isRepeated()) {
if (descriptor.isPacked()) {
int dataSize = 0;
- for (final Object element : (List)value) {
+ for (final Object element : (List<?>)value) {
dataSize += computeElementSizeNoTag(type, element);
}
return dataSize +
@@ -700,7 +895,7 @@ final class FieldSet<FieldDescriptorType extends
CodedOutputStream.computeRawVarint32Size(dataSize);
} else {
int size = 0;
- for (final Object element : (List)value) {
+ for (final Object element : (List<?>)value) {
size += computeElementSize(type, number, element);
}
return size;
diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/src/main/java/com/google/protobuf/GeneratedMessage.java
index dba0ec8..a6101cb 100644
--- a/java/src/main/java/com/google/protobuf/GeneratedMessage.java
+++ b/java/src/main/java/com/google/protobuf/GeneratedMessage.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,10 +33,14 @@ package com.google.protobuf;
import com.google.protobuf.Descriptors.Descriptor;
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 java.io.IOException;
-import java.lang.reflect.Method;
+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;
@@ -52,10 +56,37 @@ import java.util.TreeMap;
*
* @author kenton@google.com Kenton Varda
*/
-public abstract class GeneratedMessage extends AbstractMessage {
- protected GeneratedMessage() {}
+public abstract class GeneratedMessage 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;
+
+ protected GeneratedMessage() {
+ }
- private UnknownFieldSet unknownFields = UnknownFieldSet.getDefaultInstance();
+ protected GeneratedMessage(Builder<?> builder) {
+ }
+
+ public Parser<? extends GeneratedMessage> 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
@@ -64,6 +95,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
*/
protected abstract FieldAccessorTable internalGetFieldAccessorTable();
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public Descriptor getDescriptorForType() {
return internalGetFieldAccessorTable().descriptor;
}
@@ -75,7 +107,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
for (final FieldDescriptor field : descriptor.getFields()) {
if (field.isRepeated()) {
- final List value = (List) getField(field);
+ final List<?> value = (List<?>) getField(field);
if (!value.isEmpty()) {
result.put(field, value);
}
@@ -118,36 +150,146 @@ public abstract class GeneratedMessage extends AbstractMessage {
return true;
}
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public Map<FieldDescriptor, Object> getAllFields() {
return Collections.unmodifiableMap(getAllFieldsMutable());
}
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean hasOneof(final OneofDescriptor oneof) {
+ return internalGetFieldAccessorTable().getOneof(oneof).has(this);
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
+ return internalGetFieldAccessorTable().getOneof(oneof).get(this);
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public boolean hasField(final FieldDescriptor field) {
return internalGetFieldAccessorTable().getField(field).has(this);
}
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public Object getField(final FieldDescriptor field) {
return internalGetFieldAccessorTable().getField(field).get(this);
}
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
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) {
return internalGetFieldAccessorTable().getField(field)
.getRepeated(this, index);
}
- public final UnknownFieldSet getUnknownFields() {
- return unknownFields;
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ 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);
+ }
+
+
+ /**
+ * Used by parsing constructors in generated classes.
+ */
+ protected void makeExtensionsImmutable() {
+ // Noop for messages without extensions.
+ }
+
+ protected abstract Message.Builder newBuilderForType(BuilderParent parent);
+
+ /**
+ * 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 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();
}
@SuppressWarnings("unchecked")
public abstract static class Builder <BuilderType extends Builder>
extends AbstractMessage.Builder<BuilderType> {
- protected Builder() {}
+
+ private BuilderParent builderParent;
+
+ private BuilderParentImpl meAsParent;
+
+ // Indicates that we've built a message and so we are now obligated
+ // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener.
+ private boolean isClean;
+
+ private UnknownFieldSet unknownFields =
+ UnknownFieldSet.getDefaultInstance();
+
+ protected Builder() {
+ this(null);
+ }
+
+ protected Builder(BuilderParent builderParent) {
+ this.builderParent = builderParent;
+ }
+
+ 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.
+ */
+ protected void markClean() {
+ this.isClean = true;
+ }
+
+ /**
+ * Gets whether invalidations are needed
+ *
+ * @return whether invalidations are needed
+ */
+ protected boolean isClean() {
+ return isClean;
+ }
// 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
@@ -159,26 +301,50 @@ public abstract class GeneratedMessage extends AbstractMessage {
}
/**
- * Get the message being built. We don't just pass this to the
- * constructor because it becomes null when build() is called.
+ * Called by the initialization and clear code paths to allow subclasses to
+ * reset any of their builtin fields back to the initial values.
*/
- protected abstract GeneratedMessage internalGetResult();
+ 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.
*/
- private FieldAccessorTable internalGetFieldAccessorTable() {
- return internalGetResult().internalGetFieldAccessorTable();
- }
+ protected abstract FieldAccessorTable internalGetFieldAccessorTable();
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public Descriptor getDescriptorForType() {
return internalGetFieldAccessorTable().descriptor;
}
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public Map<FieldDescriptor, Object> getAllFields() {
- return internalGetResult().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;
+ for (final FieldDescriptor field : descriptor.getFields()) {
+ if (field.isRepeated()) {
+ final List value = (List) getField(field);
+ if (!value.isEmpty()) {
+ result.put(field, value);
+ }
+ } else {
+ if (hasField(field)) {
+ result.put(field, getField(field));
+ }
+ }
+ }
+ return result;
}
public Message.Builder newBuilderForField(
@@ -186,18 +352,35 @@ public abstract class GeneratedMessage extends AbstractMessage {
return internalGetFieldAccessorTable().getField(field).newBuilder();
}
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ 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 boolean hasOneof(final OneofDescriptor oneof) {
+ return internalGetFieldAccessorTable().getOneof(oneof).has(this);
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
+ return internalGetFieldAccessorTable().getOneof(oneof).get(this);
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public boolean hasField(final FieldDescriptor field) {
- return internalGetResult().hasField(field);
+ return internalGetFieldAccessorTable().getField(field).has(this);
}
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
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) internalGetResult().getField(field));
+ return Collections.unmodifiableList((List) object);
} else {
- return internalGetResult().getField(field);
+ return object;
}
}
@@ -207,18 +390,29 @@ public abstract class GeneratedMessage extends AbstractMessage {
return (BuilderType) this;
}
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
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)
+ 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)
public int getRepeatedFieldCount(final FieldDescriptor field) {
- return internalGetResult().getRepeatedFieldCount(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) {
- return internalGetResult().getRepeatedField(field, index);
+ return internalGetFieldAccessorTable().getField(field)
+ .getRepeated(this, index);
}
public BuilderType setRepeatedField(final FieldDescriptor field,
@@ -234,29 +428,57 @@ public abstract class GeneratedMessage extends AbstractMessage {
return (BuilderType) this;
}
- public final UnknownFieldSet getUnknownFields() {
- return internalGetResult().unknownFields;
- }
-
public final BuilderType setUnknownFields(
final UnknownFieldSet unknownFields) {
- internalGetResult().unknownFields = unknownFields;
+ this.unknownFields = unknownFields;
+ onChanged();
return (BuilderType) this;
}
@Override
public final BuilderType mergeUnknownFields(
final UnknownFieldSet unknownFields) {
- final GeneratedMessage result = internalGetResult();
- result.unknownFields =
- UnknownFieldSet.newBuilder(result.unknownFields)
+ this.unknownFields =
+ UnknownFieldSet.newBuilder(this.unknownFields)
.mergeFrom(unknownFields)
.build();
+ onChanged();
return (BuilderType) this;
}
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public boolean isInitialized() {
- return internalGetResult().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 (Java 1.6 override semantics, but we must support 1.5)
+ public final UnknownFieldSet getUnknownFields() {
+ return unknownFields;
}
/**
@@ -270,11 +492,71 @@ public abstract class GeneratedMessage extends AbstractMessage {
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 (Java 1.6 override semantics, but we must support 1.5)
+ 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;
+ }
+ }
}
// =================================================================
// Extensions-related stuff
+ public interface ExtendableMessageOrBuilder<
+ MessageType extends ExtendableMessage> extends MessageOrBuilder {
+ // Re-define for return type covariance.
+ Message getDefaultInstanceForType();
+
+ /** Check if a singular extension is present. */
+ <Type> boolean hasExtension(
+ Extension<MessageType, Type> extension);
+
+ /** Get the number of elements in a repeated extension. */
+ <Type> int getExtensionCount(
+ Extension<MessageType, List<Type>> extension);
+
+ /** Get the value of an extension. */
+ <Type> Type getExtension(
+ Extension<MessageType, Type> extension);
+
+ /** Get one element of a repeated extension. */
+ <Type> Type getExtension(
+ Extension<MessageType, List<Type>> extension,
+ int index);
+ }
+
/**
* Generated message classes for message types that contain extension ranges
* subclass this.
@@ -312,12 +594,23 @@ public abstract class GeneratedMessage extends AbstractMessage {
*/
public abstract static class ExtendableMessage<
MessageType extends ExtendableMessage>
- extends GeneratedMessage {
- protected ExtendableMessage() {}
- private final FieldSet<FieldDescriptor> extensions = FieldSet.newFieldSet();
+ extends GeneratedMessage
+ implements ExtendableMessageOrBuilder<MessageType> {
+
+ 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 GeneratedExtension<MessageType, ?> extension) {
+ final Extension<MessageType, ?> extension) {
if (extension.getDescriptor().getContainingType() !=
getDescriptorForType()) {
// This can only happen if someone uses unchecked operations.
@@ -330,24 +623,27 @@ public abstract class GeneratedMessage extends AbstractMessage {
}
/** Check if a singular extension is present. */
- public final boolean hasExtension(
- final GeneratedExtension<MessageType, ?> extension) {
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> boolean hasExtension(
+ final Extension<MessageType, Type> extension) {
verifyExtensionContainingType(extension);
return extensions.hasField(extension.getDescriptor());
}
/** Get the number of elements in a repeated extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public final <Type> int getExtensionCount(
- final GeneratedExtension<MessageType, List<Type>> extension) {
+ final Extension<MessageType, List<Type>> extension) {
verifyExtensionContainingType(extension);
final FieldDescriptor descriptor = extension.getDescriptor();
return extensions.getRepeatedFieldCount(descriptor);
}
/** Get the value of an extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
@SuppressWarnings("unchecked")
public final <Type> Type getExtension(
- final GeneratedExtension<MessageType, Type> extension) {
+ final Extension<MessageType, Type> extension) {
verifyExtensionContainingType(extension);
FieldDescriptor descriptor = extension.getDescriptor();
final Object value = extensions.getField(descriptor);
@@ -367,9 +663,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)
@SuppressWarnings("unchecked")
public final <Type> Type getExtension(
- final GeneratedExtension<MessageType, List<Type>> extension,
+ final Extension<MessageType, List<Type>> extension,
final int index) {
verifyExtensionContainingType(extension);
FieldDescriptor descriptor = extension.getDescriptor();
@@ -387,6 +684,26 @@ public abstract class GeneratedMessage extends AbstractMessage {
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
@@ -416,9 +733,21 @@ public abstract class GeneratedMessage extends AbstractMessage {
if (messageSetWireFormat && descriptor.getLiteJavaType() ==
WireFormat.JavaType.MESSAGE &&
!descriptor.isRepeated()) {
- output.writeMessageSetExtension(descriptor.getNumber(),
- (Message) next.getValue());
+ 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()) {
@@ -448,10 +777,14 @@ public abstract class GeneratedMessage extends AbstractMessage {
// ---------------------------------------------------------------
// Reflection
+ protected Map<FieldDescriptor, Object> getExtensionFields() {
+ return extensions.getAllFields();
+ }
+
@Override
public Map<FieldDescriptor, Object> getAllFields() {
final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable();
- result.putAll(extensions.getAllFields());
+ result.putAll(getExtensionFields());
return Collections.unmodifiableMap(result);
}
@@ -556,9 +889,29 @@ public abstract class GeneratedMessage extends AbstractMessage {
public abstract static class ExtendableBuilder<
MessageType extends ExtendableMessage,
BuilderType extends ExtendableBuilder>
- extends Builder<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 dummy clone() implementation makes it go away.
@@ -568,80 +921,143 @@ public abstract class GeneratedMessage extends AbstractMessage {
"This is supposed to be overridden by subclasses.");
}
- @Override
- protected abstract ExtendableMessage<MessageType> internalGetResult();
+ 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. */
- public final boolean hasExtension(
- final GeneratedExtension<MessageType, ?> extension) {
- return internalGetResult().hasExtension(extension);
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> boolean hasExtension(
+ final Extension<MessageType, Type> extension) {
+ verifyExtensionContainingType(extension);
+ return extensions.hasField(extension.getDescriptor());
}
/** Get the number of elements in a repeated extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public final <Type> int getExtensionCount(
- final GeneratedExtension<MessageType, List<Type>> extension) {
- return internalGetResult().getExtensionCount(extension);
+ final Extension<MessageType, List<Type>> extension) {
+ verifyExtensionContainingType(extension);
+ final FieldDescriptor descriptor = extension.getDescriptor();
+ return extensions.getRepeatedFieldCount(descriptor);
}
/** Get the value of an extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public final <Type> Type getExtension(
- final GeneratedExtension<MessageType, Type> extension) {
- return internalGetResult().getExtension(extension);
+ final Extension<MessageType, Type> extension) {
+ 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 (Java 1.6 override semantics, but we must support 1.5)
public final <Type> Type getExtension(
- final GeneratedExtension<MessageType, List<Type>> extension,
+ final Extension<MessageType, List<Type>> extension,
final int index) {
- return internalGetResult().getExtension(extension, index);
+ 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 GeneratedExtension<MessageType, Type> extension,
+ final Extension<MessageType, Type> extension,
final Type value) {
- final ExtendableMessage<MessageType> message = internalGetResult();
- message.verifyExtensionContainingType(extension);
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
final FieldDescriptor descriptor = extension.getDescriptor();
- message.extensions.setField(descriptor,
- extension.toReflectionType(value));
+ 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 GeneratedExtension<MessageType, List<Type>> extension,
+ final Extension<MessageType, List<Type>> extension,
final int index, final Type value) {
- final ExtendableMessage<MessageType> message = internalGetResult();
- message.verifyExtensionContainingType(extension);
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
final FieldDescriptor descriptor = extension.getDescriptor();
- message.extensions.setRepeatedField(
+ extensions.setRepeatedField(
descriptor, index,
extension.singularToReflectionType(value));
+ onChanged();
return (BuilderType) this;
}
/** Append a value to a repeated extension. */
public final <Type> BuilderType addExtension(
- final GeneratedExtension<MessageType, List<Type>> extension,
+ final Extension<MessageType, List<Type>> extension,
final Type value) {
- final ExtendableMessage<MessageType> message = internalGetResult();
- message.verifyExtensionContainingType(extension);
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
final FieldDescriptor descriptor = extension.getDescriptor();
- message.extensions.addRepeatedField(
+ extensions.addRepeatedField(
descriptor, extension.singularToReflectionType(value));
+ onChanged();
return (BuilderType) this;
}
/** Clear an extension. */
public final <Type> BuilderType clearExtension(
- final GeneratedExtension<MessageType, ?> extension) {
- final ExtendableMessage<MessageType> message = internalGetResult();
- message.verifyExtensionContainingType(extension);
- message.extensions.clearField(extension.getDescriptor());
+ final Extension<MessageType, ?> extension) {
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ extensions.clearField(extension.getDescriptor());
+ onChanged();
return (BuilderType) this;
}
+ /** 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.
@@ -652,24 +1068,81 @@ public abstract class GeneratedMessage extends AbstractMessage {
final UnknownFieldSet.Builder unknownFields,
final ExtensionRegistryLite extensionRegistry,
final int tag) throws IOException {
- final ExtendableMessage<MessageType> message = internalGetResult();
- return AbstractMessage.Builder.mergeFieldFrom(
- input, unknownFields, extensionRegistry, this, tag);
+ return MessageReflection.mergeFieldFrom(
+ input, unknownFields, extensionRegistry, getDescriptorForType(),
+ new MessageReflection.BuilderAdapter(this), tag);
}
// ---------------------------------------------------------------
// Reflection
- // We don't have to override the get*() methods here because they already
- // just forward to the underlying message.
+ @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()) {
- final ExtendableMessage<MessageType> message = internalGetResult();
- message.verifyContainingType(field);
- message.extensions.setField(field, value);
+ verifyContainingType(field);
+ ensureExtensionsIsMutable();
+ extensions.setField(field, value);
+ onChanged();
return (BuilderType) this;
} else {
return super.setField(field, value);
@@ -679,9 +1152,10 @@ public abstract class GeneratedMessage extends AbstractMessage {
@Override
public BuilderType clearField(final FieldDescriptor field) {
if (field.isExtension()) {
- final ExtendableMessage<MessageType> message = internalGetResult();
- message.verifyContainingType(field);
- message.extensions.clearField(field);
+ verifyContainingType(field);
+ ensureExtensionsIsMutable();
+ extensions.clearField(field);
+ onChanged();
return (BuilderType) this;
} else {
return super.clearField(field);
@@ -692,9 +1166,10 @@ public abstract class GeneratedMessage extends AbstractMessage {
public BuilderType setRepeatedField(final FieldDescriptor field,
final int index, final Object value) {
if (field.isExtension()) {
- final ExtendableMessage<MessageType> message = internalGetResult();
- message.verifyContainingType(field);
- message.extensions.setRepeatedField(field, index, value);
+ verifyContainingType(field);
+ ensureExtensionsIsMutable();
+ extensions.setRepeatedField(field, index, value);
+ onChanged();
return (BuilderType) this;
} else {
return super.setRepeatedField(field, index, value);
@@ -705,9 +1180,10 @@ public abstract class GeneratedMessage extends AbstractMessage {
public BuilderType addRepeatedField(final FieldDescriptor field,
final Object value) {
if (field.isExtension()) {
- final ExtendableMessage<MessageType> message = internalGetResult();
- message.verifyContainingType(field);
- message.extensions.addRepeatedField(field, value);
+ verifyContainingType(field);
+ ensureExtensionsIsMutable();
+ extensions.addRepeatedField(field, value);
+ onChanged();
return (BuilderType) this;
} else {
return super.addRepeatedField(field, value);
@@ -715,17 +1191,144 @@ public abstract class GeneratedMessage extends AbstractMessage {
}
protected final void mergeExtensionFields(final ExtendableMessage other) {
- internalGetResult().extensions.mergeFrom(other.extensions);
+ 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();
+ }
+
+ /** For use by generated code only. */
+ public static <ContainingType extends Message, Type>
+ GeneratedExtension<ContainingType, Type>
+ newMessageScopedGeneratedExtension(final Message scope,
+ final int descriptorIndex,
+ final Class singularType,
+ final Message defaultInstance) {
+ // For extensions scoped within a Message, we use the Message to resolve
+ // the outer class's descriptor, from which the extension descriptor is
+ // obtained.
+ return new GeneratedExtension<ContainingType, Type>(
+ new CachedDescriptorRetriever() {
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public FieldDescriptor loadDescriptor() {
+ return scope.getDescriptorForType().getExtensions()
+ .get(descriptorIndex);
+ }
+ },
+ singularType,
+ defaultInstance,
+ Extension.ExtensionType.IMMUTABLE);
+ }
+
/** For use by generated code only. */
public static <ContainingType extends Message, Type>
+ GeneratedExtension<ContainingType, Type>
+ newFileScopedGeneratedExtension(final Class singularType,
+ final Message defaultInstance) {
+ // For extensions scoped within a file, we rely on the outer class's
+ // static initializer to call internalInit() on the extension when the
+ // descriptor is available.
+ return new GeneratedExtension<ContainingType, Type>(
+ null, // ExtensionDescriptorRetriever is initialized in internalInit();
+ singularType,
+ defaultInstance,
+ Extension.ExtensionType.IMMUTABLE);
+ }
+
+ private abstract static class CachedDescriptorRetriever
+ implements ExtensionDescriptorRetriever {
+ private volatile FieldDescriptor descriptor;
+ protected abstract FieldDescriptor loadDescriptor();
+
+ public FieldDescriptor getDescriptor() {
+ if (descriptor == null) {
+ synchronized (this) {
+ if (descriptor == null) {
+ descriptor = loadDescriptor();
+ }
+ }
+ }
+ return descriptor;
+ }
+ }
+
+ /**
+ * Used in proto1 generated code only.
+ *
+ * After enabling bridge, we can define proto2 extensions (the extended type
+ * is a proto2 mutable message) in a proto1 .proto file. For these extensions
+ * we should generate proto2 GeneratedExtensions.
+ */
+ public static <ContainingType extends Message, Type>
GeneratedExtension<ContainingType, Type>
- newGeneratedExtension() {
- return new GeneratedExtension<ContainingType, Type>();
+ newMessageScopedGeneratedExtension(
+ final Message scope, final String name,
+ final Class singularType, final Message defaultInstance) {
+ // For extensions scoped within a Message, we use the Message to resolve
+ // the outer class's descriptor, from which the extension descriptor is
+ // obtained.
+ return new GeneratedExtension<ContainingType, Type>(
+ new CachedDescriptorRetriever() {
+ protected FieldDescriptor loadDescriptor() {
+ return scope.getDescriptorForType().findFieldByName(name);
+ }
+ },
+ singularType,
+ defaultInstance,
+ Extension.ExtensionType.MUTABLE);
+ }
+
+ /**
+ * Used in proto1 generated code only.
+ *
+ * After enabling bridge, we can define proto2 extensions (the extended type
+ * is a proto2 mutable message) in a proto1 .proto file. For these extensions
+ * we should generate proto2 GeneratedExtensions.
+ */
+ public static <ContainingType extends Message, Type>
+ GeneratedExtension<ContainingType, Type>
+ newFileScopedGeneratedExtension(
+ final Class singularType, final Message defaultInstance,
+ final String descriptorOuterClass, final String extensionName) {
+ // For extensions scoped within a file, we load the descriptor outer
+ // class and rely on it to get the FileDescriptor which then can be
+ // used to obtain the extension's FieldDescriptor.
+ return new GeneratedExtension<ContainingType, Type>(
+ new CachedDescriptorRetriever() {
+ protected FieldDescriptor loadDescriptor() {
+ try {
+ 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);
+ }
+ }
+ },
+ singularType,
+ defaultInstance,
+ Extension.ExtensionType.MUTABLE);
}
/**
@@ -753,87 +1356,99 @@ public abstract class GeneratedMessage extends AbstractMessage {
* these static singletons as parameters to the extension accessors defined
* in {@link ExtendableMessage} and {@link ExtendableBuilder}.
*/
- public static final class GeneratedExtension<
- ContainingType extends Message, Type> {
+ public static class GeneratedExtension<
+ ContainingType extends Message, Type> extends
+ Extension<ContainingType, Type> {
// TODO(kenton): Find ways to avoid using Java reflection within this
// class. Also try to avoid suppressing unchecked warnings.
- // We can't always initialize a GeneratedExtension when we first construct
- // it due to initialization order difficulties (namely, the descriptor may
- // not have been constructed yet, since it is often constructed by the
- // initializer of a separate module). So, we construct an uninitialized
- // GeneratedExtension once, then call internalInit() on it later. Generated
- // code will always call internalInit() on all extensions as part of the
- // static initialization code, and internalInit() throws an exception if
- // called more than once, so this method is useless to users.
- private GeneratedExtension() {}
-
- /** For use by generated code only. */
- public void internalInit(final FieldDescriptor descriptor,
- final Class type) {
- if (this.descriptor != null) {
- throw new IllegalStateException("Already initialized.");
- }
-
- if (!descriptor.isExtension()) {
+ // We can't always initialize the descriptor of a GeneratedExtension when
+ // we first construct it due to initialization order difficulties (namely,
+ // the descriptor may not have been constructed yet, since it is often
+ // constructed by the initializer of a separate module).
+ //
+ // In the case of nested extensions, we initialize the
+ // ExtensionDescriptorRetriever with an instance that uses the scoping
+ // Message's default instance to retrieve the extension's descriptor.
+ //
+ // In the case of non-nested extensions, we initialize the
+ // ExtensionDescriptorRetriever to null and rely on the outer class's static
+ // initializer to call internalInit() after the descriptor has been parsed.
+ GeneratedExtension(ExtensionDescriptorRetriever descriptorRetriever,
+ Class singularType,
+ Message messageDefaultInstance,
+ ExtensionType extensionType) {
+ if (Message.class.isAssignableFrom(singularType) &&
+ !singularType.isInstance(messageDefaultInstance)) {
throw new IllegalArgumentException(
- "GeneratedExtension given a regular (non-extension) field.");
+ "Bad messageDefaultInstance for " + singularType.getName());
}
+ this.descriptorRetriever = descriptorRetriever;
+ this.singularType = singularType;
+ this.messageDefaultInstance = messageDefaultInstance;
- this.descriptor = descriptor;
- this.type = type;
+ if (ProtocolMessageEnum.class.isAssignableFrom(singularType)) {
+ this.enumValueOf = getMethodOrDie(singularType, "valueOf",
+ EnumValueDescriptor.class);
+ this.enumGetValueDescriptor =
+ getMethodOrDie(singularType, "getValueDescriptor");
+ } else {
+ this.enumValueOf = null;
+ this.enumGetValueDescriptor = null;
+ }
+ this.extensionType = extensionType;
+ }
- switch (descriptor.getJavaType()) {
- case MESSAGE:
- enumValueOf = null;
- enumGetValueDescriptor = null;
- messageDefaultInstance =
- (Message) invokeOrDie(getMethodOrDie(type, "getDefaultInstance"),
- null);
- if (messageDefaultInstance == null) {
- throw new IllegalStateException(
- type.getName() + ".getDefaultInstance() returned null.");
- }
- break;
- case ENUM:
- enumValueOf = getMethodOrDie(type, "valueOf",
- EnumValueDescriptor.class);
- enumGetValueDescriptor = getMethodOrDie(type, "getValueDescriptor");
- messageDefaultInstance = null;
- break;
- default:
- enumValueOf = null;
- enumGetValueDescriptor = null;
- messageDefaultInstance = null;
- break;
+ /** For use by generated code only. */
+ public void internalInit(final FieldDescriptor descriptor) {
+ 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;
+ }
+ };
}
- private FieldDescriptor descriptor;
- private Class type;
- private Method enumValueOf;
- private Method enumGetValueDescriptor;
- private Message messageDefaultInstance;
+ private ExtensionDescriptorRetriever descriptorRetriever;
+ private final Class singularType;
+ private final Message messageDefaultInstance;
+ private final Method enumValueOf;
+ private final Method enumGetValueDescriptor;
+ private final ExtensionType extensionType;
- public FieldDescriptor getDescriptor() { return descriptor; }
+ public FieldDescriptor getDescriptor() {
+ if (descriptorRetriever == null) {
+ throw new IllegalStateException(
+ "getDescriptor() called before internalInit()");
+ }
+ return descriptorRetriever.getDescriptor();
+ }
/**
* If the extension is an embedded message or group, returns the default
* instance of the message.
*/
- @SuppressWarnings("unchecked")
public Message getMessageDefaultInstance() {
return messageDefaultInstance;
}
+ protected ExtensionType getExtensionType() {
+ return extensionType;
+ }
+
/**
* Convert from the type used by the reflection accessors to the type used
* by native accessors. E.g., for enums, the reflection accessors use
* EnumValueDescriptors but the native accessors use the generated enum
* type.
*/
+ // @Override
@SuppressWarnings("unchecked")
- private Object fromReflectionType(final Object value) {
+ protected Object fromReflectionType(final Object value) {
+ FieldDescriptor descriptor = getDescriptor();
if (descriptor.isRepeated()) {
if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE ||
descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) {
@@ -855,20 +1470,16 @@ public abstract class GeneratedMessage extends AbstractMessage {
* Like {@link #fromReflectionType(Object)}, but if the type is a repeated
* type, this converts a single element.
*/
- private Object singularFromReflectionType(final Object value) {
+ // @Override
+ protected Object singularFromReflectionType(final Object value) {
+ FieldDescriptor descriptor = getDescriptor();
switch (descriptor.getJavaType()) {
case MESSAGE:
- if (type.isInstance(value)) {
+ if (singularType.isInstance(value)) {
return value;
} else {
- // It seems the copy of the embedded message stored inside the
- // extended message is not of the exact type the user was
- // expecting. This can happen if a user defines a
- // GeneratedExtension manually and gives it a different type.
- // This should not happen in normal use. But, to be nice, we'll
- // copy the message to whatever type the caller was expecting.
return messageDefaultInstance.newBuilderForType()
- .mergeFrom((Message) value).build();
+ .mergeFrom((Message) value).build();
}
case ENUM:
return invokeOrDie(enumValueOf, null, (EnumValueDescriptor) value);
@@ -883,8 +1494,10 @@ public abstract class GeneratedMessage extends AbstractMessage {
* EnumValueDescriptors but the native accessors use the generated enum
* type.
*/
+ // @Override
@SuppressWarnings("unchecked")
- private Object toReflectionType(final Object value) {
+ protected Object toReflectionType(final Object value) {
+ FieldDescriptor descriptor = getDescriptor();
if (descriptor.isRepeated()) {
if (descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) {
// Must convert the whole list.
@@ -905,7 +1518,9 @@ public abstract class GeneratedMessage extends AbstractMessage {
* Like {@link #toReflectionType(Object)}, but if the type is a repeated
* type, this converts a single element.
*/
- private Object singularToReflectionType(final Object value) {
+ // @Override
+ protected Object singularToReflectionType(final Object value) {
+ FieldDescriptor descriptor = getDescriptor();
switch (descriptor.getJavaType()) {
case ENUM:
return invokeOrDie(enumGetValueDescriptor, value);
@@ -913,6 +1528,34 @@ public abstract class GeneratedMessage extends AbstractMessage {
return value;
}
}
+
+ // @Override
+ public int getNumber() {
+ return getDescriptor().getNumber();
+ }
+
+ // @Override
+ public WireFormat.FieldType getLiteType() {
+ return getDescriptor().getLiteType();
+ }
+
+ // @Override
+ public boolean isRepeated() {
+ return getDescriptor().isRepeated();
+ }
+
+ // @Override
+ @SuppressWarnings("unchecked")
+ public Type getDefaultValue() {
+ if (isRepeated()) {
+ return (Type) Collections.emptyList();
+ }
+ if (getDescriptor().getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ return (Type) messageDefaultInstance;
+ }
+ return (Type) singularFromReflectionType(
+ getDescriptor().getDefaultValue());
+ }
}
// =================================================================
@@ -973,39 +1616,90 @@ public abstract class GeneratedMessage extends AbstractMessage {
final String[] camelCaseNames,
final Class<? extends GeneratedMessage> 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;
+ }
- for (int i = 0; i < fields.length; i++) {
- final FieldDescriptor field = descriptor.getFields().get(i);
- if (field.isRepeated()) {
- if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
- 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);
+ /**
+ * 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 GeneratedMessage> 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()];
}
- } else {
- if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
- fields[i] = new SingularMessageFieldAccessor(
- field, camelCaseNames[i], messageClass, builderClass);
- } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) {
- fields[i] = new SingularEnumFieldAccessor(
- field, camelCaseNames[i], messageClass, builderClass);
+ if (field.isRepeated()) {
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ 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 {
- fields[i] = new SingularFieldAccessor(
- field, camelCaseNames[i], messageClass, builderClass);
+ 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 {
+ 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) {
@@ -1021,21 +1715,93 @@ public abstract class GeneratedMessage extends AbstractMessage {
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(GeneratedMessage message);
+ Object get(GeneratedMessage.Builder builder);
void set(Builder builder, Object value);
Object getRepeated(GeneratedMessage message, int index);
+ Object getRepeated(GeneratedMessage.Builder builder, int index);
void setRepeated(Builder builder,
int index, Object value);
void addRepeated(Builder builder, Object value);
boolean has(GeneratedMessage message);
+ boolean has(GeneratedMessage.Builder builder);
int getRepeatedCount(GeneratedMessage message);
+ int getRepeatedCount(GeneratedMessage.Builder builder);
void clear(Builder builder);
Message.Builder newBuilder();
+ Message.Builder getBuilder(GeneratedMessage.Builder builder);
+ }
+
+ /** OneofAccessor provides access to a single oneof. */
+ private static class OneofAccessor {
+ OneofAccessor(
+ final Descriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessage> 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 GeneratedMessage message) {
+ if (((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber() == 0) {
+ return false;
+ }
+ return true;
+ }
+
+ public boolean has(GeneratedMessage.Builder builder) {
+ if (((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber() == 0) {
+ return false;
+ }
+ return true;
+ }
+
+ public FieldDescriptor get(final GeneratedMessage message) {
+ int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber();
+ if (fieldNumber > 0) {
+ return descriptor.findFieldByNumber(fieldNumber);
+ }
+ return null;
+ }
+
+ public FieldDescriptor get(GeneratedMessage.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 true;
}
// ---------------------------------------------------------------
@@ -1044,27 +1810,57 @@ public abstract class GeneratedMessage extends AbstractMessage {
SingularFieldAccessor(
final FieldDescriptor descriptor, final String camelCaseName,
final Class<? extends GeneratedMessage> messageClass,
- final Class<? extends Builder> builderClass) {
+ 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 =
- getMethodOrDie(messageClass, "has" + camelCaseName);
+ 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 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 GeneratedMessage message) {
+ return ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber();
+ }
+
+ private int getOneofFieldNumber(final GeneratedMessage.Builder builder) {
+ return ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber();
+ }
public Object get(final GeneratedMessage message) {
return invokeOrDie(getMethod, message);
}
+ public Object get(GeneratedMessage.Builder builder) {
+ return invokeOrDie(getMethodBuilder, builder);
+ }
public void set(final Builder builder, final Object value) {
invokeOrDie(setMethod, builder, value);
}
@@ -1073,6 +1869,10 @@ public abstract class GeneratedMessage extends AbstractMessage {
throw new UnsupportedOperationException(
"getRepeatedField() called on a singular field.");
}
+ public Object getRepeated(GeneratedMessage.Builder builder, int index) {
+ throw new UnsupportedOperationException(
+ "getRepeatedField() called on a singular field.");
+ }
public void setRepeated(final Builder builder,
final int index, final Object value) {
throw new UnsupportedOperationException(
@@ -1083,12 +1883,31 @@ public abstract class GeneratedMessage extends AbstractMessage {
"addRepeatedField() called on a singular field.");
}
public boolean has(final GeneratedMessage message) {
+ if (!hasHasMethod) {
+ if (isOneofField) {
+ return getOneofFieldNumber(message) == field.getNumber();
+ }
+ return !get(message).equals(field.getDefaultValue());
+ }
return (Boolean) invokeOrDie(hasMethod, message);
}
+ public boolean has(GeneratedMessage.Builder builder) {
+ if (!hasHasMethod) {
+ if (isOneofField) {
+ return getOneofFieldNumber(builder) == field.getNumber();
+ }
+ return !get(builder).equals(field.getDefaultValue());
+ }
+ return (Boolean) invokeOrDie(hasMethodBuilder, builder);
+ }
public int getRepeatedCount(final GeneratedMessage message) {
throw new UnsupportedOperationException(
"getRepeatedFieldSize() called on a singular field.");
}
+ public int getRepeatedCount(GeneratedMessage.Builder builder) {
+ throw new UnsupportedOperationException(
+ "getRepeatedFieldSize() called on a singular field.");
+ }
public void clear(final Builder builder) {
invokeOrDie(clearMethod, builder);
}
@@ -1096,48 +1915,63 @@ public abstract class GeneratedMessage extends AbstractMessage {
throw new UnsupportedOperationException(
"newBuilderForField() called on a non-Message type.");
}
+ public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
+ throw new UnsupportedOperationException(
+ "getFieldBuilder() 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 GeneratedMessage> 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);
+ getMethodOrDie(messageClass, "get" + camelCaseName, Integer.TYPE);
+ getRepeatedMethodBuilder =
+ getMethodOrDie(builderClass, "get" + camelCaseName, Integer.TYPE);
type = getRepeatedMethod.getReturnType();
setRepeatedMethod =
- getMethodOrDie(builderClass, "set" + camelCaseName,
- Integer.TYPE, type);
+ getMethodOrDie(builderClass, "set" + camelCaseName,
+ Integer.TYPE, type);
addRepeatedMethod =
- getMethodOrDie(builderClass, "add" + camelCaseName, type);
+ getMethodOrDie(builderClass, "add" + camelCaseName, type);
getCountMethod =
- getMethodOrDie(messageClass, "get" + camelCaseName + "Count");
+ getMethodOrDie(messageClass, "get" + camelCaseName + "Count");
+ getCountMethodBuilder =
+ getMethodOrDie(builderClass, "get" + camelCaseName + "Count");
clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
}
- protected final Class type;
- protected final Method getMethod;
- protected final Method getRepeatedMethod;
- protected final Method setRepeatedMethod;
- protected final Method addRepeatedMethod;
- protected final Method getCountMethod;
- protected final Method clearMethod;
-
public Object get(final GeneratedMessage message) {
return invokeOrDie(getMethod, message);
}
+ public Object get(GeneratedMessage.Builder builder) {
+ return invokeOrDie(getMethodBuilder, builder);
+ }
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) {
+ for (final Object element : (List<?>) value) {
addRepeated(builder, element);
}
}
@@ -1145,6 +1979,9 @@ public abstract class GeneratedMessage extends AbstractMessage {
final int index) {
return invokeOrDie(getRepeatedMethod, message, index);
}
+ public Object getRepeated(GeneratedMessage.Builder builder, int index) {
+ return invokeOrDie(getRepeatedMethodBuilder, builder, index);
+ }
public void setRepeated(final Builder builder,
final int index, final Object value) {
invokeOrDie(setRepeatedMethod, builder, index, value);
@@ -1154,11 +1991,18 @@ public abstract class GeneratedMessage extends AbstractMessage {
}
public boolean has(final GeneratedMessage message) {
throw new UnsupportedOperationException(
- "hasField() called on a singular field.");
+ "hasField() called on a repeated field.");
+ }
+ public boolean has(GeneratedMessage.Builder builder) {
+ throw new UnsupportedOperationException(
+ "hasField() called on a repeated field.");
}
public int getRepeatedCount(final GeneratedMessage message) {
return (Integer) invokeOrDie(getCountMethod, message);
}
+ public int getRepeatedCount(GeneratedMessage.Builder builder) {
+ return (Integer) invokeOrDie(getCountMethodBuilder, builder);
+ }
public void clear(final Builder builder) {
invokeOrDie(clearMethod, builder);
}
@@ -1166,6 +2010,10 @@ public abstract class GeneratedMessage extends AbstractMessage {
throw new UnsupportedOperationException(
"newBuilderForField() called on a non-Message type.");
}
+ public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
+ throw new UnsupportedOperationException(
+ "getFieldBuilder() called on a non-Message type.");
+ }
}
// ---------------------------------------------------------------
@@ -1175,8 +2023,9 @@ public abstract class GeneratedMessage extends AbstractMessage {
SingularEnumFieldAccessor(
final FieldDescriptor descriptor, final String camelCaseName,
final Class<? extends GeneratedMessage> messageClass,
- final Class<? extends Builder> builderClass) {
- super(descriptor, camelCaseName, messageClass, builderClass);
+ final Class<? extends Builder> builderClass,
+ final String containingOneofCamelCaseName) {
+ super(descriptor, camelCaseName, messageClass, builderClass, containingOneofCamelCaseName);
valueOfMethod = getMethodOrDie(type, "valueOf",
EnumValueDescriptor.class);
@@ -1191,6 +2040,12 @@ public abstract class GeneratedMessage extends AbstractMessage {
public Object get(final GeneratedMessage message) {
return invokeOrDie(getValueDescriptorMethod, super.get(message));
}
+
+ @Override
+ public Object get(final GeneratedMessage.Builder builder) {
+ return invokeOrDie(getValueDescriptorMethod, super.get(builder));
+ }
+
@Override
public void set(final Builder builder, final Object value) {
super.set(builder, invokeOrDie(valueOfMethod, null, value));
@@ -1223,6 +2078,17 @@ public abstract class GeneratedMessage extends AbstractMessage {
}
return Collections.unmodifiableList(newList);
}
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object get(final GeneratedMessage.Builder builder) {
+ final List newList = new ArrayList();
+ for (final Object element : (List) super.get(builder)) {
+ newList.add(invokeOrDie(getValueDescriptorMethod, element));
+ }
+ return Collections.unmodifiableList(newList);
+ }
+
@Override
public Object getRepeated(final GeneratedMessage message,
final int index) {
@@ -1230,6 +2096,12 @@ public abstract class GeneratedMessage extends AbstractMessage {
super.getRepeated(message, index));
}
@Override
+ public Object getRepeated(final GeneratedMessage.Builder builder,
+ final int index) {
+ return invokeOrDie(getValueDescriptorMethod,
+ super.getRepeated(builder, index));
+ }
+ @Override
public void setRepeated(final Builder builder,
final int index, final Object value) {
super.setRepeated(builder, index, invokeOrDie(valueOfMethod, null,
@@ -1248,13 +2120,17 @@ public abstract class GeneratedMessage extends AbstractMessage {
SingularMessageFieldAccessor(
final FieldDescriptor descriptor, final String camelCaseName,
final Class<? extends GeneratedMessage> messageClass,
- final Class<? extends Builder> builderClass) {
- super(descriptor, camelCaseName, messageClass, builderClass);
+ 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)) {
@@ -1265,7 +2141,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
// 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();
+ .mergeFrom((Message) value).buildPartial();
}
}
@@ -1277,6 +2153,10 @@ public abstract class GeneratedMessage extends AbstractMessage {
public Message.Builder newBuilder() {
return (Message.Builder) invokeOrDie(newBuilderMethod, null);
}
+ @Override
+ public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
+ return (Message.Builder) invokeOrDie(getBuilderMethodBuilder, builder);
+ }
}
private static final class RepeatedMessageFieldAccessor
@@ -1320,4 +2200,14 @@ public abstract class GeneratedMessage extends AbstractMessage {
}
}
}
+
+ /**
+ * 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);
+ }
}
diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
index 9cdd4e9..6c5136f 100644
--- a/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
+++ b/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -31,6 +31,11 @@
package com.google.protobuf;
import java.io.IOException;
+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;
@@ -41,8 +46,39 @@ import java.util.Map;
*
* @author kenton@google.com Kenton Varda
*/
-public abstract class GeneratedMessageLite extends AbstractMessageLite {
- protected GeneratedMessageLite() {}
+public abstract class GeneratedMessageLite extends AbstractMessageLite
+ implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ protected GeneratedMessageLite() {
+ }
+
+ protected GeneratedMessageLite(Builder builder) {
+ }
+
+ public Parser<? extends MessageLite> getParserForType() {
+ 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,
+ CodedOutputStream unknownFieldsCodedOutput,
+ ExtensionRegistryLite extensionRegistry,
+ int tag) throws IOException {
+ return input.skipField(tag, unknownFieldsCodedOutput);
+ }
+
+ /**
+ * Used by parsing constructors in generated classes.
+ */
+ protected void makeExtensionsImmutable() {
+ // Noop for messages without extensions.
+ }
@SuppressWarnings("unchecked")
public abstract static class Builder<MessageType extends GeneratedMessageLite,
@@ -50,6 +86,12 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
extends AbstractMessageLite.Builder<BuilderType> {
protected Builder() {}
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public BuilderType clear() {
+ unknownFields = ByteString.EMPTY;
+ return (BuilderType) this;
+ }
+
// 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 dummy clone() implementation makes it go away.
@@ -66,35 +108,73 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
public abstract MessageType getDefaultInstanceForType();
/**
- * Get the message being built. We don't just pass this to the
- * constructor because it becomes null when build() is called.
- */
- protected abstract MessageType internalGetResult();
-
- /**
* 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 ExtensionRegistryLite extensionRegistry,
- final int tag) throws IOException {
- return input.skipField(tag);
+ CodedInputStream input,
+ CodedOutputStream unknownFieldsCodedOutput,
+ ExtensionRegistryLite extensionRegistry,
+ int tag) throws IOException {
+ return input.skipField(tag, unknownFieldsCodedOutput);
}
+
+ public final ByteString getUnknownFields() {
+ return unknownFields;
+ }
+
+ public final BuilderType setUnknownFields(final ByteString unknownFields) {
+ this.unknownFields = unknownFields;
+ return (BuilderType) this;
+ }
+
+ private ByteString unknownFields = ByteString.EMPTY;
}
+
// =================================================================
// Extensions-related stuff
/**
+ * Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}.
+ */
+ public interface ExtendableMessageOrBuilder<
+ MessageType extends ExtendableMessage> extends MessageLiteOrBuilder {
+
+ /** 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(
+ GeneratedExtension<MessageType, List<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(
+ GeneratedExtension<MessageType, List<Type>> extension,
+ int index);
+ }
+
+ /**
* Lite equivalent of {@link GeneratedMessage.ExtendableMessage}.
*/
public abstract static class ExtendableMessage<
MessageType extends ExtendableMessage<MessageType>>
- extends GeneratedMessageLite {
- protected ExtendableMessage() {}
- private final FieldSet<ExtensionDescriptor> extensions =
- FieldSet.newFieldSet();
+ extends GeneratedMessageLite
+ implements ExtendableMessageOrBuilder<MessageType> {
+
+ private final FieldSet<ExtensionDescriptor> extensions;
+
+ protected ExtendableMessage() {
+ this.extensions = FieldSet.newFieldSet();
+ }
+
+ protected ExtendableMessage(ExtendableBuilder<MessageType, ?> builder) {
+ this.extensions = builder.buildExtensions();
+ }
private void verifyExtensionContainingType(
final GeneratedExtension<MessageType, ?> extension) {
@@ -108,13 +188,15 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
}
/** Check if a singular extension is present. */
- public final boolean hasExtension(
- final GeneratedExtension<MessageType, ?> extension) {
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> boolean hasExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
verifyExtensionContainingType(extension);
return extensions.hasField(extension.descriptor);
}
/** Get the number of elements in a repeated extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public final <Type> int getExtensionCount(
final GeneratedExtension<MessageType, List<Type>> extension) {
verifyExtensionContainingType(extension);
@@ -122,6 +204,7 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
}
/** Get the value of an extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
@SuppressWarnings("unchecked")
public final <Type> Type getExtension(
final GeneratedExtension<MessageType, Type> extension) {
@@ -130,17 +213,19 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
if (value == null) {
return extension.defaultValue;
} else {
- return (Type) value;
+ return (Type) extension.fromFieldSetType(value);
}
}
/** Get one element of a repeated extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
@SuppressWarnings("unchecked")
public final <Type> Type getExtension(
final GeneratedExtension<MessageType, List<Type>> extension,
final int index) {
verifyExtensionContainingType(extension);
- return (Type) extensions.getRepeatedField(extension.descriptor, index);
+ return (Type) extension.singularFromFieldSetType(
+ extensions.getRepeatedField(extension.descriptor, index));
}
/** Called by subclasses to check if all extensions are initialized. */
@@ -149,6 +234,34 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
}
/**
+ * 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(
+ CodedInputStream input,
+ CodedOutputStream unknownFieldsCodedOutput,
+ ExtensionRegistryLite extensionRegistry,
+ int tag) throws IOException {
+ return GeneratedMessageLite.parseUnknownField(
+ extensions,
+ getDefaultInstanceForType(),
+ input,
+ unknownFieldsCodedOutput,
+ extensionRegistry,
+ 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
@@ -214,53 +327,111 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
public abstract static class ExtendableBuilder<
MessageType extends ExtendableMessage<MessageType>,
BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
- extends Builder<MessageType, BuilderType> {
+ extends Builder<MessageType, BuilderType>
+ implements ExtendableMessageOrBuilder<MessageType> {
protected ExtendableBuilder() {}
- // 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 dummy clone() implementation makes it go away.
- @Override
- public BuilderType clone() {
- throw new UnsupportedOperationException(
- "This is supposed to be overridden by subclasses.");
+ private FieldSet<ExtensionDescriptor> extensions = FieldSet.emptySet();
+ private boolean extensionsIsMutable;
+
+ // For immutable message conversion.
+ void internalSetExtensionSet(FieldSet<ExtensionDescriptor> extensions) {
+ this.extensions = extensions;
}
@Override
- protected abstract MessageType internalGetResult();
+ public BuilderType clear() {
+ extensions.clear();
+ extensionsIsMutable = false;
+ return super.clear();
+ }
- /** Check if a singular extension is present. */
- public final boolean hasExtension(
+ private void ensureExtensionsIsMutable() {
+ if (!extensionsIsMutable) {
+ extensions = extensions.clone();
+ extensionsIsMutable = true;
+ }
+ }
+
+ /**
+ * Called by the build code path to create a copy of the extensions for
+ * building the message.
+ */
+ private FieldSet<ExtensionDescriptor> buildExtensions() {
+ extensions.makeImmutable();
+ extensionsIsMutable = false;
+ return extensions;
+ }
+
+ private void verifyExtensionContainingType(
final GeneratedExtension<MessageType, ?> extension) {
- return internalGetResult().hasExtension(extension);
+ if (extension.getContainingTypeDefaultInstance() !=
+ getDefaultInstanceForType()) {
+ // This can only happen if someone uses unchecked operations.
+ throw new IllegalArgumentException(
+ "This extension is for a different message type. Please make " +
+ "sure that you are not suppressing any generics type warnings.");
+ }
+ }
+
+ /** 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 GeneratedExtension<MessageType, Type> extension) {
+ verifyExtensionContainingType(extension);
+ return extensions.hasField(extension.descriptor);
}
/** Get the number of elements in a repeated extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public final <Type> int getExtensionCount(
final GeneratedExtension<MessageType, List<Type>> extension) {
- return internalGetResult().getExtensionCount(extension);
+ verifyExtensionContainingType(extension);
+ return extensions.getRepeatedFieldCount(extension.descriptor);
}
/** Get the value of an extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @SuppressWarnings("unchecked")
public final <Type> Type getExtension(
final GeneratedExtension<MessageType, Type> extension) {
- return internalGetResult().getExtension(extension);
+ verifyExtensionContainingType(extension);
+ final Object value = extensions.getField(extension.descriptor);
+ if (value == null) {
+ return extension.defaultValue;
+ } else {
+ return (Type) extension.fromFieldSetType(value);
+ }
}
/** Get one element of a repeated extension. */
+ @SuppressWarnings("unchecked")
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
public final <Type> Type getExtension(
final GeneratedExtension<MessageType, List<Type>> extension,
final int index) {
- return internalGetResult().getExtension(extension, index);
+ verifyExtensionContainingType(extension);
+ return (Type) extension.singularFromFieldSetType(
+ extensions.getRepeatedField(extension.descriptor, index));
+ }
+
+ // 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 dummy clone() implementation makes it go away.
+ @Override
+ public BuilderType clone() {
+ throw new UnsupportedOperationException(
+ "This is supposed to be overridden by subclasses.");
}
/** Set the value of an extension. */
public final <Type> BuilderType setExtension(
final GeneratedExtension<MessageType, Type> extension,
final Type value) {
- final ExtendableMessage<MessageType> message = internalGetResult();
- message.verifyExtensionContainingType(extension);
- message.extensions.setField(extension.descriptor, value);
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ extensions.setField(extension.descriptor,
+ extension.toFieldSetType(value));
return (BuilderType) this;
}
@@ -268,9 +439,10 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
public final <Type> BuilderType setExtension(
final GeneratedExtension<MessageType, List<Type>> extension,
final int index, final Type value) {
- final ExtendableMessage<MessageType> message = internalGetResult();
- message.verifyExtensionContainingType(extension);
- message.extensions.setRepeatedField(extension.descriptor, index, value);
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ extensions.setRepeatedField(extension.descriptor, index,
+ extension.singularToFieldSetType(value));
return (BuilderType) this;
}
@@ -278,141 +450,177 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
public final <Type> BuilderType addExtension(
final GeneratedExtension<MessageType, List<Type>> extension,
final Type value) {
- final ExtendableMessage<MessageType> message = internalGetResult();
- message.verifyExtensionContainingType(extension);
- message.extensions.addRepeatedField(extension.descriptor, value);
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ extensions.addRepeatedField(extension.descriptor,
+ extension.singularToFieldSetType(value));
return (BuilderType) this;
}
/** Clear an extension. */
public final <Type> BuilderType clearExtension(
final GeneratedExtension<MessageType, ?> extension) {
- final ExtendableMessage<MessageType> message = internalGetResult();
- message.verifyExtensionContainingType(extension);
- message.extensions.clearField(extension.descriptor);
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ extensions.clearField(extension.descriptor);
return (BuilderType) this;
}
+ /** Called by subclasses to check if all extensions are initialized. */
+ protected boolean extensionsAreInitialized() {
+ return extensions.isInitialized();
+ }
+
/**
* 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 ExtensionRegistryLite extensionRegistry,
- final int tag) throws IOException {
- final FieldSet<ExtensionDescriptor> extensions =
- ((ExtendableMessage) internalGetResult()).extensions;
-
- final int wireType = WireFormat.getTagWireType(tag);
- final int fieldNumber = WireFormat.getTagFieldNumber(tag);
-
- final GeneratedExtension<MessageType, ?> extension =
- extensionRegistry.findLiteExtensionByNumber(
- getDefaultInstanceForType(), fieldNumber);
-
- boolean unknown = false;
- boolean packed = false;
- if (extension == null) {
- unknown = true; // Unknown field.
- } else if (wireType == FieldSet.getWireFormatForFieldType(
- extension.descriptor.getLiteType(),
- false /* isPacked */)) {
- packed = false; // Normal, unpacked value.
- } else if (extension.descriptor.isRepeated &&
- extension.descriptor.type.isPackable() &&
- wireType == FieldSet.getWireFormatForFieldType(
- extension.descriptor.getLiteType(),
- true /* isPacked */)) {
- packed = true; // Packed value.
- } else {
- unknown = true; // Wrong wire type.
- }
+ CodedInputStream input,
+ CodedOutputStream unknownFieldsCodedOutput,
+ ExtensionRegistryLite extensionRegistry,
+ int tag) throws IOException {
+ ensureExtensionsIsMutable();
+ return GeneratedMessageLite.parseUnknownField(
+ extensions,
+ getDefaultInstanceForType(),
+ input,
+ unknownFieldsCodedOutput,
+ extensionRegistry,
+ tag);
+ }
- if (unknown) { // Unknown field or wrong wire type. Skip.
- return input.skipField(tag);
- }
+ protected final void mergeExtensionFields(final MessageType other) {
+ ensureExtensionsIsMutable();
+ extensions.mergeFrom(((ExtendableMessage) other).extensions);
+ }
+ }
- if (packed) {
- final int length = input.readRawVarint32();
- final int limit = input.pushLimit(length);
- if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) {
- while (input.getBytesUntilLimit() > 0) {
- final int rawValue = input.readEnum();
- final Object value =
- extension.descriptor.getEnumType().findValueByNumber(rawValue);
- if (value == null) {
- // If the number isn't recognized as a valid value for this
- // enum, drop it (don't even add it to unknownFields).
- return true;
- }
- extensions.addRepeatedField(extension.descriptor, value);
- }
- } else {
- while (input.getBytesUntilLimit() > 0) {
- final Object value =
- FieldSet.readPrimitiveField(input,
- extension.descriptor.getLiteType());
- extensions.addRepeatedField(extension.descriptor, value);
+ // -----------------------------------------------------------------
+
+ /**
+ * Parse an unknown field or an extension.
+ * @return {@code true} unless the tag is an end-group tag.
+ */
+ private static <MessageType extends MessageLite>
+ boolean parseUnknownField(
+ FieldSet<ExtensionDescriptor> extensions,
+ MessageType defaultInstance,
+ CodedInputStream input,
+ CodedOutputStream unknownFieldsCodedOutput,
+ ExtensionRegistryLite extensionRegistry,
+ int tag) throws IOException {
+ int wireType = WireFormat.getTagWireType(tag);
+ int fieldNumber = WireFormat.getTagFieldNumber(tag);
+
+ GeneratedExtension<MessageType, ?> extension =
+ extensionRegistry.findLiteExtensionByNumber(
+ defaultInstance, fieldNumber);
+
+ boolean unknown = false;
+ boolean packed = false;
+ if (extension == null) {
+ unknown = true; // Unknown field.
+ } else if (wireType == FieldSet.getWireFormatForFieldType(
+ extension.descriptor.getLiteType(),
+ false /* isPacked */)) {
+ packed = false; // Normal, unpacked value.
+ } else if (extension.descriptor.isRepeated &&
+ extension.descriptor.type.isPackable() &&
+ wireType == FieldSet.getWireFormatForFieldType(
+ extension.descriptor.getLiteType(),
+ true /* isPacked */)) {
+ packed = true; // Packed value.
+ } else {
+ unknown = true; // Wrong wire type.
+ }
+
+ if (unknown) { // Unknown field or wrong wire type. Skip.
+ return input.skipField(tag, unknownFieldsCodedOutput);
+ }
+
+ if (packed) {
+ int length = input.readRawVarint32();
+ int limit = input.pushLimit(length);
+ if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) {
+ while (input.getBytesUntilLimit() > 0) {
+ int rawValue = input.readEnum();
+ Object value =
+ extension.descriptor.getEnumType().findValueByNumber(rawValue);
+ if (value == null) {
+ // If the number isn't recognized as a valid value for this
+ // enum, drop it (don't even add it to unknownFields).
+ return true;
}
+ extensions.addRepeatedField(extension.descriptor,
+ extension.singularToFieldSetType(value));
}
- input.popLimit(limit);
} else {
- final Object value;
- switch (extension.descriptor.getLiteJavaType()) {
- case MESSAGE: {
- MessageLite.Builder subBuilder = null;
- if (!extension.descriptor.isRepeated()) {
- MessageLite existingValue =
- (MessageLite) extensions.getField(extension.descriptor);
- if (existingValue != null) {
- subBuilder = existingValue.toBuilder();
- }
- }
- if (subBuilder == null) {
- subBuilder = extension.messageDefaultInstance.newBuilderForType();
- }
- if (extension.descriptor.getLiteType() ==
- WireFormat.FieldType.GROUP) {
- input.readGroup(extension.getNumber(),
- subBuilder, extensionRegistry);
- } else {
- input.readMessage(subBuilder, extensionRegistry);
+ while (input.getBytesUntilLimit() > 0) {
+ Object value =
+ FieldSet.readPrimitiveField(input,
+ extension.descriptor.getLiteType(),
+ /*checkUtf8=*/ false);
+ extensions.addRepeatedField(extension.descriptor, value);
+ }
+ }
+ input.popLimit(limit);
+ } else {
+ Object value;
+ switch (extension.descriptor.getLiteJavaType()) {
+ case MESSAGE: {
+ MessageLite.Builder subBuilder = null;
+ if (!extension.descriptor.isRepeated()) {
+ MessageLite existingValue =
+ (MessageLite) extensions.getField(extension.descriptor);
+ if (existingValue != null) {
+ subBuilder = existingValue.toBuilder();
}
- value = subBuilder.build();
- break;
}
- case ENUM:
- final int rawValue = input.readEnum();
- value = extension.descriptor.getEnumType()
- .findValueByNumber(rawValue);
- // If the number isn't recognized as a valid value for this enum,
- // drop it.
- if (value == null) {
- return true;
- }
- break;
- default:
- value = FieldSet.readPrimitiveField(input,
- extension.descriptor.getLiteType());
- break;
- }
-
- if (extension.descriptor.isRepeated()) {
- extensions.addRepeatedField(extension.descriptor, value);
- } else {
- extensions.setField(extension.descriptor, value);
+ if (subBuilder == null) {
+ subBuilder = extension.getMessageDefaultInstance()
+ .newBuilderForType();
+ }
+ if (extension.descriptor.getLiteType() ==
+ WireFormat.FieldType.GROUP) {
+ input.readGroup(extension.getNumber(),
+ subBuilder, extensionRegistry);
+ } else {
+ input.readMessage(subBuilder, extensionRegistry);
+ }
+ value = subBuilder.build();
+ break;
}
+ case ENUM:
+ int rawValue = input.readEnum();
+ value = extension.descriptor.getEnumType()
+ .findValueByNumber(rawValue);
+ // If the number isn't recognized as a valid value for this enum,
+ // write it to unknown fields object.
+ if (value == null) {
+ unknownFieldsCodedOutput.writeRawVarint32(tag);
+ unknownFieldsCodedOutput.writeUInt32NoTag(rawValue);
+ return true;
+ }
+ break;
+ default:
+ value = FieldSet.readPrimitiveField(input,
+ extension.descriptor.getLiteType(),
+ /*checkUtf8=*/ false);
+ break;
}
- return true;
+ if (extension.descriptor.isRepeated()) {
+ extensions.addRepeatedField(extension.descriptor,
+ extension.singularToFieldSetType(value));
+ } else {
+ extensions.setField(extension.descriptor,
+ extension.singularToFieldSetType(value));
+ }
}
- protected final void mergeExtensionFields(final MessageType other) {
- ((ExtendableMessage) internalGetResult()).extensions.mergeFrom(
- ((ExtendableMessage) other).extensions);
- }
+ return true;
}
// -----------------------------------------------------------------
@@ -420,14 +628,50 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
/** For use by generated code only. */
public static <ContainingType extends MessageLite, Type>
GeneratedExtension<ContainingType, Type>
- newGeneratedExtension() {
- return new GeneratedExtension<ContainingType, Type>();
+ newSingularGeneratedExtension(
+ final ContainingType containingTypeDefaultInstance,
+ final Type defaultValue,
+ final MessageLite messageDefaultInstance,
+ final Internal.EnumLiteMap<?> enumTypeMap,
+ final int number,
+ final WireFormat.FieldType type,
+ final Class singularType) {
+ return new GeneratedExtension<ContainingType, Type>(
+ containingTypeDefaultInstance,
+ defaultValue,
+ messageDefaultInstance,
+ new ExtensionDescriptor(enumTypeMap, number, type,
+ false /* isRepeated */,
+ false /* isPacked */),
+ singularType);
}
- private static final class ExtensionDescriptor
+ /** For use by generated code only. */
+ public static <ContainingType extends MessageLite, Type>
+ GeneratedExtension<ContainingType, Type>
+ newRepeatedGeneratedExtension(
+ final ContainingType containingTypeDefaultInstance,
+ final MessageLite messageDefaultInstance,
+ final Internal.EnumLiteMap<?> enumTypeMap,
+ final int number,
+ final WireFormat.FieldType type,
+ final boolean isPacked,
+ final Class singularType) {
+ @SuppressWarnings("unchecked") // Subclasses ensure Type is a List
+ Type emptyList = (Type) Collections.emptyList();
+ return new GeneratedExtension<ContainingType, Type>(
+ containingTypeDefaultInstance,
+ emptyList,
+ messageDefaultInstance,
+ new ExtensionDescriptor(
+ enumTypeMap, number, type, true /* isRepeated */, isPacked),
+ singularType);
+ }
+
+ static final class ExtensionDescriptor
implements FieldSet.FieldDescriptorLite<
ExtensionDescriptor> {
- private ExtensionDescriptor(
+ ExtensionDescriptor(
final Internal.EnumLiteMap<?> enumTypeMap,
final int number,
final WireFormat.FieldType type,
@@ -440,11 +684,11 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
this.isPacked = isPacked;
}
- private final Internal.EnumLiteMap<?> enumTypeMap;
- private final int number;
- private final WireFormat.FieldType type;
- private final boolean isRepeated;
- private final boolean isPacked;
+ final Internal.EnumLiteMap<?> enumTypeMap;
+ final int number;
+ final WireFormat.FieldType type;
+ final boolean isRepeated;
+ final boolean isPacked;
public int getNumber() {
return number;
@@ -476,72 +720,103 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
}
+
public int compareTo(ExtensionDescriptor other) {
return number - other.number;
}
}
+ // =================================================================
+
+ /** Calls Class.getMethod and throws a RuntimeException if it fails. */
+ @SuppressWarnings("unchecked")
+ static Method getMethodOrDie(Class clazz, String name, 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. */
+ static Object invokeOrDie(Method method, Object object, 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);
+ }
+ }
+ }
+
/**
* Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
*
* Users should ignore the contents of this class and only use objects of
* this type as parameters to extension accessors and ExtensionRegistry.add().
*/
- public static final class GeneratedExtension<
+ public static class GeneratedExtension<
ContainingType extends MessageLite, Type> {
- // We can't always initialize a GeneratedExtension when we first construct
- // it due to initialization order difficulties (namely, the default
- // instances may not have been constructed yet). So, we construct an
- // uninitialized GeneratedExtension once, then call internalInit() on it
- // later. Generated code will always call internalInit() on all extensions
- // as part of the static initialization code, and internalInit() throws an
- // exception if called more than once, so this method is useless to users.
- private GeneratedExtension() {}
-
- private void internalInit(
+
+ /**
+ * Create a new isntance with the given parameters.
+ *
+ * The last parameter {@code singularType} is only needed for enum types.
+ * We store integer values for enum types in a {@link ExtendableMessage}
+ * and use Java reflection to convert an integer value back into a concrete
+ * enum object.
+ */
+ GeneratedExtension(
final ContainingType containingTypeDefaultInstance,
final Type defaultValue,
final MessageLite messageDefaultInstance,
- final ExtensionDescriptor descriptor) {
+ final ExtensionDescriptor descriptor,
+ Class singularType) {
+ // Defensive checks to verify the correct initialization order of
+ // GeneratedExtensions and their related GeneratedMessages.
+ if (containingTypeDefaultInstance == null) {
+ throw new IllegalArgumentException(
+ "Null containingTypeDefaultInstance");
+ }
+ if (descriptor.getLiteType() == WireFormat.FieldType.MESSAGE &&
+ messageDefaultInstance == null) {
+ throw new IllegalArgumentException(
+ "Null messageDefaultInstance");
+ }
this.containingTypeDefaultInstance = containingTypeDefaultInstance;
this.defaultValue = defaultValue;
this.messageDefaultInstance = messageDefaultInstance;
this.descriptor = descriptor;
- }
-
- /** For use by generated code only. */
- public void internalInitSingular(
- final ContainingType containingTypeDefaultInstance,
- final Type defaultValue,
- final MessageLite messageDefaultInstance,
- final Internal.EnumLiteMap<?> enumTypeMap,
- final int number,
- final WireFormat.FieldType type) {
- internalInit(
- containingTypeDefaultInstance, defaultValue, messageDefaultInstance,
- new ExtensionDescriptor(enumTypeMap, number, type,
- false /* isRepeated */, false /* isPacked */));
- }
- /** For use by generated code only. */
- public void internalInitRepeated(
- final ContainingType containingTypeDefaultInstance,
- final MessageLite messageDefaultInstance,
- final Internal.EnumLiteMap<?> enumTypeMap,
- final int number,
- final WireFormat.FieldType type,
- final boolean isPacked) {
- internalInit(
- containingTypeDefaultInstance, (Type) Collections.emptyList(),
- messageDefaultInstance,
- new ExtensionDescriptor(
- enumTypeMap, number, type, true /* isRepeated */, isPacked));
+ // Use Java reflection to invoke the static method {@code valueOf} of
+ // enum types in order to convert integers to concrete enum objects.
+ this.singularType = singularType;
+ if (Internal.EnumLite.class.isAssignableFrom(singularType)) {
+ this.enumValueOf = getMethodOrDie(
+ singularType, "valueOf", int.class);
+ } else {
+ this.enumValueOf = null;
+ }
}
- private ContainingType containingTypeDefaultInstance;
- private Type defaultValue;
- private MessageLite messageDefaultInstance;
- private ExtensionDescriptor descriptor;
+ final ContainingType containingTypeDefaultInstance;
+ final Type defaultValue;
+ final MessageLite messageDefaultInstance;
+ final ExtensionDescriptor descriptor;
+ final Class singularType;
+ final Method enumValueOf;
/**
* Default instance of the type being extended, used to identify that type.
@@ -555,12 +830,120 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite {
return descriptor.getNumber();
}
+
/**
- * If the extension is an embedded message, this is the default instance of
- * that type.
+ * If the extension is an embedded message or group, returns the default
+ * instance of the message.
*/
public MessageLite getMessageDefaultInstance() {
return messageDefaultInstance;
}
+
+ @SuppressWarnings("unchecked")
+ Object fromFieldSetType(final Object value) {
+ if (descriptor.isRepeated()) {
+ if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
+ final List result = new ArrayList();
+ for (final Object element : (List) value) {
+ result.add(singularFromFieldSetType(element));
+ }
+ return result;
+ } else {
+ return value;
+ }
+ } else {
+ return singularFromFieldSetType(value);
+ }
+ }
+
+ Object singularFromFieldSetType(final Object value) {
+ if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
+ return invokeOrDie(enumValueOf, null, (Integer) value);
+ } else {
+ return value;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ Object toFieldSetType(final Object value) {
+ if (descriptor.isRepeated()) {
+ if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
+ final List result = new ArrayList();
+ for (final Object element : (List) value) {
+ result.add(singularToFieldSetType(element));
+ }
+ return result;
+ } else {
+ return value;
+ }
+ } else {
+ return singularToFieldSetType(value);
+ }
+ }
+
+ Object singularToFieldSetType(final Object value) {
+ if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
+ return ((Internal.EnumLite) value).getNumber();
+ } else {
+ return value;
+ }
+ }
+ }
+
+ /**
+ * 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 {
+ private static final long serialVersionUID = 0L;
+
+ private String messageClassName;
+ private byte[] asBytes;
+
+ /**
+ * Creates the serialized form by calling {@link com.google.protobuf.MessageLite#toByteArray}.
+ * @param regularForm the message to serialize
+ */
+ SerializedForm(MessageLite regularForm) {
+ messageClassName = regularForm.getClass().getName();
+ asBytes = regularForm.toByteArray();
+ }
+
+ /**
+ * When read from an ObjectInputStream, this method converts this object
+ * back to the regular form. Part of Java's serialization magic.
+ * @return a GeneratedMessage of the type that was serialized
+ */
+ @SuppressWarnings("unchecked")
+ protected Object readResolve() throws ObjectStreamException {
+ try {
+ Class messageClass = Class.forName(messageClassName);
+ Method newBuilder = messageClass.getMethod("newBuilder");
+ MessageLite.Builder builder =
+ (MessageLite.Builder) newBuilder.invoke(null);
+ builder.mergeFrom(asBytes);
+ return builder.buildPartial();
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("Unable to find proto buffer class", e);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException("Unable to find newBuilder method", e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("Unable to call newBuilder method", e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException("Error calling newBuilder", e.getCause());
+ } catch (InvalidProtocolBufferException e) {
+ 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);
}
}
diff --git a/java/src/main/java/com/google/protobuf/Internal.java b/java/src/main/java/com/google/protobuf/Internal.java
index 965465e..48d29e6 100644
--- a/java/src/main/java/com/google/protobuf/Internal.java
+++ b/java/src/main/java/com/google/protobuf/Internal.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -30,7 +30,11 @@
package com.google.protobuf;
+import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
/**
* The classes contained within are used internally by the Protocol Buffer
@@ -98,6 +102,112 @@ public class Internal {
"Java VM does not support a standard character set.", e);
}
}
+ /**
+ * Helper called by generated code to construct default values for bytes
+ * fields.
+ * <p>
+ * This is like {@link #bytesDefaultValue}, but returns a byte array.
+ */
+ public static byte[] byteArrayDefaultValue(String bytes) {
+ try {
+ return bytes.getBytes("ISO-8859-1");
+ } catch (UnsupportedEncodingException e) {
+ // This should never happen since all JVMs are required to implement
+ // ISO-8859-1.
+ throw new IllegalStateException(
+ "Java VM does not support a standard character set.", e);
+ }
+ }
+
+ /**
+ * Helper called by generated code to construct default values for bytes
+ * fields.
+ * <p>
+ * This is like {@link #bytesDefaultValue}, but returns a ByteBuffer.
+ */
+ public static ByteBuffer byteBufferDefaultValue(String bytes) {
+ return ByteBuffer.wrap(byteArrayDefaultValue(bytes));
+ }
+
+ /**
+ * Create a new ByteBuffer and copy all the content of {@code source}
+ * ByteBuffer to the new ByteBuffer. The new ByteBuffer's limit and
+ * capacity will be source.capacity(), and its position will be 0.
+ * Note that the state of {@code source} ByteBuffer won't be changed.
+ */
+ public static ByteBuffer copyByteBuffer(ByteBuffer source) {
+ // Make a duplicate of the source ByteBuffer and read data from the
+ // duplicate. This is to avoid affecting the source ByteBuffer's state.
+ ByteBuffer temp = source.duplicate();
+ // We want to copy all the data in the source ByteBuffer, not just the
+ // remaining bytes.
+ temp.clear();
+ ByteBuffer result = ByteBuffer.allocate(temp.capacity());
+ result.put(temp);
+ result.clear();
+ return result;
+ }
+
+ /**
+ * Helper called by generated code to determine if a byte array is a valid
+ * UTF-8 encoded string such that the original bytes can be converted to
+ * a String object and then back to a byte array round tripping the bytes
+ * without loss. More precisely, returns {@code true} whenever:
+ * <pre> {@code
+ * Arrays.equals(byteString.toByteArray(),
+ * new String(byteString.toByteArray(), "UTF-8").getBytes("UTF-8"))
+ * }</pre>
+ *
+ * <p>This method rejects "overlong" byte sequences, as well as
+ * 3-byte sequences that would map to a surrogate character, in
+ * accordance with the restricted definition of UTF-8 introduced in
+ * Unicode 3.1. Note that the UTF-8 decoder included in Oracle's
+ * JDK has been modified to also reject "overlong" byte sequences,
+ * but currently (2011) still accepts 3-byte surrogate character
+ * byte sequences.
+ *
+ * <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>As of 2011-02, this method simply returns the result of {@link
+ * ByteString#isValidUtf8()}. Calling that method directly is preferred.
+ *
+ * @param byteString the string to check
+ * @return whether the byte array is round trippable
+ */
+ public static boolean isValidUtf8(ByteString byteString) {
+ return byteString.isValidUtf8();
+ }
+
+ /**
+ * Like {@link #isValidUtf8(ByteString)} but for byte arrays.
+ */
+ public static boolean isValidUtf8(byte[] byteArray) {
+ return Utf8.isValidUtf8(byteArray);
+ }
+
+ /**
+ * Helper method to get the UTF-8 bytes of a string.
+ */
+ public static byte[] toByteArray(String value) {
+ try {
+ return value.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not supported?", e);
+ }
+ }
+
+ /**
+ * Helper method to convert a byte array to a string using UTF-8 encoding.
+ */
+ public static String toStringUtf8(byte[] bytes) {
+ try {
+ return new String(bytes, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not supported?", e);
+ }
+ }
/**
* Interface for an enum value or value descriptor, to be used in FieldSet.
@@ -118,4 +228,164 @@ public class Internal {
public interface EnumLiteMap<T extends EnumLite> {
T findValueByNumber(int number);
}
+
+ /**
+ * Helper method for implementing {@link MessageLite#hashCode()} for longs.
+ * @see Long#hashCode()
+ */
+ public static int hashLong(long n) {
+ return (int) (n ^ (n >>> 32));
+ }
+
+ /**
+ * Helper method for implementing {@link MessageLite#hashCode()} for
+ * booleans.
+ * @see Boolean#hashCode()
+ */
+ public static int hashBoolean(boolean b) {
+ return b ? 1231 : 1237;
+ }
+
+ /**
+ * Helper method for implementing {@link MessageLite#hashCode()} for enums.
+ * <p>
+ * This is needed because {@link java.lang.Enum#hashCode()} is final, but we
+ * need to use the field number as the hash code to ensure compatibility
+ * between statically and dynamically generated enum objects.
+ */
+ public static int hashEnum(EnumLite e) {
+ return e.getNumber();
+ }
+
+ /**
+ * Helper method for implementing {@link MessageLite#hashCode()} for
+ * enum lists.
+ */
+ public static int hashEnumList(List<? extends EnumLite> list) {
+ int hash = 1;
+ for (EnumLite e : list) {
+ hash = 31 * hash + hashEnum(e);
+ }
+ return hash;
+ }
+
+ /**
+ * Helper method for implementing {@link MessageLite#equals()} for bytes field.
+ */
+ public static boolean equals(List<byte[]> a, List<byte[]> b) {
+ if (a.size() != b.size()) return false;
+ for (int i = 0; i < a.size(); ++i) {
+ if (!Arrays.equals(a.get(i), b.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Helper method for implementing {@link MessageLite#hashCode()} for bytes field.
+ */
+ public static int hashCode(List<byte[]> list) {
+ int hash = 1;
+ for (byte[] bytes : list) {
+ hash = 31 * hash + hashCode(bytes);
+ }
+ return hash;
+ }
+
+ /**
+ * Helper method for implementing {@link MessageLite#hashCode()} for bytes field.
+ */
+ public static int hashCode(byte[] bytes) {
+ // 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.
+ return LiteralByteString.hashCode(bytes);
+ }
+
+ /**
+ * Helper method for implementing {@link MessageLite#equals()} for bytes
+ * field.
+ */
+ public static boolean equalsByteBuffer(ByteBuffer a, ByteBuffer b) {
+ if (a.capacity() != b.capacity()) {
+ return false;
+ }
+ // ByteBuffer.equals() will only compare the remaining bytes, but we want to
+ // compare all the content.
+ return a.duplicate().clear().equals(b.duplicate().clear());
+ }
+
+ /**
+ * Helper method for implementing {@link MessageLite#equals()} for bytes
+ * field.
+ */
+ public static boolean equalsByteBuffer(
+ List<ByteBuffer> a, List<ByteBuffer> b) {
+ if (a.size() != b.size()) {
+ return false;
+ }
+ for (int i = 0; i < a.size(); ++i) {
+ if (!equalsByteBuffer(a.get(i), b.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Helper method for implementing {@link MessageLite#hashCode()} for bytes
+ * field.
+ */
+ public static int hashCodeByteBuffer(List<ByteBuffer> list) {
+ int hash = 1;
+ for (ByteBuffer bytes : list) {
+ hash = 31 * hash + hashCodeByteBuffer(bytes);
+ }
+ return hash;
+ }
+
+ private static final int DEFAULT_BUFFER_SIZE = 4096;
+
+ /**
+ * Helper method for implementing {@link MessageLite#hashCode()} for bytes
+ * field.
+ */
+ public static int hashCodeByteBuffer(ByteBuffer bytes) {
+ if (bytes.hasArray()) {
+ // Fast path.
+ int h = LiteralByteString.hashCode(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
+ // hash value.
+ final int bufferSize = bytes.capacity() > DEFAULT_BUFFER_SIZE
+ ? DEFAULT_BUFFER_SIZE : bytes.capacity();
+ final byte[] buffer = new byte[bufferSize];
+ final ByteBuffer duplicated = bytes.duplicate();
+ duplicated.clear();
+ int h = bytes.capacity();
+ while (duplicated.remaining() > 0) {
+ final int length = duplicated.remaining() <= bufferSize ?
+ duplicated.remaining() : bufferSize;
+ duplicated.get(buffer, 0, length);
+ h = LiteralByteString.hashCode(h, buffer, 0, length);
+ }
+ return h == 0 ? 1 : h;
+ }
+ }
+
+ /**
+ * An empty byte array constant used in generated code.
+ */
+ public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+
+ /**
+ * An empty byte array constant used in generated code.
+ */
+ public static final ByteBuffer EMPTY_BYTE_BUFFER =
+ ByteBuffer.wrap(EMPTY_BYTE_ARRAY);
+
}
diff --git a/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java b/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
index 90f7ffb..367fa23 100644
--- a/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
+++ b/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -40,11 +40,32 @@ import java.io.IOException;
*/
public class InvalidProtocolBufferException extends IOException {
private static final long serialVersionUID = -1616151763072450476L;
+ private MessageLite unfinishedMessage = null;
public InvalidProtocolBufferException(final String description) {
super(description);
}
+ /**
+ * Attaches an unfinished message to the exception to support best-effort
+ * parsing in {@code Parser} interface.
+ *
+ * @return this
+ */
+ public InvalidProtocolBufferException setUnfinishedMessage(
+ MessageLite unfinishedMessage) {
+ this.unfinishedMessage = unfinishedMessage;
+ return this;
+ }
+
+ /**
+ * Returns the unfinished message attached to the exception, or null if
+ * no message is attached.
+ */
+ public MessageLite getUnfinishedMessage() {
+ return unfinishedMessage;
+ }
+
static InvalidProtocolBufferException truncatedMessage() {
return new InvalidProtocolBufferException(
"While parsing a protocol message, the input ended unexpectedly " +
@@ -90,4 +111,12 @@ public class InvalidProtocolBufferException extends IOException {
"Protocol message was too large. May be malicious. " +
"Use CodedInputStream.setSizeLimit() to increase the size limit.");
}
+
+ static InvalidProtocolBufferException parseFailure() {
+ return new InvalidProtocolBufferException("Failed to parse the message.");
+ }
+
+ static InvalidProtocolBufferException invalidUtf8() {
+ return new InvalidProtocolBufferException("Protocol message had invalid UTF-8.");
+ }
}
diff --git a/java/src/main/java/com/google/protobuf/LazyField.java b/java/src/main/java/com/google/protobuf/LazyField.java
new file mode 100644
index 0000000..3da8b90
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/LazyField.java
@@ -0,0 +1,154 @@
+// 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.Iterator;
+import java.util.Map.Entry;
+
+/**
+ * LazyField encapsulates the logic of lazily parsing message fields. It stores
+ * the message in a ByteString initially and then parse it on-demand.
+ *
+ * Most of key methods are implemented in {@link LazyFieldLite} but this class
+ * can contain default instance of the message to provide {@code hashCode()},
+ * {@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 euqals()} and
+ * {@code toString()}.
+ */
+ private final MessageLite defaultInstance;
+
+ public LazyField(MessageLite defaultInstance,
+ ExtensionRegistryLite extensionRegistry, ByteString bytes) {
+ super(extensionRegistry, bytes);
+
+ this.defaultInstance = defaultInstance;
+ }
+
+ @Override
+ public boolean containsDefaultInstance() {
+ return super.containsDefaultInstance() || value == defaultInstance;
+ }
+
+ public MessageLite getValue() {
+ return getValue(defaultInstance);
+ }
+
+ @Override
+ public int hashCode() {
+ return getValue().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return getValue().equals(obj);
+ }
+
+ @Override
+ public String toString() {
+ return getValue().toString();
+ }
+
+ // ====================================================
+
+ /**
+ * LazyEntry and LazyIterator are used to encapsulate the LazyField, when
+ * users iterate all fields from FieldSet.
+ */
+ static class LazyEntry<K> implements Entry<K, Object> {
+ private Entry<K, LazyField> entry;
+
+ private LazyEntry(Entry<K, LazyField> entry) {
+ this.entry = entry;
+ }
+
+ // @Override
+ public K getKey() {
+ return entry.getKey();
+ }
+
+ // @Override
+ public Object getValue() {
+ LazyField field = entry.getValue();
+ if (field == null) {
+ return null;
+ }
+ return field.getValue();
+ }
+
+ public LazyField getField() {
+ return entry.getValue();
+ }
+
+ // @Override
+ public Object setValue(Object value) {
+ if (!(value instanceof MessageLite)) {
+ throw new IllegalArgumentException(
+ "LazyField now only used for MessageSet, "
+ + "and the value of MessageSet must be an instance of MessageLite");
+ }
+ return entry.getValue().setValue((MessageLite) value);
+ }
+ }
+
+ static class LazyIterator<K> implements Iterator<Entry<K, Object>> {
+ private Iterator<Entry<K, Object>> iterator;
+
+ public LazyIterator(Iterator<Entry<K, Object>> iterator) {
+ this.iterator = iterator;
+ }
+
+ // @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @SuppressWarnings("unchecked")
+ // @Override
+ public Entry<K, Object> next() {
+ Entry<K, ?> entry = iterator.next();
+ if (entry.getValue() instanceof LazyField) {
+ return new LazyEntry<K>((Entry<K, LazyField>) entry);
+ }
+ return (Entry<K, Object>) entry;
+ }
+
+ // @Override
+ public void remove() {
+ iterator.remove();
+ }
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/LazyFieldLite.java b/java/src/main/java/com/google/protobuf/LazyFieldLite.java
new file mode 100644
index 0000000..1fc80e8
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/LazyFieldLite.java
@@ -0,0 +1,176 @@
+// 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;
+
+/**
+ * LazyFieldLite encapsulates the logic of lazily parsing message fields. It stores
+ * the message in a ByteString initially and then parse it on-demand.
+ *
+ * LazyField is thread-compatible e.g. concurrent read are safe, however,
+ * synchronizations are needed under read/write situations.
+ *
+ * This class is internal implementation detail, so you don't need to use it directly.
+ *
+ * @author xiangl@google.com (Xiang Li)
+ */
+public class LazyFieldLite {
+ private ByteString bytes;
+ private ExtensionRegistryLite extensionRegistry;
+ private volatile boolean isDirty = false;
+
+ protected volatile MessageLite value;
+
+ public LazyFieldLite(ExtensionRegistryLite extensionRegistry, ByteString bytes) {
+ this.extensionRegistry = extensionRegistry;
+ this.bytes = bytes;
+ }
+
+ public LazyFieldLite() {
+ }
+
+ public static LazyFieldLite fromValue(MessageLite value) {
+ LazyFieldLite lf = new LazyFieldLite();
+ lf.setValue(value);
+ return lf;
+ }
+
+ public boolean containsDefaultInstance() {
+ return value == null && bytes == null;
+ }
+
+ public void clear() {
+ bytes = null;
+ value = null;
+ extensionRegistry = null;
+ isDirty = true;
+ }
+
+ /**
+ * Returns message instance. At first time, serialized data is parsed by
+ * {@code defaultInstance.getParserForType()}.
+ *
+ * @param defaultInstance its message's default instance. It's also used to get parser for the
+ * message type.
+ */
+ public MessageLite getValue(MessageLite defaultInstance) {
+ ensureInitialized(defaultInstance);
+ return value;
+ }
+
+ /**
+ * LazyField is not thread-safe for write access. Synchronizations are needed
+ * under read/write situations.
+ */
+ public MessageLite setValue(MessageLite value) {
+ MessageLite originalValue = this.value;
+ this.value = value;
+ bytes = null;
+ isDirty = true;
+ return originalValue;
+ }
+
+ public void merge(LazyFieldLite value) {
+ if (value.containsDefaultInstance()) {
+ return;
+ }
+
+ if (bytes == null) {
+ this.bytes = value.bytes;
+ } else {
+ this.bytes.concat(value.toByteString());
+ }
+ isDirty = false;
+ }
+
+ public void setByteString(ByteString bytes, ExtensionRegistryLite extensionRegistry) {
+ this.bytes = bytes;
+ this.extensionRegistry = extensionRegistry;
+ isDirty = false;
+ }
+
+ public ExtensionRegistryLite getExtensionRegistry() {
+ return extensionRegistry;
+ }
+
+ /**
+ * Due to the optional field can be duplicated at the end of serialized
+ * bytes, which will make the serialized size changed after LazyField
+ * parsed. Be careful when using this method.
+ */
+ public int getSerializedSize() {
+ if (isDirty) {
+ return value.getSerializedSize();
+ }
+ return bytes.size();
+ }
+
+ public ByteString toByteString() {
+ if (!isDirty) {
+ return bytes;
+ }
+ synchronized (this) {
+ if (!isDirty) {
+ return bytes;
+ }
+ if (value == null) {
+ bytes = ByteString.EMPTY;
+ } else {
+ bytes = value.toByteString();
+ }
+ isDirty = false;
+ return bytes;
+ }
+ }
+
+ protected void ensureInitialized(MessageLite defaultInstance) {
+ if (value != null) {
+ return;
+ }
+ synchronized (this) {
+ if (value != null) {
+ return;
+ }
+ try {
+ if (bytes != null) {
+ value = defaultInstance.getParserForType()
+ .parseFrom(bytes, extensionRegistry);
+ } else {
+ value = defaultInstance;
+ }
+ } catch (IOException e) {
+ // TODO(xiangl): Refactory the API to support the exception thrown from
+ // lazily load messages.
+ }
+ }
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/LazyStringArrayList.java b/java/src/main/java/com/google/protobuf/LazyStringArrayList.java
new file mode 100644
index 0000000..61c7e1e
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/LazyStringArrayList.java
@@ -0,0 +1,367 @@
+// 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.List;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.RandomAccess;
+
+/**
+ * An implementation of {@link LazyStringList} that wraps an ArrayList. Each
+ * element is one of String, ByteString, or byte[]. It caches the last one
+ * requested which is most likely the one needed next. This minimizes memory
+ * usage while satisfying the most common use cases.
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong>
+ * If multiple threads access an <tt>ArrayList</tt> instance concurrently,
+ * and at least one of the threads modifies the list structurally, it
+ * <i>must</i> be synchronized externally. (A structural modification is
+ * any operation that adds or deletes one or more elements, or explicitly
+ * resizes the backing array; merely setting the value of an element is not
+ * a structural modification.) This is typically accomplished by
+ * synchronizing on some object that naturally encapsulates the list.
+ * <p>
+ * If the implementation is accessed via concurrent reads, this is thread safe.
+ * Conversions are done in a thread safe manner. It's possible that the
+ * conversion may happen more than once if two threads attempt to access the
+ * same element and the modifications were not visible to each other, but this
+ * will not result in any corruption of the list or change in behavior other
+ * than performance.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class LazyStringArrayList extends AbstractList<String>
+ implements LazyStringList, RandomAccess {
+
+ public static final LazyStringList EMPTY =
+ new LazyStringArrayList().getUnmodifiableView();
+
+ private final List<Object> list;
+
+ public LazyStringArrayList() {
+ list = new ArrayList<Object>();
+ }
+
+ public LazyStringArrayList(LazyStringList from) {
+ list = new ArrayList<Object>(from.size());
+ addAll(from);
+ }
+
+ public LazyStringArrayList(List<String> from) {
+ list = new ArrayList<Object>(from);
+ }
+
+ @Override
+ public String get(int index) {
+ Object o = list.get(index);
+ if (o instanceof String) {
+ return (String) o;
+ } else if (o instanceof ByteString) {
+ ByteString bs = (ByteString) o;
+ String s = bs.toStringUtf8();
+ if (bs.isValidUtf8()) {
+ list.set(index, s);
+ }
+ return s;
+ } else {
+ byte[] ba = (byte[]) o;
+ String s = Internal.toStringUtf8(ba);
+ if (Internal.isValidUtf8(ba)) {
+ list.set(index, s);
+ }
+ return s;
+ }
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ @Override
+ public String set(int index, String s) {
+ Object o = list.set(index, s);
+ return asString(o);
+ }
+
+ @Override
+ public void add(int index, String element) {
+ list.add(index, element);
+ modCount++;
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends String> c) {
+ // The default implementation of AbstractCollection.addAll(Collection)
+ // delegates to add(Object). This implementation instead delegates to
+ // addAll(int, Collection), which makes a special case for Collections
+ // which are instances of LazyStringList.
+ return addAll(size(), c);
+ }
+
+ @Override
+ public boolean addAll(int index, Collection<? extends String> c) {
+ // When copying from another LazyStringList, directly copy the underlying
+ // elements rather than forcing each element to be decoded to a String.
+ Collection<?> collection = c instanceof LazyStringList
+ ? ((LazyStringList) c).getUnderlyingElements() : c;
+ boolean ret = list.addAll(index, collection);
+ modCount++;
+ return ret;
+ }
+
+ // @Override
+ public boolean addAllByteString(Collection<? extends ByteString> values) {
+ boolean ret = list.addAll(values);
+ modCount++;
+ return ret;
+ }
+
+ // @Override
+ public boolean addAllByteArray(Collection<byte[]> c) {
+ boolean ret = list.addAll(c);
+ modCount++;
+ return ret;
+ }
+
+ @Override
+ public String remove(int index) {
+ Object o = list.remove(index);
+ modCount++;
+ return asString(o);
+ }
+
+ @Override
+ public void clear() {
+ list.clear();
+ modCount++;
+ }
+
+ // @Override
+ public void add(ByteString element) {
+ list.add(element);
+ modCount++;
+ }
+
+ // @Override
+ public void add(byte[] element) {
+ list.add(element);
+ modCount++;
+ }
+
+ // @Override
+ public ByteString getByteString(int index) {
+ Object o = list.get(index);
+ ByteString b = asByteString(o);
+ if (b != o) {
+ list.set(index, b);
+ }
+ return b;
+ }
+
+ // @Override
+ public byte[] getByteArray(int index) {
+ Object o = list.get(index);
+ byte[] b = asByteArray(o);
+ if (b != o) {
+ list.set(index, b);
+ }
+ return b;
+ }
+
+ // @Override
+ public void set(int index, ByteString s) {
+ list.set(index, s);
+ }
+
+ // @Override
+ public void set(int index, byte[] s) {
+ list.set(index, s);
+ }
+
+
+ private static String asString(Object o) {
+ if (o instanceof String) {
+ return (String) o;
+ } else if (o instanceof ByteString) {
+ return ((ByteString) o).toStringUtf8();
+ } else {
+ return Internal.toStringUtf8((byte[]) o);
+ }
+ }
+
+ private static ByteString asByteString(Object o) {
+ if (o instanceof ByteString) {
+ return (ByteString) o;
+ } else if (o instanceof String) {
+ return ByteString.copyFromUtf8((String) o);
+ } else {
+ return ByteString.copyFrom((byte[]) o);
+ }
+ }
+
+ private static byte[] asByteArray(Object o) {
+ if (o instanceof byte[]) {
+ return (byte[]) o;
+ } else if (o instanceof String) {
+ return Internal.toByteArray((String) o);
+ } else {
+ return ((ByteString) o).toByteArray();
+ }
+ }
+
+ // @Override
+ public List<?> getUnderlyingElements() {
+ return Collections.unmodifiableList(list);
+ }
+
+ // @Override
+ public void mergeFrom(LazyStringList other) {
+ for (Object o : other.getUnderlyingElements()) {
+ if (o instanceof byte[]) {
+ byte[] b = (byte[]) o;
+ // Byte array's content is mutable so they should be copied rather than
+ // shared when merging from one message to another.
+ list.add(Arrays.copyOf(b, b.length));
+ } else {
+ list.add(o);
+ }
+ }
+ }
+
+ private static class ByteArrayListView extends AbstractList<byte[]>
+ implements RandomAccess {
+ private final List<Object> list;
+
+ ByteArrayListView(List<Object> list) {
+ this.list = list;
+ }
+
+ @Override
+ public byte[] get(int index) {
+ Object o = list.get(index);
+ byte[] b = asByteArray(o);
+ if (b != o) {
+ list.set(index, b);
+ }
+ return b;
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ @Override
+ public byte[] set(int index, byte[] s) {
+ Object o = list.set(index, s);
+ modCount++;
+ return asByteArray(o);
+ }
+
+ @Override
+ public void add(int index, byte[] s) {
+ list.add(index, s);
+ modCount++;
+ }
+
+ @Override
+ public byte[] remove(int index) {
+ Object o = list.remove(index);
+ modCount++;
+ return asByteArray(o);
+ }
+ }
+
+ // @Override
+ public List<byte[]> asByteArrayList() {
+ return new ByteArrayListView(list);
+ }
+
+ private static class ByteStringListView extends AbstractList<ByteString>
+ implements RandomAccess {
+ private final List<Object> list;
+
+ ByteStringListView(List<Object> list) {
+ this.list = list;
+ }
+
+ @Override
+ public ByteString get(int index) {
+ Object o = list.get(index);
+ ByteString b = asByteString(o);
+ if (b != o) {
+ list.set(index, b);
+ }
+ return b;
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ @Override
+ public ByteString set(int index, ByteString s) {
+ Object o = list.set(index, s);
+ modCount++;
+ return asByteString(o);
+ }
+
+ @Override
+ public void add(int index, ByteString s) {
+ list.add(index, s);
+ modCount++;
+ }
+
+ @Override
+ public ByteString remove(int index) {
+ Object o = list.remove(index);
+ modCount++;
+ return asByteString(o);
+ }
+ }
+
+ // @Override
+ public List<ByteString> asByteStringList() {
+ return new ByteStringListView(list);
+ }
+
+ // @Override
+ public LazyStringList getUnmodifiableView() {
+ return new UnmodifiableLazyStringList(this);
+ }
+
+}
diff --git a/java/src/main/java/com/google/protobuf/LazyStringList.java b/java/src/main/java/com/google/protobuf/LazyStringList.java
new file mode 100644
index 0000000..235126b
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/LazyStringList.java
@@ -0,0 +1,163 @@
+// 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.Collection;
+import java.util.List;
+
+/**
+ * An interface extending {@code List<String>} that also provides access to the
+ * items of the list as UTF8-encoded ByteString or byte[] objects. This is
+ * used by the protocol buffer implementation to support lazily converting bytes
+ * parsed over the wire to String objects until needed and also increases the
+ * efficiency of serialization if the String was never requested as the
+ * ByteString or byte[] is already cached. The ByteString methods are used in
+ * immutable API only and byte[] methods used in mutable API only for they use
+ * different representations for string/bytes fields.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public interface LazyStringList extends ProtocolStringList {
+
+ /**
+ * Returns the element at the specified position in this list as a ByteString.
+ *
+ * @param index index of the element to return
+ * @return the element at the specified position in this list
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * ({@code index < 0 || index >= size()})
+ */
+ ByteString getByteString(int index);
+
+ /**
+ * Returns the element at the specified position in this list as byte[].
+ *
+ * @param index index of the element to return
+ * @return the element at the specified position in this list
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * ({@code index < 0 || index >= size()})
+ */
+ byte[] getByteArray(int index);
+
+ /**
+ * Appends the specified element to the end of this list (optional
+ * operation).
+ *
+ * @param element element to be appended to this list
+ * @throws UnsupportedOperationException if the <tt>add</tt> operation
+ * is not supported by this list
+ */
+ void add(ByteString element);
+
+ /**
+ * Appends the specified element to the end of this list (optional
+ * operation).
+ *
+ * @param element element to be appended to this list
+ * @throws UnsupportedOperationException if the <tt>add</tt> operation
+ * is not supported by this list
+ */
+ void add(byte[] element);
+
+ /**
+ * Replaces the element at the specified position in this list with the
+ * specified element (optional operation).
+ *
+ * @param index index of the element to replace
+ * @param element the element to be stored at the specified position
+ * @throws UnsupportedOperationException if the <tt>set</tt> operation
+ * is not supported by this list
+ * IndexOutOfBoundsException if the index is out of range
+ * ({@code index < 0 || index >= size()})
+ */
+ void set(int index, ByteString element);
+
+ /**
+ * Replaces the element at the specified position in this list with the
+ * specified element (optional operation).
+ *
+ * @param index index of the element to replace
+ * @param element the element to be stored at the specified position
+ * @throws UnsupportedOperationException if the <tt>set</tt> operation
+ * is not supported by this list
+ * IndexOutOfBoundsException if the index is out of range
+ * ({@code index < 0 || index >= size()})
+ */
+ void set(int index, byte[] element);
+
+ /**
+ * Appends all elements in the specified ByteString collection to the end of
+ * this list.
+ *
+ * @param c collection whose elements are to be added to this list
+ * @return true if this list changed as a result of the call
+ * @throws UnsupportedOperationException if the <tt>addAllByteString</tt>
+ * operation is not supported by this list
+ */
+ boolean addAllByteString(Collection<? extends ByteString> c);
+
+ /**
+ * Appends all elements in the specified byte[] collection to the end of
+ * this list.
+ *
+ * @param c collection whose elements are to be added to this list
+ * @return true if this list changed as a result of the call
+ * @throws UnsupportedOperationException if the <tt>addAllByteArray</tt>
+ * operation is not supported by this list
+ */
+ boolean addAllByteArray(Collection<byte[]> c);
+
+ /**
+ * Returns an unmodifiable List of the underlying elements, each of which is
+ * either a {@code String} or its equivalent UTF-8 encoded {@code ByteString}
+ * or byte[]. It is an error for the caller to modify the returned
+ * List, and attempting to do so will result in an
+ * {@link UnsupportedOperationException}.
+ */
+ List<?> getUnderlyingElements();
+
+ /**
+ * Merges all elements from another LazyStringList into this one. This method
+ * differs from {@link #addAll(Collection)} on that underlying byte arrays are
+ * copied instead of reference shared. Immutable API doesn't need to use this
+ * method as byte[] is not used there at all.
+ */
+ void mergeFrom(LazyStringList other);
+
+ /**
+ * Returns a mutable view of this list. Changes to the view will be made into
+ * the original list. This method is used in mutable API only.
+ */
+ List<byte[]> asByteArrayList();
+
+ /** Returns an unmodifiable view of the list. */
+ LazyStringList getUnmodifiableView();
+}
diff --git a/java/src/main/java/com/google/protobuf/LiteralByteString.java b/java/src/main/java/com/google/protobuf/LiteralByteString.java
new file mode 100644
index 0000000..83e71e9
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/LiteralByteString.java
@@ -0,0 +1,362 @@
+// 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.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+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 {
+
+ 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
+ public String toString(String charsetName)
+ throws UnsupportedEncodingException {
+ return new String(bytes, getOffsetIntoBytes(), size(), charsetName);
+ }
+
+ // =================================================================
+ // 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) {
+ 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/Message.java b/java/src/main/java/com/google/protobuf/Message.java
index 8c29e21..5673d3b 100644
--- a/java/src/main/java/com/google/protobuf/Message.java
+++ b/java/src/main/java/com/google/protobuf/Message.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -48,89 +48,33 @@ import java.util.Map;
*
* @author kenton@google.com Kenton Varda
*/
-public interface Message extends MessageLite {
- /**
- * Get the message's type's descriptor. This differs from the
- * {@code getDescriptor()} method of generated message classes in that
- * this method is an abstract method of the {@code Message} interface
- * whereas {@code getDescriptor()} is a static method of a specific class.
- * They return the same thing.
- */
- Descriptors.Descriptor getDescriptorForType();
+public interface Message extends MessageLite, MessageOrBuilder {
// (From MessageLite, re-declared here only for return type covariance.)
- Message getDefaultInstanceForType();
-
- /**
- * 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 getRepeatedFieldSize() is greater than zero. The
- * values are exactly what would be returned by calling
- * {@link #getField(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<Descriptors.FieldDescriptor, Object> getAllFields();
-
- /**
- * Returns true if the given field is set. This is exactly equivalent to
- * calling the generated "has" accessor method corresponding to the field.
- * @throws IllegalArgumentException The field is a repeated field, or
- * {@code field.getContainingType() != getDescriptorForType()}.
- */
- boolean hasField(Descriptors.FieldDescriptor field);
-
- /**
- * 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 returend. For
- * embedded message fields, the sub-message is returned. For repeated
- * fields, a java.util.List is returned.
- */
- Object getField(Descriptors.FieldDescriptor field);
-
- /**
- * Gets the number of elements of a repeated field. This is exactly
- * equivalent to calling the generated "Count" accessor method corresponding
- * to the field.
- * @throws IllegalArgumentException The field is not a repeated field, or
- * {@code field.getContainingType() != getDescriptorForType()}.
- */
- int getRepeatedFieldCount(Descriptors.FieldDescriptor field);
-
- /**
- * Gets an element of a repeated field. For primitive fields, the boxed
- * primitive value is returned. For enum fields, the EnumValueDescriptor
- * for the value is returend. For embedded message fields, the sub-message
- * is returned.
- * @throws IllegalArgumentException The field is not a repeated field, or
- * {@code field.getContainingType() != getDescriptorForType()}.
- */
- Object getRepeatedField(Descriptors.FieldDescriptor field, int index);
+ Parser<? extends Message> getParserForType();
- /** Get the {@link UnknownFieldSet} for this message. */
- UnknownFieldSet getUnknownFields();
// -----------------------------------------------------------------
// Comparison and hashing
/**
* Compares the specified object with this message for equality. Returns
- * <tt>true</tt> if the given object is a message of the same type (as
+ * {@code true} if the given object is a message of the same type (as
* defined by {@code getDescriptorForType()}) and has identical values for
- * all of its fields.
+ * all of its fields. Subclasses must implement this; inheriting
+ * {@code Object.equals()} is incorrect.
*
* @param other object to be compared for equality with this message
- * @return <tt>true</tt> if the specified object is equal to this message
+ * @return {@code true} if the specified object is equal to this message
*/
@Override
boolean equals(Object other);
/**
* Returns the hash code value for this message. The hash code of a message
- * is defined to be <tt>getDescriptor().hashCode() ^ map.hashCode()</tt>,
- * where <tt>map</tt> is a map of field numbers to field values.
+ * should mix the message's type (object identity of the descriptor) with its
+ * contents (known and unknown field values). Subclasses must implement this;
+ * inheriting {@code Object.hashCode()} is incorrect.
*
* @return the hash code value for this message
* @see Map#hashCode()
@@ -143,7 +87,8 @@ public interface Message extends MessageLite {
/**
* Converts the message to a string in protocol buffer text format. This is
- * just a trivial wrapper around {@link TextFormat#printToString(Message)}.
+ * just a trivial wrapper around {@link
+ * TextFormat#printToString(MessageOrBuilder)}.
*/
@Override
String toString();
@@ -158,7 +103,7 @@ public interface Message extends MessageLite {
/**
* Abstract interface implemented by Protocol Message builders.
*/
- interface Builder extends MessageLite.Builder {
+ interface Builder extends MessageLite.Builder, MessageOrBuilder {
// (From MessageLite.Builder, re-declared here only for return type
// covariance.)
Builder clear();
@@ -197,17 +142,6 @@ public interface Message extends MessageLite {
*/
Descriptors.Descriptor getDescriptorForType();
- // (From MessageLite.Builder, re-declared here only for return type
- // covariance.)
- Message getDefaultInstanceForType();
-
- /**
- * Like {@link Message#getAllFields()}. The returned map may or may not
- * reflect future changes to the builder. Either way, the returned map is
- * itself unmodifiable.
- */
- Map<Descriptors.FieldDescriptor, Object> getAllFields();
-
/**
* Create a Builder for messages of the appropriate type for the given
* field. Messages built with this can then be passed to setField(),
@@ -215,11 +149,23 @@ public interface Message extends MessageLite {
*/
Builder newBuilderForField(Descriptors.FieldDescriptor field);
- /** Like {@link Message#hasField(Descriptors.FieldDescriptor)} */
- boolean hasField(Descriptors.FieldDescriptor field);
-
- /** Like {@link Message#getField(Descriptors.FieldDescriptor)} */
- Object getField(Descriptors.FieldDescriptor field);
+ /**
+ * Get a nested builder instance for the given field.
+ * <p>
+ * Normally, we hold a reference to the immutable message object for the
+ * message type field. Some implementations(the generated message builders),
+ * however, can also hold a reference to the builder object (a nested
+ * builder) for the field.
+ * <p>
+ * If the field is already backed up by a nested builder, the nested builder
+ * will be returned. Otherwise, a new field builder will be created and
+ * returned. The original message field (if exist) will be merged into the
+ * field builder, which will then be nested into its parent builder.
+ * <p>
+ * NOTE: implementations that do not support nested builders will throw
+ * <code>UnsupportedException</code>.
+ */
+ Builder getFieldBuilder(Descriptors.FieldDescriptor field);
/**
* Sets a field to the given value. The value must be of the correct type
@@ -235,14 +181,10 @@ public interface Message extends MessageLite {
Builder clearField(Descriptors.FieldDescriptor field);
/**
- * Like {@link Message#getRepeatedFieldCount(Descriptors.FieldDescriptor)}
+ * Clears the oneof. This is exactly equivalent to calling the generated
+ * "clear" accessor method corresponding to the oneof.
*/
- int getRepeatedFieldCount(Descriptors.FieldDescriptor field);
-
- /**
- * Like {@link Message#getRepeatedField(Descriptors.FieldDescriptor,int)}
- */
- Object getRepeatedField(Descriptors.FieldDescriptor field, int index);
+ Builder clearOneof(Descriptors.OneofDescriptor oneof);
/**
* Sets an element of a repeated field to the given value. The value must
@@ -262,9 +204,6 @@ public interface Message extends MessageLite {
*/
Builder addRepeatedField(Descriptors.FieldDescriptor field, Object value);
- /** Get the {@link UnknownFieldSet} for this message. */
- UnknownFieldSet getUnknownFields();
-
/** Set the {@link UnknownFieldSet} for this message. */
Builder setUnknownFields(UnknownFieldSet unknownFields);
diff --git a/java/src/main/java/com/google/protobuf/MessageLite.java b/java/src/main/java/com/google/protobuf/MessageLite.java
index cf7f39e..798b794 100644
--- a/java/src/main/java/com/google/protobuf/MessageLite.java
+++ b/java/src/main/java/com/google/protobuf/MessageLite.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -64,22 +64,8 @@ import java.io.OutputStream;
*
* @author kenton@google.com Kenton Varda
*/
-public interface MessageLite {
- /**
- * Get an instance of the type with all fields set to their default values.
- * This may or may not be a singleton. This differs from the
- * {@code getDefaultInstance()} method of generated message classes in that
- * this method is an abstract method of the {@code MessageLite} interface
- * whereas {@code getDefaultInstance()} is a static method of a specific
- * class. They return the same thing.
- */
- MessageLite getDefaultInstanceForType();
+public interface MessageLite extends MessageLiteOrBuilder {
- /**
- * Returns true if all required fields in the message and all embedded
- * messages are set, false otherwise.
- */
- boolean isInitialized();
/**
* Serializes the message and writes it to {@code output}. This does not
@@ -93,6 +79,12 @@ public interface MessageLite {
*/
int getSerializedSize();
+
+ /**
+ * Gets the parser for a message of the same type as this message.
+ */
+ Parser<? extends MessageLite> getParserForType();
+
// -----------------------------------------------------------------
// Convenience methods.
@@ -136,6 +128,7 @@ public interface MessageLite {
*/
void writeDelimitedTo(OutputStream output) throws IOException;
+
// =================================================================
// Builders
@@ -153,16 +146,13 @@ public interface MessageLite {
/**
* Abstract interface implemented by Protocol Message builders.
*/
- interface Builder extends Cloneable {
+ interface Builder extends MessageLiteOrBuilder, Cloneable {
/** Resets all fields to their default values. */
Builder clear();
/**
- * Construct the final message. Once this is called, the Builder is no
- * longer valid, and calling any other method will result in undefined
- * behavior and may throw a NullPointerException. If you need to continue
- * working with the builder after calling {@code build()}, {@code clone()}
- * it first.
+ * Constructs the message based on the state of the Builder. Subsequent
+ * changes to the Builder will not affect the returned message.
* @throws UninitializedMessageException The message is missing one or more
* required fields (i.e. {@link #isInitialized()} returns false).
* Use {@link #buildPartial()} to bypass this check.
@@ -172,11 +162,7 @@ public interface MessageLite {
/**
* Like {@link #build()}, but does not throw an exception if the message
* is missing required fields. Instead, a partial message is returned.
- * Once this is called, the Builder is no longer valid, and calling any
- * will result in undefined behavior and may throw a NullPointerException.
- *
- * If you need to continue working with the builder after calling
- * {@code buildPartial()}, {@code clone()} it first.
+ * Subsequent changes to the Builder will not affect the returned message.
*/
MessageLite buildPartial();
@@ -187,14 +173,8 @@ public interface MessageLite {
Builder clone();
/**
- * Returns true if all required fields in the message and all embedded
- * messages are set, false otherwise.
- */
- boolean isInitialized();
-
- /**
* Parses a message of this type from the input and merges it with this
- * message, as if using {@link Builder#mergeFrom(MessageLite)}.
+ * message.
*
* <p>Warning: This does not verify that all required fields are present in
* the input message. If you call {@link #build()} without setting all
@@ -204,11 +184,6 @@ public interface MessageLite {
* <ul>
* <li>Call {@link #isInitialized()} to verify that all required fields
* are set before building.
- * <li>Parse the message separately using one of the static
- * {@code parseFrom} methods, then use {@link #mergeFrom(MessageLite)}
- * to merge it with this one. {@code parseFrom} will throw an
- * {@link InvalidProtocolBufferException} (an {@code IOException})
- * if some required fields are missing.
* <li>Use {@code buildPartial()} to build, which ignores missing
* required fields.
* </ul>
@@ -230,12 +205,6 @@ public interface MessageLite {
ExtensionRegistryLite extensionRegistry)
throws IOException;
- /**
- * Get the message's type's default instance.
- * See {@link MessageLite#getDefaultInstanceForType()}.
- */
- MessageLite getDefaultInstanceForType();
-
// ---------------------------------------------------------------
// Convenience methods.
@@ -243,13 +212,17 @@ public interface MessageLite {
* Parse {@code data} as a message of this type and merge it with the
* message being built. This is just a small wrapper around
* {@link #mergeFrom(CodedInputStream)}.
+ *
+ * @return this
*/
Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException;
/**
* Parse {@code data} as a message of this type and merge it with the
* message being built. This is just a small wrapper around
- * {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}.
+ * {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}.
+ *
+ * @return this
*/
Builder mergeFrom(ByteString data,
ExtensionRegistryLite extensionRegistry)
@@ -259,6 +232,8 @@ public interface MessageLite {
* Parse {@code data} as a message of this type and merge it with the
* message being built. This is just a small wrapper around
* {@link #mergeFrom(CodedInputStream)}.
+ *
+ * @return this
*/
Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException;
@@ -266,6 +241,8 @@ public interface MessageLite {
* Parse {@code data} as a message of this type and merge it with the
* message being built. This is just a small wrapper around
* {@link #mergeFrom(CodedInputStream)}.
+ *
+ * @return this
*/
Builder mergeFrom(byte[] data, int off, int len)
throws InvalidProtocolBufferException;
@@ -273,7 +250,9 @@ public interface MessageLite {
/**
* Parse {@code data} as a message of this type and merge it with the
* message being built. This is just a small wrapper around
- * {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}.
+ * {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}.
+ *
+ * @return this
*/
Builder mergeFrom(byte[] data,
ExtensionRegistryLite extensionRegistry)
@@ -282,7 +261,9 @@ public interface MessageLite {
/**
* Parse {@code data} as a message of this type and merge it with the
* message being built. This is just a small wrapper around
- * {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}.
+ * {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}.
+ *
+ * @return this
*/
Builder mergeFrom(byte[] data, int off, int len,
ExtensionRegistryLite extensionRegistry)
@@ -299,13 +280,17 @@ public interface MessageLite {
* and {@link #mergeDelimitedFrom(InputStream)} to read it.
* <p>
* Despite usually reading the entire input, this does not close the stream.
+ *
+ * @return this
*/
Builder mergeFrom(InputStream input) throws IOException;
/**
* Parse a message of this type from {@code input} and merge it with the
* message being built. This is just a small wrapper around
- * {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}.
+ * {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}.
+ *
+ * @return this
*/
Builder mergeFrom(InputStream input,
ExtensionRegistryLite extensionRegistry)
@@ -318,9 +303,9 @@ public interface MessageLite {
* {@link MessageLite#writeDelimitedTo(OutputStream)} to write messages in
* this format.
*
- * @returns True if successful, or false if the stream is at EOF when the
- * method starts. Any other error (including reaching EOF during
- * parsing) will cause an exception to be thrown.
+ * @return True if successful, or false if the stream is at EOF when the
+ * method starts. Any other error (including reaching EOF during
+ * parsing) will cause an exception to be thrown.
*/
boolean mergeDelimitedFrom(InputStream input)
throws IOException;
diff --git a/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java b/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java
new file mode 100644
index 0000000..818386c
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java
@@ -0,0 +1,60 @@
+// 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;
+
+/**
+ * Base interface for methods common to {@link MessageLite}
+ * and {@link MessageLite.Builder} to provide type equivalency.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public interface MessageLiteOrBuilder {
+ /**
+ * Get an instance of the type with no fields set. Because no fields are set,
+ * all getters for singular fields will return default values and repeated
+ * fields will appear empty.
+ * This may or may not be a singleton. This differs from the
+ * {@code getDefaultInstance()} method of generated message classes in that
+ * this method is an abstract method of the {@code MessageLite} interface
+ * whereas {@code getDefaultInstance()} is a static method of a specific
+ * class. They return the same thing.
+ */
+ MessageLite getDefaultInstanceForType();
+
+ /**
+ * Returns true if all required fields in the message and all embedded
+ * messages are set, false otherwise.
+ *
+ * <p>See also: {@link MessageOrBuilder#getInitializationErrorString()}
+ */
+ boolean isInitialized();
+
+}
diff --git a/java/src/main/java/com/google/protobuf/MessageOrBuilder.java b/java/src/main/java/com/google/protobuf/MessageOrBuilder.java
new file mode 100644
index 0000000..f0fc485
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/MessageOrBuilder.java
@@ -0,0 +1,143 @@
+// 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.List;
+import java.util.Map;
+
+/**
+ * Base interface for methods common to {@link Message} and
+ * {@link Message.Builder} to provide type equivalency.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+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)
+ Message getDefaultInstanceForType();
+
+ /**
+ * Returns a list of field paths (e.g. "foo.bar.baz") of required fields
+ * which are not set in this message. You should call
+ * {@link MessageLiteOrBuilder#isInitialized()} first to check if there
+ * are any missing fields, as that method is likely to be much faster
+ * than this one even when the message is fully-initialized.
+ */
+ List<String> findInitializationErrors();
+
+ /**
+ * Returns a comma-delimited list of required fields which are not set
+ * in this message object. You should call
+ * {@link MessageLiteOrBuilder#isInitialized()} first to check if there
+ * are any missing fields, as that method is likely to be much faster
+ * than this one even when the message is fully-initialized.
+ */
+ String getInitializationErrorString();
+
+ /**
+ * Get the message's type's descriptor. This differs from the
+ * {@code getDescriptor()} method of generated message classes in that
+ * this method is an abstract method of the {@code Message} interface
+ * whereas {@code getDescriptor()} is a static method of a specific class.
+ * They return the same thing.
+ */
+ Descriptors.Descriptor getDescriptorForType();
+
+ /**
+ * 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 #getField(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.
+ * <br>
+ * If this is for a builder, the returned map may or may not reflect future
+ * changes to the builder. Either way, the returned map is itself
+ * unmodifiable.
+ */
+ Map<Descriptors.FieldDescriptor, Object> getAllFields();
+
+ /**
+ * Returns true if the given oneof is set.
+ * @throws IllegalArgumentException if
+ * {@code oneof.getContainingType() != getDescriptorForType()}.
+ */
+ boolean hasOneof(Descriptors.OneofDescriptor oneof);
+
+ /**
+ * Obtains the FieldDescriptor if the given oneof is set. Returns null
+ * if no field is set.
+ */
+ Descriptors.FieldDescriptor getOneofFieldDescriptor(
+ Descriptors.OneofDescriptor oneof);
+
+ /**
+ * Returns true if the given field is set. This is exactly equivalent to
+ * calling the generated "has" accessor method corresponding to the field.
+ * @throws IllegalArgumentException The field is a repeated field, or
+ * {@code field.getContainingType() != getDescriptorForType()}.
+ */
+ boolean hasField(Descriptors.FieldDescriptor field);
+
+ /**
+ * 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.
+ */
+ Object getField(Descriptors.FieldDescriptor field);
+
+ /**
+ * Gets the number of elements of a repeated field. This is exactly
+ * equivalent to calling the generated "Count" accessor method corresponding
+ * to the field.
+ * @throws IllegalArgumentException The field is not a repeated field, or
+ * {@code field.getContainingType() != getDescriptorForType()}.
+ */
+ int getRepeatedFieldCount(Descriptors.FieldDescriptor field);
+
+ /**
+ * Gets an element of a repeated field. 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.
+ * @throws IllegalArgumentException The field is not a repeated field, or
+ * {@code field.getContainingType() != getDescriptorForType()}.
+ */
+ Object getRepeatedField(Descriptors.FieldDescriptor field, int index);
+
+ /** Get the {@link UnknownFieldSet} for this message. */
+ UnknownFieldSet getUnknownFields();
+}
diff --git a/java/src/main/java/com/google/protobuf/MessageReflection.java b/java/src/main/java/com/google/protobuf/MessageReflection.java
new file mode 100644
index 0000000..edb5b5c
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/MessageReflection.java
@@ -0,0 +1,931 @@
+// 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.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Reflection utility methods shared by both mutable and immutable messages.
+ *
+ * @author liujisi@google.com (Pherl Liu)
+ */
+class MessageReflection {
+
+ static void writeMessageTo(Message message, CodedOutputStream output,
+ boolean alwaysWriteRequiredFields)
+ throws IOException {
+ final boolean isMessageSet =
+ message.getDescriptorForType().getOptions().getMessageSetWireFormat();
+
+ Map<FieldDescriptor, Object> fields = message.getAllFields();
+ if (alwaysWriteRequiredFields) {
+ fields = new TreeMap<FieldDescriptor, Object>(fields);
+ for (final FieldDescriptor field :
+ message.getDescriptorForType().getFields()) {
+ if (field.isRequired() && !fields.containsKey(field)) {
+ fields.put(field, message.getField(field));
+ }
+ }
+ }
+ for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
+ fields.entrySet()) {
+ final Descriptors.FieldDescriptor field = entry.getKey();
+ final Object value = entry.getValue();
+ if (isMessageSet && field.isExtension() &&
+ field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE &&
+ !field.isRepeated()) {
+ output.writeMessageSetExtension(field.getNumber(), (Message) value);
+ } else {
+ FieldSet.writeField(field, value, output);
+ }
+ }
+
+ final UnknownFieldSet unknownFields = message.getUnknownFields();
+ if (isMessageSet) {
+ unknownFields.writeAsMessageSetTo(output);
+ } else {
+ unknownFields.writeTo(output);
+ }
+ }
+
+ static int getSerializedSize(Message message) {
+ int size = 0;
+ final boolean isMessageSet =
+ message.getDescriptorForType().getOptions().getMessageSetWireFormat();
+
+ for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
+ message.getAllFields().entrySet()) {
+ final Descriptors.FieldDescriptor field = entry.getKey();
+ final Object value = entry.getValue();
+ if (isMessageSet && field.isExtension() &&
+ field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE &&
+ !field.isRepeated()) {
+ size += CodedOutputStream.computeMessageSetExtensionSize(
+ field.getNumber(), (Message) value);
+ } else {
+ size += FieldSet.computeFieldSize(field, value);
+ }
+ }
+
+ final UnknownFieldSet unknownFields = message.getUnknownFields();
+ if (isMessageSet) {
+ size += unknownFields.getSerializedSizeAsMessageSet();
+ } else {
+ size += unknownFields.getSerializedSize();
+ }
+ return size;
+ }
+
+ static String delimitWithCommas(List<String> parts) {
+ StringBuilder result = new StringBuilder();
+ for (String part : parts) {
+ if (result.length() > 0) {
+ result.append(", ");
+ }
+ result.append(part);
+ }
+ return result.toString();
+ }
+
+ @SuppressWarnings("unchecked")
+ static boolean isInitialized(MessageOrBuilder message) {
+ // Check that all required fields are present.
+ for (final Descriptors.FieldDescriptor field : message
+ .getDescriptorForType()
+ .getFields()) {
+ if (field.isRequired()) {
+ if (!message.hasField(field)) {
+ return false;
+ }
+ }
+ }
+
+ // Check that embedded messages are initialized.
+ for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
+ message.getAllFields().entrySet()) {
+ final Descriptors.FieldDescriptor field = entry.getKey();
+ if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
+ if (field.isRepeated()) {
+ for (final Message element
+ : (List<Message>) entry.getValue()) {
+ if (!element.isInitialized()) {
+ return false;
+ }
+ }
+ } else {
+ if (!((Message) entry.getValue()).isInitialized()) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private static String subMessagePrefix(final String prefix,
+ final Descriptors.FieldDescriptor field,
+ final int index) {
+ final StringBuilder result = new StringBuilder(prefix);
+ if (field.isExtension()) {
+ result.append('(')
+ .append(field.getFullName())
+ .append(')');
+ } else {
+ result.append(field.getName());
+ }
+ if (index != -1) {
+ result.append('[')
+ .append(index)
+ .append(']');
+ }
+ result.append('.');
+ return result.toString();
+ }
+
+ private static void findMissingFields(final MessageOrBuilder message,
+ final String prefix,
+ final List<String> results) {
+ for (final Descriptors.FieldDescriptor field :
+ message.getDescriptorForType().getFields()) {
+ if (field.isRequired() && !message.hasField(field)) {
+ results.add(prefix + field.getName());
+ }
+ }
+
+ for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
+ message.getAllFields().entrySet()) {
+ final Descriptors.FieldDescriptor field = entry.getKey();
+ final Object value = entry.getValue();
+
+ if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
+ if (field.isRepeated()) {
+ int i = 0;
+ for (final Object element : (List) value) {
+ findMissingFields((MessageOrBuilder) element,
+ subMessagePrefix(prefix, field, i++),
+ results);
+ }
+ } else {
+ if (message.hasField(field)) {
+ findMissingFields((MessageOrBuilder) value,
+ subMessagePrefix(prefix, field, -1),
+ results);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Populates {@code this.missingFields} with the full "path" of each missing
+ * required field in the given message.
+ */
+ static List<String> findMissingFields(
+ final MessageOrBuilder message) {
+ final List<String> results = new ArrayList<String>();
+ findMissingFields(message, "", results);
+ return results;
+ }
+
+ static interface MergeTarget {
+ enum ContainerType {
+ MESSAGE, EXTENSION_SET
+ }
+
+ /**
+ * Returns the descriptor for the target.
+ */
+ public Descriptors.Descriptor getDescriptorForType();
+
+ public ContainerType getContainerType();
+
+ public ExtensionRegistry.ExtensionInfo findExtensionByName(
+ ExtensionRegistry registry, String name);
+
+ public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
+ ExtensionRegistry registry, Descriptors.Descriptor containingType,
+ int fieldNumber);
+
+ /**
+ * 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.
+ */
+ public Object getField(Descriptors.FieldDescriptor field);
+
+ /**
+ * Returns true if the given field is set. This is exactly equivalent to
+ * calling the generated "has" accessor method corresponding to the field.
+ *
+ * @throws IllegalArgumentException The field is a repeated field, or {@code
+ * field.getContainingType() != getDescriptorForType()}.
+ */
+ boolean hasField(Descriptors.FieldDescriptor field);
+
+ /**
+ * Sets a field to the given value. The value must be of the correct type
+ * for this field, i.e. the same type that
+ * {@link Message#getField(Descriptors.FieldDescriptor)}
+ * would return.
+ */
+ MergeTarget setField(Descriptors.FieldDescriptor field, Object value);
+
+ /**
+ * Clears the field. This is exactly equivalent to calling the generated
+ * "clear" accessor method corresponding to the field.
+ */
+ MergeTarget clearField(Descriptors.FieldDescriptor field);
+
+ /**
+ * Sets an element of a repeated field to the given value. The value must
+ * be of the correct type for this field, i.e. the same type that {@link
+ * Message#getRepeatedField(Descriptors.FieldDescriptor, int)} would return.
+ *
+ * @throws IllegalArgumentException The field is not a repeated field, or
+ * {@code field.getContainingType() !=
+ * getDescriptorForType()}.
+ */
+ MergeTarget setRepeatedField(Descriptors.FieldDescriptor field,
+ int index, Object value);
+
+ /**
+ * Like {@code setRepeatedField}, but appends the value as a new element.
+ *
+ * @throws IllegalArgumentException The field is not a repeated field, or
+ * {@code field.getContainingType() !=
+ * getDescriptorForType()}.
+ */
+ MergeTarget addRepeatedField(Descriptors.FieldDescriptor field,
+ Object value);
+
+ /**
+ * Returns true if the given oneof is set.
+ *
+ * @throws IllegalArgumentException if
+ * {@code oneof.getContainingType() != getDescriptorForType()}.
+ */
+ boolean hasOneof(Descriptors.OneofDescriptor oneof);
+
+ /**
+ * Clears the oneof. This is exactly equivalent to calling the generated
+ * "clear" accessor method corresponding to the oneof.
+ */
+ MergeTarget clearOneof(Descriptors.OneofDescriptor oneof);
+
+ /**
+ * Obtains the FieldDescriptor if the given oneof is set. Returns null
+ * if no field is set.
+ */
+ Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof);
+
+ /**
+ * Parse the input stream into a sub field group defined based on either
+ * FieldDescriptor or the default instance.
+ */
+ Object parseGroup(CodedInputStream input, ExtensionRegistryLite registry,
+ Descriptors.FieldDescriptor descriptor, Message defaultInstance)
+ throws IOException;
+
+ /**
+ * Parse the input stream into a sub field message defined based on either
+ * FieldDescriptor or the default instance.
+ */
+ Object parseMessage(CodedInputStream input, ExtensionRegistryLite registry,
+ Descriptors.FieldDescriptor descriptor, Message defaultInstance)
+ throws IOException;
+
+ /**
+ * Parse from a ByteString into a sub field message defined based on either
+ * FieldDescriptor or the default instance. There isn't a varint indicating
+ * the length of the message at the beginning of the input ByteString.
+ */
+ Object parseMessageFromBytes(
+ ByteString bytes, ExtensionRegistryLite registry,
+ Descriptors.FieldDescriptor descriptor, Message defaultInstance)
+ throws IOException;
+
+ /**
+ * Read a primitive field from input. Note that builders and mutable
+ * messages may use different Java types to represent a primtive field.
+ */
+ Object readPrimitiveField(
+ CodedInputStream input, WireFormat.FieldType type,
+ boolean checkUtf8) throws IOException;
+
+ /**
+ * Returns a new merge target for a sub-field. When defaultInstance is
+ * provided, it indicates the descriptor is for an extension type, and
+ * implementations should create a new instance from the defaultInstance
+ * prototype directly.
+ */
+ MergeTarget newMergeTargetForField(
+ Descriptors.FieldDescriptor descriptor,
+ Message defaultInstance);
+
+ /**
+ * Finishes the merge and returns the underlying object.
+ */
+ Object finish();
+ }
+
+ static class BuilderAdapter implements MergeTarget {
+
+ private final Message.Builder builder;
+
+ public Descriptors.Descriptor getDescriptorForType() {
+ return builder.getDescriptorForType();
+ }
+
+ public BuilderAdapter(Message.Builder builder) {
+ this.builder = builder;
+ }
+
+ public Object getField(Descriptors.FieldDescriptor field) {
+ return builder.getField(field);
+ }
+
+ @Override
+ public boolean hasField(Descriptors.FieldDescriptor field) {
+ return builder.hasField(field);
+ }
+
+ public MergeTarget setField(Descriptors.FieldDescriptor field,
+ Object value) {
+ builder.setField(field, value);
+ return this;
+ }
+
+ public MergeTarget clearField(Descriptors.FieldDescriptor field) {
+ builder.clearField(field);
+ return this;
+ }
+
+ 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) {
+ builder.addRepeatedField(field, value);
+ return this;
+ }
+
+ @Override
+ public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
+ return builder.hasOneof(oneof);
+ }
+
+ @Override
+ public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
+ builder.clearOneof(oneof);
+ return this;
+ }
+
+ @Override
+ public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
+ return builder.getOneofFieldDescriptor(oneof);
+ }
+
+ public ContainerType getContainerType() {
+ return ContainerType.MESSAGE;
+ }
+
+ public ExtensionRegistry.ExtensionInfo findExtensionByName(
+ ExtensionRegistry registry, String name) {
+ return registry.findImmutableExtensionByName(name);
+ }
+
+ public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
+ ExtensionRegistry registry, Descriptors.Descriptor containingType,
+ int fieldNumber) {
+ return registry.findImmutableExtensionByNumber(containingType,
+ fieldNumber);
+ }
+
+ public Object parseGroup(CodedInputStream input,
+ ExtensionRegistryLite extensionRegistry,
+ Descriptors.FieldDescriptor field, Message defaultInstance)
+ throws IOException {
+ Message.Builder subBuilder;
+ // When default instance is not null. The field is an extension field.
+ if (defaultInstance != null) {
+ subBuilder = defaultInstance.newBuilderForType();
+ } else {
+ subBuilder = builder.newBuilderForField(field);
+ }
+ if (!field.isRepeated()) {
+ Message originalMessage = (Message) getField(field);
+ if (originalMessage != null) {
+ subBuilder.mergeFrom(originalMessage);
+ }
+ }
+ input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
+ return subBuilder.buildPartial();
+ }
+
+ public Object parseMessage(CodedInputStream input,
+ ExtensionRegistryLite extensionRegistry,
+ Descriptors.FieldDescriptor field, Message defaultInstance)
+ throws IOException {
+ Message.Builder subBuilder;
+ // When default instance is not null. The field is an extension field.
+ if (defaultInstance != null) {
+ subBuilder = defaultInstance.newBuilderForType();
+ } else {
+ subBuilder = builder.newBuilderForField(field);
+ }
+ if (!field.isRepeated()) {
+ Message originalMessage = (Message) getField(field);
+ if (originalMessage != null) {
+ subBuilder.mergeFrom(originalMessage);
+ }
+ }
+ input.readMessage(subBuilder, extensionRegistry);
+ return subBuilder.buildPartial();
+ }
+
+ public Object parseMessageFromBytes(ByteString bytes,
+ ExtensionRegistryLite extensionRegistry,
+ Descriptors.FieldDescriptor field, Message defaultInstance)
+ throws IOException {
+ Message.Builder subBuilder;
+ // When default instance is not null. The field is an extension field.
+ if (defaultInstance != null) {
+ subBuilder = defaultInstance.newBuilderForType();
+ } else {
+ subBuilder = builder.newBuilderForField(field);
+ }
+ if (!field.isRepeated()) {
+ Message originalMessage = (Message) getField(field);
+ if (originalMessage != null) {
+ subBuilder.mergeFrom(originalMessage);
+ }
+ }
+ subBuilder.mergeFrom(bytes, extensionRegistry);
+ return subBuilder.buildPartial();
+ }
+
+ public MergeTarget newMergeTargetForField(Descriptors.FieldDescriptor field,
+ Message defaultInstance) {
+ if (defaultInstance != null) {
+ return new BuilderAdapter(
+ defaultInstance.newBuilderForType());
+ } else {
+ return new BuilderAdapter(builder.newBuilderForField(field));
+ }
+ }
+
+ public Object readPrimitiveField(
+ CodedInputStream input, WireFormat.FieldType type,
+ boolean checkUtf8) throws IOException {
+ return FieldSet.readPrimitiveField(input, type, checkUtf8);
+ }
+
+ public Object finish() {
+ return builder.buildPartial();
+ }
+ }
+
+
+ static class ExtensionAdapter implements MergeTarget {
+
+ private final FieldSet<Descriptors.FieldDescriptor> extensions;
+
+ ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions) {
+ this.extensions = extensions;
+ }
+
+ public Descriptors.Descriptor getDescriptorForType() {
+ throw new UnsupportedOperationException(
+ "getDescriptorForType() called on FieldSet object");
+ }
+
+ public Object getField(Descriptors.FieldDescriptor field) {
+ return extensions.getField(field);
+ }
+
+ public boolean hasField(Descriptors.FieldDescriptor field) {
+ return extensions.hasField(field);
+ }
+
+ public MergeTarget setField(Descriptors.FieldDescriptor field,
+ Object value) {
+ extensions.setField(field, value);
+ return this;
+ }
+
+ public MergeTarget clearField(Descriptors.FieldDescriptor field) {
+ extensions.clearField(field);
+ return this;
+ }
+
+ 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) {
+ extensions.addRepeatedField(field, value);
+ return this;
+ }
+
+ @Override
+ public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
+ return false;
+ }
+
+ @Override
+ public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
+ // Nothing to clear.
+ return this;
+ }
+
+ @Override
+ public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
+ return null;
+ }
+
+ public ContainerType getContainerType() {
+ return ContainerType.EXTENSION_SET;
+ }
+
+ public ExtensionRegistry.ExtensionInfo findExtensionByName(
+ ExtensionRegistry registry, String name) {
+ return registry.findImmutableExtensionByName(name);
+ }
+
+ public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
+ 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 {
+ Message.Builder subBuilder =
+ defaultInstance.newBuilderForType();
+ if (!field.isRepeated()) {
+ Message originalMessage = (Message) getField(field);
+ if (originalMessage != null) {
+ subBuilder.mergeFrom(originalMessage);
+ }
+ }
+ input.readGroup(field.getNumber(), subBuilder, registry);
+ return subBuilder.buildPartial();
+ }
+
+ public Object parseMessage(CodedInputStream input,
+ ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
+ Message defaultInstance) throws IOException {
+ Message.Builder subBuilder =
+ defaultInstance.newBuilderForType();
+ if (!field.isRepeated()) {
+ Message originalMessage = (Message) getField(field);
+ if (originalMessage != null) {
+ subBuilder.mergeFrom(originalMessage);
+ }
+ }
+ input.readMessage(subBuilder, registry);
+ return subBuilder.buildPartial();
+ }
+
+ 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);
+ if (originalMessage != null) {
+ subBuilder.mergeFrom(originalMessage);
+ }
+ }
+ subBuilder.mergeFrom(bytes, registry);
+ return subBuilder.buildPartial();
+ }
+
+ public MergeTarget newMergeTargetForField(
+ Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
+ throw new UnsupportedOperationException(
+ "newMergeTargetForField() called on FieldSet object");
+ }
+
+ public Object readPrimitiveField(
+ CodedInputStream input, WireFormat.FieldType type,
+ boolean checkUtf8) throws IOException {
+ return FieldSet.readPrimitiveField(input, type, checkUtf8);
+ }
+
+ public Object finish() {
+ throw new UnsupportedOperationException(
+ "finish() called on FieldSet object");
+ }
+ }
+
+ /**
+ * Parses a single field into MergeTarget. The target can be Message.Builder,
+ * FieldSet or MutableMessage.
+ *
+ * Package-private because it is used by GeneratedMessage.ExtendableMessage.
+ *
+ * @param tag The tag, which should have already been read.
+ * @return {@code true} unless the tag is an end-group tag.
+ */
+ static boolean mergeFieldFrom(
+ CodedInputStream input,
+ UnknownFieldSet.Builder unknownFields,
+ ExtensionRegistryLite extensionRegistry,
+ Descriptors.Descriptor type,
+ MergeTarget target,
+ int tag) throws IOException {
+ if (type.getOptions().getMessageSetWireFormat() &&
+ tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
+ mergeMessageSetExtensionFromCodedStream(
+ input, unknownFields, extensionRegistry, type, target);
+ return true;
+ }
+
+ final int wireType = WireFormat.getTagWireType(tag);
+ final int fieldNumber = WireFormat.getTagFieldNumber(tag);
+
+ final Descriptors.FieldDescriptor field;
+ Message defaultInstance = null;
+
+ if (type.isExtensionNumber(fieldNumber)) {
+ // extensionRegistry may be either ExtensionRegistry or
+ // ExtensionRegistryLite. Since the type we are parsing is a full
+ // message, only a full ExtensionRegistry could possibly contain
+ // extensions of it. Otherwise we will treat the registry as if it
+ // were empty.
+ if (extensionRegistry instanceof ExtensionRegistry) {
+ final ExtensionRegistry.ExtensionInfo extension =
+ target.findExtensionByNumber((ExtensionRegistry) extensionRegistry,
+ type, fieldNumber);
+ if (extension == null) {
+ field = null;
+ } else {
+ field = extension.descriptor;
+ defaultInstance = extension.defaultInstance;
+ if (defaultInstance == null &&
+ field.getJavaType()
+ == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
+ throw new IllegalStateException(
+ "Message-typed extension lacked default instance: " +
+ field.getFullName());
+ }
+ }
+ } else {
+ field = null;
+ }
+ } else if (target.getContainerType() == MergeTarget.ContainerType.MESSAGE) {
+ field = type.findFieldByNumber(fieldNumber);
+ } else {
+ field = null;
+ }
+
+ boolean unknown = false;
+ boolean packed = false;
+ if (field == null) {
+ unknown = true; // Unknown field.
+ } else if (wireType == FieldSet.getWireFormatForFieldType(
+ field.getLiteType(),
+ false /* isPacked */)) {
+ packed = false;
+ } else if (field.isPackable() &&
+ wireType == FieldSet.getWireFormatForFieldType(
+ field.getLiteType(),
+ true /* isPacked */)) {
+ packed = true;
+ } else {
+ unknown = true; // Unknown wire type.
+ }
+
+ if (unknown) { // Unknown field or wrong wire type. Skip.
+ return unknownFields.mergeFieldFrom(tag, input);
+ }
+
+ if (packed) {
+ final int length = input.readRawVarint32();
+ final int limit = input.pushLimit(length);
+ if (field.getLiteType() == WireFormat.FieldType.ENUM) {
+ while (input.getBytesUntilLimit() > 0) {
+ final int rawValue = input.readEnum();
+ final Object value = field.getEnumType().findValueByNumber(rawValue);
+ if (value == null) {
+ // If the number isn't recognized as a valid value for this
+ // enum, drop it (don't even add it to unknownFields).
+ return true;
+ }
+ target.addRepeatedField(field, value);
+ }
+ } else {
+ while (input.getBytesUntilLimit() > 0) {
+ final Object value =
+ target.readPrimitiveField(input, field.getLiteType(), field.needsUtf8Check());
+ target.addRepeatedField(field, value);
+ }
+ }
+ input.popLimit(limit);
+ } else {
+ final Object value;
+ switch (field.getType()) {
+ case GROUP: {
+ value = target
+ .parseGroup(input, extensionRegistry, field, defaultInstance);
+ break;
+ }
+ case MESSAGE: {
+ value = target
+ .parseMessage(input, extensionRegistry, field, defaultInstance);
+ break;
+ }
+ case ENUM:
+ final int rawValue = input.readEnum();
+ value = field.getEnumType().findValueByNumber(rawValue);
+ // If the number isn't recognized as a valid value for this enum,
+ // drop it.
+ if (value == null) {
+ unknownFields.mergeVarintField(fieldNumber, rawValue);
+ return true;
+ }
+ break;
+ default:
+ value = target.readPrimitiveField(input, field.getLiteType(), field.needsUtf8Check());
+ break;
+ }
+
+ if (field.isRepeated()) {
+ target.addRepeatedField(field, value);
+ } else {
+ target.setField(field, value);
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Called by {@code #mergeFieldFrom()} to parse a MessageSet extension into
+ * MergeTarget.
+ */
+ private static void mergeMessageSetExtensionFromCodedStream(
+ CodedInputStream input,
+ UnknownFieldSet.Builder unknownFields,
+ ExtensionRegistryLite extensionRegistry,
+ Descriptors.Descriptor type,
+ MergeTarget target) throws IOException {
+
+ // The wire format for MessageSet is:
+ // message MessageSet {
+ // repeated group Item = 1 {
+ // required int32 typeId = 2;
+ // required bytes message = 3;
+ // }
+ // }
+ // "typeId" is the extension's field number. The extension can only be
+ // a message type, where "message" contains the encoded bytes of that
+ // message.
+ //
+ // In practice, we will probably never see a MessageSet item in which
+ // the message appears before the type ID, or where either field does not
+ // appear exactly once. However, in theory such cases are valid, so we
+ // should be prepared to accept them.
+
+ int typeId = 0;
+ ByteString rawBytes = null; // If we encounter "message" before "typeId"
+ ExtensionRegistry.ExtensionInfo extension = null;
+
+ // Read bytes from input, if we get it's type first then parse it eagerly,
+ // otherwise we store the raw bytes in a local variable.
+ while (true) {
+ final int tag = input.readTag();
+ if (tag == 0) {
+ break;
+ }
+
+ if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
+ typeId = input.readUInt32();
+ if (typeId != 0) {
+ // extensionRegistry may be either ExtensionRegistry or
+ // ExtensionRegistryLite. Since the type we are parsing is a full
+ // message, only a full ExtensionRegistry could possibly contain
+ // extensions of it. Otherwise we will treat the registry as if it
+ // were empty.
+ if (extensionRegistry instanceof ExtensionRegistry) {
+ extension = target.findExtensionByNumber(
+ (ExtensionRegistry) extensionRegistry, type, typeId);
+ }
+ }
+
+ } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
+ if (typeId != 0) {
+ if (extension != null &&
+ ExtensionRegistryLite.isEagerlyParseMessageSets()) {
+ // We already know the type, so we can parse directly from the
+ // input with no copying. Hooray!
+ eagerlyMergeMessageSetExtension(
+ input, extension, extensionRegistry, target);
+ rawBytes = null;
+ continue;
+ }
+ }
+ // We haven't seen a type ID yet or we want parse message lazily.
+ rawBytes = input.readBytes();
+
+ } else { // Unknown tag. Skip it.
+ if (!input.skipField(tag)) {
+ break; // End of group
+ }
+ }
+ }
+ input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG);
+
+ // Process the raw bytes.
+ if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID.
+ if (extension != null) { // We known the type
+ mergeMessageSetExtensionFromBytes(
+ rawBytes, extension, extensionRegistry, target);
+ } else { // We don't know how to parse this. Ignore it.
+ if (rawBytes != null) {
+ unknownFields.mergeField(typeId, UnknownFieldSet.Field.newBuilder()
+ .addLengthDelimited(rawBytes).build());
+ }
+ }
+ }
+ }
+
+ private static void mergeMessageSetExtensionFromBytes(
+ ByteString rawBytes,
+ ExtensionRegistry.ExtensionInfo extension,
+ ExtensionRegistryLite extensionRegistry,
+ MergeTarget target) throws IOException {
+
+ Descriptors.FieldDescriptor field = extension.descriptor;
+ boolean hasOriginalValue = target.hasField(field);
+
+ if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) {
+ // If the field already exists, we just parse the field.
+ Object value = target.parseMessageFromBytes(
+ rawBytes, extensionRegistry,field, extension.defaultInstance);
+ target.setField(field, value);
+ } else {
+ // Use LazyField to load MessageSet lazily.
+ LazyField lazyField = new LazyField(
+ extension.defaultInstance, extensionRegistry, rawBytes);
+ target.setField(field, lazyField);
+ }
+ }
+
+ private static void eagerlyMergeMessageSetExtension(
+ CodedInputStream input,
+ ExtensionRegistry.ExtensionInfo extension,
+ ExtensionRegistryLite extensionRegistry,
+ MergeTarget target) throws IOException {
+ Descriptors.FieldDescriptor field = extension.descriptor;
+ Object value = target.parseMessage(input, extensionRegistry, field,
+ extension.defaultInstance);
+ target.setField(field, value);
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/Parser.java b/java/src/main/java/com/google/protobuf/Parser.java
new file mode 100644
index 0000000..f636014
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/Parser.java
@@ -0,0 +1,261 @@
+// 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.InputStream;
+
+/**
+ * Abstract interface for parsing Protocol Messages.
+ *
+ * The implementation should be stateless and thread-safe.
+ *
+ * @author liujisi@google.com (Pherl Liu)
+ */
+public interface Parser<MessageType> {
+ /**
+ * Parses a message of {@code MessageType} from the input.
+ *
+ * <p>Note: The caller should call
+ * {@link CodedInputStream#checkLastTagWas(int)} after calling this to
+ * verify that the last tag seen was the appropriate end-group tag,
+ * or zero for EOF.
+ */
+ public MessageType parseFrom(CodedInputStream input)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseFrom(CodedInputStream)}, but also parses extensions.
+ * The extensions that you want to be able to parse must be registered in
+ * {@code extensionRegistry}. Extensions not in the registry will be treated
+ * as unknown fields.
+ */
+ public MessageType parseFrom(CodedInputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseFrom(CodedInputStream)}, but does not throw an
+ * exception if the message is missing required fields. Instead, a partial
+ * message is returned.
+ */
+ public MessageType parsePartialFrom(CodedInputStream input)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseFrom(CodedInputStream input, ExtensionRegistryLite)},
+ * but does not throw an exception if the message is missing required fields.
+ * Instead, a partial message is returned.
+ */
+ public MessageType parsePartialFrom(CodedInputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ // ---------------------------------------------------------------
+ // Convenience methods.
+
+ /**
+ * Parses {@code data} as a message of {@code MessageType}.
+ * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}.
+ */
+ public MessageType parseFrom(ByteString data)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Parses {@code data} as a message of {@code MessageType}.
+ * This is just a small wrapper around
+ * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
+ */
+ public MessageType parseFrom(ByteString data,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseFrom(ByteString)}, but does not throw an
+ * exception if the message is missing required fields. Instead, a partial
+ * message is returned.
+ */
+ public MessageType parsePartialFrom(ByteString data)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseFrom(ByteString, ExtensionRegistryLite)},
+ * but does not throw an exception if the message is missing required fields.
+ * Instead, a partial message is returned.
+ */
+ public MessageType parsePartialFrom(ByteString data,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Parses {@code data} as a message of {@code MessageType}.
+ * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}.
+ */
+ public MessageType parseFrom(byte[] data, int off, int len)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Parses {@code data} as a message of {@code MessageType}.
+ * This is just a small wrapper around
+ * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
+ */
+ public MessageType parseFrom(byte[] data, int off, int len,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Parses {@code data} as a message of {@code MessageType}.
+ * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}.
+ */
+ public MessageType parseFrom(byte[] data)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Parses {@code data} as a message of {@code MessageType}.
+ * This is just a small wrapper around
+ * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
+ */
+ public MessageType parseFrom(byte[] data,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseFrom(byte[], int, int)}, but does not throw an
+ * exception if the message is missing required fields. Instead, a partial
+ * message is returned.
+ */
+ public MessageType parsePartialFrom(byte[] data, int off, int len)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseFrom(ByteString, ExtensionRegistryLite)},
+ * but does not throw an exception if the message is missing required fields.
+ * Instead, a partial message is returned.
+ */
+ public MessageType parsePartialFrom(byte[] data, int off, int len,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseFrom(byte[])}, but does not throw an
+ * exception if the message is missing required fields. Instead, a partial
+ * message is returned.
+ */
+ public MessageType parsePartialFrom(byte[] data)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseFrom(byte[], ExtensionRegistryLite)},
+ * but does not throw an exception if the message is missing required fields.
+ * Instead, a partial message is returned.
+ */
+ public MessageType parsePartialFrom(byte[] data,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Parse a message of {@code MessageType} from {@code input}.
+ * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}.
+ * Note that this method always reads the <i>entire</i> input (unless it
+ * throws an exception). If you want it to stop earlier, you will need to
+ * wrap your input in some wrapper stream that limits reading. Or, use
+ * {@link MessageLite#writeDelimitedTo(java.io.OutputStream)} to write your
+ * message and {@link #parseDelimitedFrom(InputStream)} to read it.
+ * <p>
+ * Despite usually reading the entire input, this does not close the stream.
+ */
+ public MessageType parseFrom(InputStream input)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Parses a message of {@code MessageType} from {@code input}.
+ * This is just a small wrapper around
+ * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
+ */
+ public MessageType parseFrom(InputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseFrom(InputStream)}, but does not throw an
+ * exception if the message is missing required fields. Instead, a partial
+ * message is returned.
+ */
+ public MessageType parsePartialFrom(InputStream input)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseFrom(InputStream, ExtensionRegistryLite)},
+ * but does not throw an exception if the message is missing required fields.
+ * Instead, a partial message is returned.
+ */
+ public MessageType parsePartialFrom(InputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseFrom(InputStream)}, but does not read util EOF.
+ * Instead, the size of message (encoded as a varint) is read first,
+ * then the message data. Use
+ * {@link MessageLite#writeDelimitedTo(java.io.OutputStream)} to write
+ * messages in this format.
+ *
+ * @return True if successful, or false if the stream is at EOF when the
+ * method starts. Any other error (including reaching EOF during
+ * parsing) will cause an exception to be thrown.
+ */
+ public MessageType parseDelimitedFrom(InputStream input)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseDelimitedFrom(InputStream)} but supporting extensions.
+ */
+ public MessageType parseDelimitedFrom(InputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseDelimitedFrom(InputStream)}, but does not throw an
+ * exception if the message is missing required fields. Instead, a partial
+ * message is returned.
+ */
+ public MessageType parsePartialDelimitedFrom(InputStream input)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Like {@link #parseDelimitedFrom(InputStream, ExtensionRegistryLite)},
+ * but does not throw an exception if the message is missing required fields.
+ * Instead, a partial message is returned.
+ */
+ public MessageType parsePartialDelimitedFrom(
+ InputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+}
diff --git a/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java b/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java
index 112400f..0c8df98 100644
--- a/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java
+++ b/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/java/src/main/java/com/google/protobuf/ProtocolStringList.java b/java/src/main/java/com/google/protobuf/ProtocolStringList.java
new file mode 100644
index 0000000..d553b41
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/ProtocolStringList.java
@@ -0,0 +1,48 @@
+// 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.List;
+
+/**
+ * An interface extending {@code List<String>} used for repeated string fields
+ * to provide optional access to the data as a list of ByteStrings. The
+ * underlying implementation stores values as either ByteStrings or Strings
+ * (see {@link LazyStringArrayList}) depending on how the value was initialized
+ * or last read, and it is often more efficient to deal with lists of
+ * ByteStrings when handling protos that have been deserialized from bytes.
+ */
+public interface ProtocolStringList extends List<String> {
+
+ /** Returns a view of the data as a list of ByteStrings. */
+ List<ByteString> asByteStringList();
+
+}
diff --git a/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java b/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
new file mode 100644
index 0000000..22760d3
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
@@ -0,0 +1,696 @@
+// 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 RepeatedFieldBuilder} 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 SingleFieldBuilder} and {@code RepeatedFieldBuilder}
+ * classes cache messages that were created so that messages only need to be
+ * created when some change occured 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 RepeatedFieldBuilder
+ <MType extends GeneratedMessage,
+ BType extends GeneratedMessage.Builder,
+ IType extends MessageOrBuilder>
+ implements GeneratedMessage.BuilderParent {
+
+ // Parent to send changes to.
+ private GeneratedMessage.BuilderParent parent;
+
+ // List of messages. Never null. It may be immutable, in which case
+ // isMessagesListImmutable will be true. 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<SingleFieldBuilder<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 GeneratedMessage.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 RepeatedFieldBuilder(
+ List<MType> messages,
+ boolean isMessagesListMutable,
+ GeneratedMessage.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<SingleFieldBuilder<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 SingleFieldBuilder.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);
+ }
+
+ SingleFieldBuilder<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();
+ SingleFieldBuilder<MType, BType, IType> builder = builders.get(index);
+ if (builder == null) {
+ MType message = messages.get(index);
+ builder = new SingleFieldBuilder<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);
+ }
+
+ SingleFieldBuilder<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 RepeatedFieldBuilder<MType, BType, IType> setMessage(
+ int index, MType message) {
+ if (message == null) {
+ throw new NullPointerException();
+ }
+ ensureMutableMessageList();
+ messages.set(index, message);
+ if (builders != null) {
+ SingleFieldBuilder<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 RepeatedFieldBuilder<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 RepeatedFieldBuilder<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 RepeatedFieldBuilder<MType, BType, IType> addAllMessages(
+ Iterable<? extends MType> values) {
+ for (final MType value : values) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ }
+ if (values instanceof Collection) {
+ @SuppressWarnings("unchecked") final
+ Collection<MType> collection = (Collection<MType>) values;
+ if (collection.size() == 0) {
+ return this;
+ }
+ ensureMutableMessageList();
+ for (MType value : values) {
+ addMessage(value);
+ }
+ } else {
+ ensureMutableMessageList();
+ 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();
+ SingleFieldBuilder<MType, BType, IType> builder =
+ new SingleFieldBuilder<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();
+ SingleFieldBuilder<MType, BType, IType> builder =
+ new SingleFieldBuilder<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) {
+ SingleFieldBuilder<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 (SingleFieldBuilder<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);
+ SingleFieldBuilder<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 (Java 1.6 override semantics, but we must support 1.5)
+ 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 GeneratedMessage,
+ BType extends GeneratedMessage.Builder,
+ IType extends MessageOrBuilder>
+ extends AbstractList<MType> implements List<MType> {
+
+ RepeatedFieldBuilder<MType, BType, IType> builder;
+
+ MessageExternalList(
+ RepeatedFieldBuilder<MType, BType, IType> builder) {
+ this.builder = builder;
+ }
+
+ public int size() {
+ return this.builder.getCount();
+ }
+
+ 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 GeneratedMessage,
+ BType extends GeneratedMessage.Builder,
+ IType extends MessageOrBuilder>
+ extends AbstractList<BType> implements List<BType> {
+
+ RepeatedFieldBuilder<MType, BType, IType> builder;
+
+ BuilderExternalList(
+ RepeatedFieldBuilder<MType, BType, IType> builder) {
+ this.builder = builder;
+ }
+
+ public int size() {
+ return this.builder.getCount();
+ }
+
+ 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 GeneratedMessage,
+ BType extends GeneratedMessage.Builder,
+ IType extends MessageOrBuilder>
+ extends AbstractList<IType> implements List<IType> {
+
+ RepeatedFieldBuilder<MType, BType, IType> builder;
+
+ MessageOrBuilderExternalList(
+ RepeatedFieldBuilder<MType, BType, IType> builder) {
+ this.builder = builder;
+ }
+
+ public int size() {
+ return this.builder.getCount();
+ }
+
+ 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/src/main/java/com/google/protobuf/RopeByteString.java
new file mode 100644
index 0000000..d1655b8
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/RopeByteString.java
@@ -0,0 +1,957 @@
+// 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.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.io.ByteArrayInputStream;
+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.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}.
+ *
+ * <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">
+ * BAP95 </a> Ropes: an Alternative to Strings hans-j. boehm, russ atkinson and
+ * michael plass
+ *
+ * <p>The algorithms described in the paper have been implemented for character
+ * strings in {@link com.google.common.string.Rope} and in the c++ class {@code
+ * cord.cc}.
+ *
+ * <p>Fundamentally the Rope algorithm represents the collection of pieces as a
+ * binary tree. BAP95 uses a Fibonacci bound relating depth to a minimum
+ * sequence length, sequences that are too short relative to their depth cause a
+ * tree rebalance. More precisely, a tree of depth d is "balanced" in the
+ * terminology of BAP95 if its length is at least F(d+2), where F(n) is the
+ * n-the Fibonacci number. Thus for depths 0, 1, 2, 3, 4, 5,... we have minimum
+ * lengths 1, 2, 3, 5, 8, 13,...
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+class RopeByteString extends ByteString {
+
+ /**
+ * BAP95. Let Fn be the nth Fibonacci number. A {@link RopeByteString} of
+ * depth n is "balanced", i.e flat enough, if its length is at least Fn+2,
+ * e.g. a "balanced" {@link RopeByteString} of depth 1 must have length at
+ * least 2, of depth 4 must have length >= 8, etc.
+ *
+ * <p>There's nothing special about using the Fibonacci numbers for this, but
+ * they are a reasonable sequence for encapsulating the idea that we are OK
+ * with longer strings being encoded in deeper binary trees.
+ *
+ * <p>For 32-bit integers, this array has length 46.
+ */
+ private static final int[] minLengthByDepth;
+
+ static {
+ // Dynamically generate the list of Fibonacci numbers the first time this
+ // class is accessed.
+ List<Integer> numbers = new ArrayList<Integer>();
+
+ // we skip the first Fibonacci number (1). So instead of: 1 1 2 3 5 8 ...
+ // we have: 1 2 3 5 8 ...
+ int f1 = 1;
+ int f2 = 1;
+
+ // get all the values until we roll over.
+ while (f2 > 0) {
+ numbers.add(f2);
+ int temp = f1 + f2;
+ f1 = f2;
+ f2 = temp;
+ }
+
+ // we include this here so that we can index this array to [x + 1] in the
+ // loops below.
+ numbers.add(Integer.MAX_VALUE);
+ minLengthByDepth = new int[numbers.size()];
+ for (int i = 0; i < minLengthByDepth.length; i++) {
+ // unbox all the values
+ minLengthByDepth[i] = numbers.get(i);
+ }
+ }
+
+ private final int totalLength;
+ private final ByteString left;
+ private final ByteString right;
+ private final int leftLength;
+ private final int treeDepth;
+
+ /**
+ * Create a new RopeByteString, which can be thought of as a new tree node, by
+ * recording references to the two given strings.
+ *
+ * @param left string on the left of this node, should have {@code size() >
+ * 0}
+ * @param right string on the right of this node, should have {@code size() >
+ * 0}
+ */
+ private RopeByteString(ByteString left, ByteString right) {
+ this.left = left;
+ this.right = right;
+ leftLength = left.size();
+ totalLength = leftLength + right.size();
+ treeDepth = Math.max(left.getTreeDepth(), right.getTreeDepth()) + 1;
+ }
+
+ /**
+ * 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.
+ *
+ * <p>Small pieces of length less than {@link
+ * ByteString#CONCATENATE_BY_COPY_SIZE} may be copied by value here, as in
+ * BAP95. Large pieces are referenced without copy.
+ *
+ * @param left string on the left
+ * @param right string on the right
+ * @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) {
+ // 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
+ // right-hand branch is short. In the paper this applies to leaves, but
+ // we just look at the length here. This has the advantage of shedding
+ // references to unneeded data when substrings have been taken.
+ //
+ // When we recognize this case, we do a copy of the data and create a
+ // 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()
+ && 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
+ // 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 result;
+ }
+
+ /**
+ * Concatenates two strings by copying data values. This is called in a few
+ * cases in order to reduce the growth of the number of tree nodes.
+ *
+ * @param left string on the left
+ * @param right string on the right
+ * @return string formed by copying data bytes
+ */
+ private static LiteralByteString 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
+ }
+
+ /**
+ * Create a new RopeByteString for testing only while bypassing all the
+ * defenses of {@link #concatenate(ByteString, ByteString)}. This allows
+ * testing trees of specific structure. We are also able to insert empty
+ * leaves, though these are dis-allowed, so that we can make sure the
+ * implementation can withstand their presence.
+ *
+ * @param left string on the left of this node
+ * @param right string on the right of this node
+ * @return an unsafe instance for testing only
+ */
+ static RopeByteString newInstanceForTest(ByteString left, ByteString right) {
+ return new RopeByteString(left, right);
+ }
+
+ /**
+ * 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) {
+ if (index < 0) {
+ throw new ArrayIndexOutOfBoundsException("Index < 0: " + index);
+ }
+ if (index > totalLength) {
+ throw new ArrayIndexOutOfBoundsException(
+ "Index > length: " + 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 result;
+ }
+
+ @Override
+ public int size() {
+ return totalLength;
+ }
+
+ // =================================================================
+ // Pieces
+
+ @Override
+ protected int getTreeDepth() {
+ return treeDepth;
+ }
+
+ /**
+ * Determines if the tree is balanced according to BAP95, which means the tree
+ * is flat-enough with respect to the bounds. Note that this definition of
+ * balanced is one where sub-trees of balanced trees are not necessarily
+ * balanced.
+ *
+ * @return true if the tree is balanced
+ */
+ @Override
+ protected boolean isBalanced() {
+ return totalLength >= minLengthByDepth[treeDepth];
+ }
+
+ /**
+ * Takes a substring of this one. This involves recursive descent along the
+ * left and right edges of the substring, and referencing any wholly contained
+ * segments in between. Any leaf nodes entirely uninvolved in the substring
+ * will not be referenced by the substring.
+ *
+ * <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)}.
+ *
+ * @param beginIndex start at this index
+ * @param endIndex the last character is the one before this index
+ * @return substring leaf node or tree
+ */
+ @Override
+ public ByteString substring(int beginIndex, int endIndex) {
+ if (beginIndex < 0) {
+ throw new IndexOutOfBoundsException(
+ "Beginning index: " + beginIndex + " < 0");
+ }
+ if (endIndex > totalLength) {
+ throw new IndexOutOfBoundsException(
+ "End index: " + endIndex + " > " + totalLength);
+ }
+ int substringLength = endIndex - beginIndex;
+ if (substringLength < 0) {
+ throw new IndexOutOfBoundsException(
+ "Beginning index larger than ending index: " + 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);
+ }
+ }
+ return result;
+ }
+
+ // =================================================================
+ // ByteString -> byte[]
+
+ @Override
+ protected void copyToInternal(byte[] target, int sourceOffset,
+ int targetOffset, int numberToCopy) {
+ if (sourceOffset + numberToCopy <= leftLength) {
+ left.copyToInternal(target, sourceOffset, targetOffset, numberToCopy);
+ } else if (sourceOffset >= leftLength) {
+ right.copyToInternal(target, sourceOffset - leftLength, targetOffset,
+ numberToCopy);
+ } else {
+ int leftLength = this.leftLength - sourceOffset;
+ left.copyToInternal(target, sourceOffset, targetOffset, leftLength);
+ right.copyToInternal(target, 0, targetOffset + leftLength,
+ numberToCopy - leftLength);
+ }
+ }
+
+ @Override
+ public void copyTo(ByteBuffer target) {
+ left.copyTo(target);
+ right.copyTo(target);
+ }
+
+ @Override
+ public ByteBuffer asReadOnlyByteBuffer() {
+ ByteBuffer byteBuffer = ByteBuffer.wrap(toByteArray());
+ return byteBuffer.asReadOnlyBuffer();
+ }
+
+ @Override
+ public List<ByteBuffer> asReadOnlyByteBufferList() {
+ // Walk through the list of LiteralByteString'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();
+ result.add(byteString.asReadOnlyByteBuffer());
+ }
+ return result;
+ }
+
+ @Override
+ public void writeTo(OutputStream outputStream) throws IOException {
+ left.writeTo(outputStream);
+ right.writeTo(outputStream);
+ }
+
+ @Override
+ void writeToInternal(OutputStream out, int sourceOffset,
+ int numberToWrite) throws IOException {
+ if (sourceOffset + numberToWrite <= leftLength) {
+ left.writeToInternal(out, sourceOffset, numberToWrite);
+ } else if (sourceOffset >= leftLength) {
+ right.writeToInternal(out, sourceOffset - leftLength, numberToWrite);
+ } else {
+ int numberToWriteInLeft = leftLength - sourceOffset;
+ left.writeToInternal(out, sourceOffset, numberToWriteInLeft);
+ right.writeToInternal(out, 0, numberToWrite - numberToWriteInLeft);
+ }
+ }
+
+ @Override
+ public String toString(String charsetName)
+ throws UnsupportedEncodingException {
+ return new String(toByteArray(), charsetName);
+ }
+
+ // =================================================================
+ // UTF-8 decoding
+
+ @Override
+ public boolean isValidUtf8() {
+ int leftPartial = left.partialIsValidUtf8(Utf8.COMPLETE, 0, leftLength);
+ int state = right.partialIsValidUtf8(leftPartial, 0, right.size());
+ return state == Utf8.COMPLETE;
+ }
+
+ @Override
+ protected int partialIsValidUtf8(int state, int offset, int length) {
+ int toIndex = offset + length;
+ if (toIndex <= leftLength) {
+ return left.partialIsValidUtf8(state, offset, length);
+ } else if (offset >= leftLength) {
+ return right.partialIsValidUtf8(state, offset - leftLength, length);
+ } else {
+ int leftLength = this.leftLength - offset;
+ int leftPartial = left.partialIsValidUtf8(state, offset, leftLength);
+ return right.partialIsValidUtf8(leftPartial, 0, length - leftLength);
+ }
+ }
+
+ // =================================================================
+ // equals() and hashCode()
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if (!(other instanceof ByteString)) {
+ return false;
+ }
+
+ ByteString otherByteString = (ByteString) other;
+ if (totalLength != otherByteString.size()) {
+ return false;
+ }
+ if (totalLength == 0) {
+ return true;
+ }
+
+ // You don't really want to be calling equals on long strings, but since
+ // we cache the hashCode, we effectively cache inequality. We use the cached
+ // 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;
+ }
+ }
+
+ return equalsFragments(otherByteString);
+ }
+
+ /**
+ * Determines if this string is equal to another of the same length by
+ * iterating over the leaf nodes. On each step of the iteration, the
+ * overlapping segments of the leaves are compared.
+ *
+ * @param other string of the same length as this one
+ * @return true if the values of this string equals the value of the given
+ * one
+ */
+ private boolean equalsFragments(ByteString other) {
+ int thisOffset = 0;
+ Iterator<LiteralByteString> thisIter = new PieceIterator(this);
+ LiteralByteString thisString = thisIter.next();
+
+ int thatOffset = 0;
+ Iterator<LiteralByteString> thatIter = new PieceIterator(other);
+ LiteralByteString thatString = thatIter.next();
+
+ int pos = 0;
+ while (true) {
+ int thisRemaining = thisString.size() - thisOffset;
+ int thatRemaining = thatString.size() - thatOffset;
+ int bytesToCompare = Math.min(thisRemaining, thatRemaining);
+
+ // At least one of the offsets will be zero
+ boolean stillEqual = (thisOffset == 0)
+ ? thisString.equalsRange(thatString, thatOffset, bytesToCompare)
+ : thatString.equalsRange(thisString, thisOffset, bytesToCompare);
+ if (!stillEqual) {
+ return false;
+ }
+
+ pos += bytesToCompare;
+ if (pos >= totalLength) {
+ if (pos == totalLength) {
+ return true;
+ }
+ throw new IllegalStateException();
+ }
+ // We always get to the end of at least one of the pieces
+ if (bytesToCompare == thisRemaining) { // If reached end of this
+ thisOffset = 0;
+ thisString = thisIter.next();
+ } else {
+ thisOffset += bytesToCompare;
+ }
+ if (bytesToCompare == thatRemaining) { // If reached end of that
+ thatOffset = 0;
+ thatString = thatIter.next();
+ } else {
+ thatOffset += bytesToCompare;
+ }
+ }
+ }
+
+ /**
+ * 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;
+ if (toIndex <= leftLength) {
+ return left.partialHash(h, offset, length);
+ } else if (offset >= leftLength) {
+ return right.partialHash(h, offset - leftLength, length);
+ } else {
+ int leftLength = this.leftLength - offset;
+ int leftPartial = left.partialHash(h, offset, leftLength);
+ return right.partialHash(leftPartial, 0, length - leftLength);
+ }
+ }
+
+ // =================================================================
+ // Input stream
+
+ @Override
+ public CodedInputStream newCodedInput() {
+ return CodedInputStream.newInstance(new RopeInputStream());
+ }
+
+ @Override
+ public InputStream newInput() {
+ return new RopeInputStream();
+ }
+
+ /**
+ * This class implements the balancing algorithm of BAP95. In the paper the
+ * authors use an array to keep track of pieces, while here we use a stack.
+ * The tree is balanced by traversing subtrees in left to right order, and the
+ * stack always contains the part of the string we've traversed so far.
+ *
+ * <p>One surprising aspect of the algorithm is the result of balancing is not
+ * necessarily balanced, though it is nearly balanced. For details, see
+ * BAP95.
+ */
+ private static class Balancer {
+ // Stack containing the part of the string, starting from the left, that
+ // we've already traversed. The final string should be the equivalent of
+ // concatenating the strings on the stack from bottom to top.
+ private final Stack<ByteString> prefixesStack = new Stack<ByteString>();
+
+ private ByteString balance(ByteString left, ByteString right) {
+ doBalance(left);
+ doBalance(right);
+
+ // Sweep stack to gather the result
+ ByteString partialString = prefixesStack.pop();
+ while (!prefixesStack.isEmpty()) {
+ ByteString newLeft = prefixesStack.pop();
+ partialString = new RopeByteString(newLeft, partialString);
+ }
+ // We should end up with a RopeByteString since at a minimum we will
+ // create one from concatenating left and right
+ return partialString;
+ }
+
+ private void doBalance(ByteString root) {
+ // BAP95: Insert balanced subtrees whole. This means the result might not
+ // be balanced, leading to repeated rebalancings on concatenate. However,
+ // these rebalancings are shallow due to ignoring balanced subtrees, and
+ // relatively few calls to insert() result.
+ if (root.isBalanced()) {
+ insert(root);
+ } else if (root instanceof RopeByteString) {
+ RopeByteString rbs = (RopeByteString) root;
+ doBalance(rbs.left);
+ doBalance(rbs.right);
+ } else {
+ throw new IllegalArgumentException(
+ "Has a new type of ByteString been created? Found " +
+ root.getClass());
+ }
+ }
+
+ /**
+ * Push a string on the balance stack (BAP95). BAP95 uses an array and
+ * calls the elements in the array 'bins'. We instead use a stack, so the
+ * 'bins' of lengths are represented by differences between the elements of
+ * minLengthByDepth.
+ *
+ * <p>If the length bin for our string, and all shorter length bins, are
+ * empty, we just push it on the stack. Otherwise, we need to start
+ * concatenating, putting the given string in the "middle" and continuing
+ * until we land in an empty length bin that matches the length of our
+ * concatenation.
+ *
+ * @param byteString string to place on the balance stack
+ */
+ private void insert(ByteString byteString) {
+ int depthBin = getDepthBinForLength(byteString.size());
+ int binEnd = minLengthByDepth[depthBin + 1];
+
+ // BAP95: Concatenate all trees occupying bins representing the length of
+ // our new piece or of shorter pieces, to the extent that is possible.
+ // The goal is to clear the bin which our piece belongs in, but that may
+ // not be entirely possible if there aren't enough longer bins occupied.
+ if (prefixesStack.isEmpty() || prefixesStack.peek().size() >= binEnd) {
+ prefixesStack.push(byteString);
+ } else {
+ int binStart = minLengthByDepth[depthBin];
+
+ // Concatenate the subtrees of shorter length
+ ByteString newTree = prefixesStack.pop();
+ while (!prefixesStack.isEmpty()
+ && prefixesStack.peek().size() < binStart) {
+ ByteString left = prefixesStack.pop();
+ newTree = new RopeByteString(left, newTree);
+ }
+
+ // Concatenate the given string
+ newTree = new RopeByteString(newTree, byteString);
+
+ // Continue concatenating until we land in an empty bin
+ while (!prefixesStack.isEmpty()) {
+ depthBin = getDepthBinForLength(newTree.size());
+ binEnd = minLengthByDepth[depthBin + 1];
+ if (prefixesStack.peek().size() < binEnd) {
+ ByteString left = prefixesStack.pop();
+ newTree = new RopeByteString(left, newTree);
+ } else {
+ break;
+ }
+ }
+ prefixesStack.push(newTree);
+ }
+ }
+
+ private int getDepthBinForLength(int length) {
+ int depth = Arrays.binarySearch(minLengthByDepth, length);
+ if (depth < 0) {
+ // It wasn't an exact match, so convert to the index of the containing
+ // fragment, which is one less even than the insertion point.
+ int insertionPoint = -(depth + 1);
+ depth = insertionPoint - 1;
+ }
+
+ return depth;
+ }
+ }
+
+ /**
+ * This class is a continuable tree traversal, which keeps the state
+ * information which would exist on the stack in a recursive traversal instead
+ * on a stack of "Bread Crumbs". The maximum depth of the stack in this
+ * iterator is the same as the depth of the tree being traversed.
+ *
+ * <p>This iterator is used to implement
+ * {@link RopeByteString#equalsFragments(ByteString)}.
+ */
+ private static class PieceIterator implements Iterator<LiteralByteString> {
+
+ private final Stack<RopeByteString> breadCrumbs =
+ new Stack<RopeByteString>();
+ private LiteralByteString next;
+
+ private PieceIterator(ByteString root) {
+ next = getLeafByLeft(root);
+ }
+
+ private LiteralByteString getLeafByLeft(ByteString root) {
+ ByteString pos = root;
+ while (pos instanceof RopeByteString) {
+ RopeByteString rbs = (RopeByteString) pos;
+ breadCrumbs.push(rbs);
+ pos = rbs.left;
+ }
+ return (LiteralByteString) pos;
+ }
+
+ private LiteralByteString 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);
+ if (!result.isEmpty()) {
+ return result;
+ }
+ }
+ }
+ }
+
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ /**
+ * Returns the next item and advances one {@code LiteralByteString}.
+ *
+ * @return next non-empty LiteralByteString or {@code null}
+ */
+ public LiteralByteString next() {
+ if (next == null) {
+ throw new NoSuchElementException();
+ }
+ LiteralByteString result = next;
+ next = getNextNonEmptyLeaf();
+ return result;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ // =================================================================
+ // 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}.
+ */
+ private class RopeInputStream extends InputStream {
+ // Iterates through the pieces of the rope
+ private PieceIterator pieceIterator;
+ // The current piece
+ private LiteralByteString currentPiece;
+ // The size of the current piece
+ private int currentPieceSize;
+ // The index of the next byte to read in the current piece
+ private int currentPieceIndex;
+ // The offset of the start of the current piece in the rope byte string
+ private int currentPieceOffsetInRope;
+ // Offset in the buffer at which user called mark();
+ private int mark;
+
+ public RopeInputStream() {
+ initialize();
+ }
+
+ @Override
+ public int read(byte b[], int offset, int length) {
+ if (b == null) {
+ throw new NullPointerException();
+ } else if (offset < 0 || length < 0 || length > b.length - offset) {
+ throw new IndexOutOfBoundsException();
+ }
+ return readSkipInternal(b, offset, length);
+ }
+
+ @Override
+ public long skip(long length) {
+ if (length < 0) {
+ throw new IndexOutOfBoundsException();
+ } else if (length > Integer.MAX_VALUE) {
+ length = Integer.MAX_VALUE;
+ }
+ return readSkipInternal(null, 0, (int) length);
+ }
+
+ /**
+ * 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)
+ * bytes.
+ * <p>
+ * This method assumes that all error checking has already happened.
+ * <p>
+ * Returns the actual number of bytes read or skipped.
+ */
+ private int readSkipInternal(byte b[], int offset, int length) {
+ int bytesRemaining = length;
+ while (bytesRemaining > 0) {
+ advanceIfCurrentPieceFullyRead();
+ if (currentPiece == null) {
+ if (bytesRemaining == length) {
+ // We didn't manage to read anything
+ return -1;
+ }
+ break;
+ } else {
+ // Copy the bytes from this piece.
+ int currentPieceRemaining = currentPieceSize - currentPieceIndex;
+ int count = Math.min(currentPieceRemaining, bytesRemaining);
+ if (b != null) {
+ currentPiece.copyTo(b, currentPieceIndex, offset, count);
+ offset += count;
+ }
+ currentPieceIndex += count;
+ bytesRemaining -= count;
+ }
+ }
+ // Return the number of bytes read.
+ return length - bytesRemaining;
+ }
+
+ @Override
+ public int read() throws IOException {
+ advanceIfCurrentPieceFullyRead();
+ if (currentPiece == null) {
+ return -1;
+ } else {
+ return currentPiece.byteAt(currentPieceIndex++) & 0xFF;
+ }
+ }
+
+ @Override
+ public int available() throws IOException {
+ int bytesRead = currentPieceOffsetInRope + currentPieceIndex;
+ return RopeByteString.this.size() - bytesRead;
+ }
+
+ @Override
+ public boolean markSupported() {
+ return true;
+ }
+
+ @Override
+ public void mark(int readAheadLimit) {
+ // Set the mark to our position in the byte string
+ mark = currentPieceOffsetInRope + currentPieceIndex;
+ }
+
+ @Override
+ public synchronized void reset() {
+ // Just reinitialize and skip the specified number of bytes.
+ initialize();
+ readSkipInternal(null, 0, mark);
+ }
+
+ /** Common initialization code used by both the constructor and reset() */
+ private void initialize() {
+ pieceIterator = new PieceIterator(RopeByteString.this);
+ currentPiece = pieceIterator.next();
+ currentPieceSize = currentPiece.size();
+ currentPieceIndex = 0;
+ currentPieceOffsetInRope = 0;
+ }
+
+ /**
+ * Skips to the next piece if we have read all the data in the current
+ * piece. Sets currentPiece to null if we have reached the end of the
+ * input.
+ */
+ private void advanceIfCurrentPieceFullyRead() {
+ if (currentPiece != null && currentPieceIndex == currentPieceSize) {
+ // Generally, we can only go through this loop at most once, since
+ // empty strings can't end up in a rope. But better to test.
+ currentPieceOffsetInRope += currentPieceSize;
+ currentPieceIndex = 0;
+ if (pieceIterator.hasNext()) {
+ currentPiece = pieceIterator.next();
+ currentPieceSize = currentPiece.size();
+ } else {
+ currentPiece = null;
+ currentPieceSize = 0;
+ }
+ }
+ }
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/RpcCallback.java b/java/src/main/java/com/google/protobuf/RpcCallback.java
index 1fd35ed..1075296 100644
--- a/java/src/main/java/com/google/protobuf/RpcCallback.java
+++ b/java/src/main/java/com/google/protobuf/RpcCallback.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/java/src/main/java/com/google/protobuf/RpcChannel.java b/java/src/main/java/com/google/protobuf/RpcChannel.java
index c6ec54f..f272f4a 100644
--- a/java/src/main/java/com/google/protobuf/RpcChannel.java
+++ b/java/src/main/java/com/google/protobuf/RpcChannel.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/java/src/main/java/com/google/protobuf/RpcController.java b/java/src/main/java/com/google/protobuf/RpcController.java
index aaa5446..a92dd7b 100644
--- a/java/src/main/java/com/google/protobuf/RpcController.java
+++ b/java/src/main/java/com/google/protobuf/RpcController.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/java/src/main/java/com/google/protobuf/RpcUtil.java b/java/src/main/java/com/google/protobuf/RpcUtil.java
index b1b959a..694b8d1 100644
--- a/java/src/main/java/com/google/protobuf/RpcUtil.java
+++ b/java/src/main/java/com/google/protobuf/RpcUtil.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -91,9 +91,8 @@ public final class RpcUtil {
@SuppressWarnings("unchecked")
private static <Type extends Message> Type copyAsType(
final Type typeDefaultInstance, final Message source) {
- return (Type)typeDefaultInstance.newBuilderForType()
- .mergeFrom(source)
- .build();
+ return (Type) typeDefaultInstance
+ .newBuilderForType().mergeFrom(source).build();
}
/**
diff --git a/java/src/main/java/com/google/protobuf/Service.java b/java/src/main/java/com/google/protobuf/Service.java
index 541585f..ba7b033 100644
--- a/java/src/main/java/com/google/protobuf/Service.java
+++ b/java/src/main/java/com/google/protobuf/Service.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/java/src/main/java/com/google/protobuf/ServiceException.java b/java/src/main/java/com/google/protobuf/ServiceException.java
index c043a77..00d5707 100644
--- a/java/src/main/java/com/google/protobuf/ServiceException.java
+++ b/java/src/main/java/com/google/protobuf/ServiceException.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,10 +35,18 @@ package com.google.protobuf;
*
* @author cpovirk@google.com (Chris Povirk)
*/
-public final class ServiceException extends Exception {
+public class ServiceException extends Exception {
private static final long serialVersionUID = -1219262335729891920L;
public ServiceException(final String message) {
super(message);
}
+
+ public ServiceException(final Throwable cause) {
+ super(cause);
+ }
+
+ public ServiceException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
}
diff --git a/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java b/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java
new file mode 100644
index 0000000..13a36d4
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/SingleFieldBuilder.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 SingleFieldBuilder} 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 SingleFieldBuilder} and {@code RepeatedFieldBuilder}
+ * classes cache messages that were created so that messages only need to be
+ * created when some change occured 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 SingleFieldBuilder
+ <MType extends GeneratedMessage,
+ BType extends GeneratedMessage.Builder,
+ IType extends MessageOrBuilder>
+ implements GeneratedMessage.BuilderParent {
+
+ // Parent to send changes to.
+ private GeneratedMessage.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 GeneratedMessage.BuilderListener.
+ private boolean isClean;
+
+ public SingleFieldBuilder(
+ MType message,
+ GeneratedMessage.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 SingleFieldBuilder<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 SingleFieldBuilder<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 SingleFieldBuilder<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 (Java 1.6 override semantics, but we must support 1.5)
+ public void markDirty() {
+ onChanged();
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/SmallSortedMap.java b/java/src/main/java/com/google/protobuf/SmallSortedMap.java
new file mode 100644
index 0000000..0674d2e
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/SmallSortedMap.java
@@ -0,0 +1,618 @@
+// 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.AbstractMap;
+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;
+
+/**
+ * A custom map implementation from FieldDescriptor to Object optimized to
+ * minimize the number of memory allocations for instances with a small number
+ * of mappings. The implementation stores the first {@code k} mappings in an
+ * array for a configurable value of {@code k}, allowing direct access to the
+ * corresponding {@code Entry}s without the need to create an Iterator. The
+ * remaining entries are stored in an overflow map. Iteration over the entries
+ * in the map should be done as follows:
+ *
+ * <pre> {@code
+ * for (int i = 0; i < fieldMap.getNumArrayEntries(); i++) {
+ * process(fieldMap.getArrayEntryAt(i));
+ * }
+ * for (Map.Entry<K, V> entry : fieldMap.getOverflowEntries()) {
+ * process(entry);
+ * }
+ * }</pre>
+ *
+ * The resulting iteration is in order of ascending field tag number. The
+ * object returned by {@link #entrySet()} adheres to the same contract but is
+ * less efficient as it necessarily involves creating an object for iteration.
+ * <p>
+ * The tradeoff for this memory efficiency is that the worst case running time
+ * of the {@code put()} operation is {@code O(k + lg n)}, which happens when
+ * entries are added in descending order. {@code k} should be chosen such that
+ * it covers enough common cases without adversely affecting larger maps. In
+ * practice, the worst case scenario does not happen for extensions because
+ * extension fields are serialized and deserialized in order of ascending tag
+ * number, but the worst case scenario can happen for DynamicMessages.
+ * <p>
+ * The running time for all other operations is similar to that of
+ * {@code TreeMap}.
+ * <p>
+ * Instances are not thread-safe until {@link #makeImmutable()} is called,
+ * after which any modifying operation will result in an
+ * {@link UnsupportedOperationException}.
+ *
+ * @author darick@google.com Darick Tong
+ */
+// This class is final for all intents and purposes because the constructor is
+// private. However, the FieldDescriptor-specific logic is encapsulated in
+// a subclass to aid testability of the core logic.
+class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
+
+ /**
+ * Creates a new instance for mapping FieldDescriptors to their values.
+ * The {@link #makeImmutable()} implementation will convert the List values
+ * of any repeated fields to unmodifiable lists.
+ *
+ * @param arraySize The size of the entry array containing the
+ * lexicographically smallest mappings.
+ */
+ static <FieldDescriptorType extends
+ FieldSet.FieldDescriptorLite<FieldDescriptorType>>
+ SmallSortedMap<FieldDescriptorType, Object> newFieldMap(int arraySize) {
+ return new SmallSortedMap<FieldDescriptorType, Object>(arraySize) {
+ @Override
+ @SuppressWarnings("unchecked")
+ public void makeImmutable() {
+ if (!isImmutable()) {
+ for (int i = 0; i < getNumArrayEntries(); i++) {
+ final Map.Entry<FieldDescriptorType, Object> entry =
+ getArrayEntryAt(i);
+ if (entry.getKey().isRepeated()) {
+ final List value = (List) entry.getValue();
+ entry.setValue(Collections.unmodifiableList(value));
+ }
+ }
+ for (Map.Entry<FieldDescriptorType, Object> entry :
+ getOverflowEntries()) {
+ if (entry.getKey().isRepeated()) {
+ final List value = (List) entry.getValue();
+ entry.setValue(Collections.unmodifiableList(value));
+ }
+ }
+ }
+ super.makeImmutable();
+ }
+ };
+ }
+
+ /**
+ * Creates a new instance for testing.
+ *
+ * @param arraySize The size of the entry array containing the
+ * lexicographically smallest mappings.
+ */
+ static <K extends Comparable<K>, V> SmallSortedMap<K, V> newInstanceForTest(
+ int arraySize) {
+ return new SmallSortedMap<K, V>(arraySize);
+ }
+
+ private final int maxArraySize;
+ // The "entry array" is actually a List because generic arrays are not
+ // allowed. ArrayList also nicely handles the entry shifting on inserts and
+ // removes.
+ private List<Entry> entryList;
+ private Map<K, V> overflowEntries;
+ private boolean isImmutable;
+ // The EntrySet is a stateless view of the Map. It's initialized the first
+ // time it is requested and reused henceforth.
+ private volatile EntrySet lazyEntrySet;
+
+ /**
+ * @code arraySize Size of the array in which the lexicographically smallest
+ * mappings are stored. (i.e. the {@code k} referred to in the class
+ * documentation).
+ */
+ private SmallSortedMap(int arraySize) {
+ this.maxArraySize = arraySize;
+ this.entryList = Collections.emptyList();
+ this.overflowEntries = Collections.emptyMap();
+ }
+
+ /** Make this map immutable from this point forward. */
+ public void makeImmutable() {
+ if (!isImmutable) {
+ // Note: There's no need to wrap the entryList in an unmodifiableList
+ // because none of the list's accessors are exposed. The iterator() of
+ // overflowEntries, on the other hand, is exposed so it must be made
+ // unmodifiable.
+ overflowEntries = overflowEntries.isEmpty() ?
+ Collections.<K, V>emptyMap() :
+ Collections.unmodifiableMap(overflowEntries);
+ isImmutable = true;
+ }
+ }
+
+ /** @return Whether {@link #makeImmutable()} has been called. */
+ public boolean isImmutable() {
+ return isImmutable;
+ }
+
+ /** @return The number of entries in the entry array. */
+ public int getNumArrayEntries() {
+ return entryList.size();
+ }
+
+ /** @return The array entry at the given {@code index}. */
+ public Map.Entry<K, V> getArrayEntryAt(int index) {
+ return entryList.get(index);
+ }
+
+ /** @return There number of overflow entries. */
+ public int getNumOverflowEntries() {
+ return overflowEntries.size();
+ }
+
+ /** @return An iterable over the overflow entries. */
+ public Iterable<Map.Entry<K, V>> getOverflowEntries() {
+ return overflowEntries.isEmpty() ?
+ EmptySet.<Map.Entry<K, V>>iterable() :
+ overflowEntries.entrySet();
+ }
+
+ @Override
+ public int size() {
+ return entryList.size() + overflowEntries.size();
+ }
+
+ /**
+ * The implementation throws a {@code ClassCastException} if o is not an
+ * object of type {@code K}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean containsKey(Object o) {
+ @SuppressWarnings("unchecked")
+ final K key = (K) o;
+ return binarySearchInArray(key) >= 0 || overflowEntries.containsKey(key);
+ }
+
+ /**
+ * The implementation throws a {@code ClassCastException} if o is not an
+ * object of type {@code K}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public V get(Object o) {
+ @SuppressWarnings("unchecked")
+ final K key = (K) o;
+ final int index = binarySearchInArray(key);
+ if (index >= 0) {
+ return entryList.get(index).getValue();
+ }
+ return overflowEntries.get(key);
+ }
+
+ @Override
+ public V put(K key, V value) {
+ checkMutable();
+ final int index = binarySearchInArray(key);
+ if (index >= 0) {
+ // Replace existing array entry.
+ return entryList.get(index).setValue(value);
+ }
+ ensureEntryArrayMutable();
+ final int insertionPoint = -(index + 1);
+ if (insertionPoint >= maxArraySize) {
+ // Put directly in overflow.
+ return getOverflowEntriesMutable().put(key, value);
+ }
+ // Insert new Entry in array.
+ if (entryList.size() == maxArraySize) {
+ // Shift the last array entry into overflow.
+ final Entry lastEntryInArray = entryList.remove(maxArraySize - 1);
+ getOverflowEntriesMutable().put(lastEntryInArray.getKey(),
+ lastEntryInArray.getValue());
+ }
+ entryList.add(insertionPoint, new Entry(key, value));
+ return null;
+ }
+
+ @Override
+ public void clear() {
+ checkMutable();
+ if (!entryList.isEmpty()) {
+ entryList.clear();
+ }
+ if (!overflowEntries.isEmpty()) {
+ overflowEntries.clear();
+ }
+ }
+
+ /**
+ * The implementation throws a {@code ClassCastException} if o is not an
+ * object of type {@code K}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public V remove(Object o) {
+ checkMutable();
+ @SuppressWarnings("unchecked")
+ final K key = (K) o;
+ final int index = binarySearchInArray(key);
+ if (index >= 0) {
+ return removeArrayEntryAt(index);
+ }
+ // overflowEntries might be Collections.unmodifiableMap(), so only
+ // call remove() if it is non-empty.
+ if (overflowEntries.isEmpty()) {
+ return null;
+ } else {
+ return overflowEntries.remove(key);
+ }
+ }
+
+ private V removeArrayEntryAt(int index) {
+ checkMutable();
+ final V removed = entryList.remove(index).getValue();
+ if (!overflowEntries.isEmpty()) {
+ // Shift the first entry in the overflow to be the last entry in the
+ // array.
+ final Iterator<Map.Entry<K, V>> iterator =
+ getOverflowEntriesMutable().entrySet().iterator();
+ entryList.add(new Entry(iterator.next()));
+ iterator.remove();
+ }
+ return removed;
+ }
+
+ /**
+ * @param key The key to find in the entry array.
+ * @return The returned integer position follows the same semantics as the
+ * value returned by {@link java.util.Arrays#binarySearch()}.
+ */
+ private int binarySearchInArray(K key) {
+ int left = 0;
+ int right = entryList.size() - 1;
+
+ // Optimization: For the common case in which entries are added in
+ // ascending tag order, check the largest element in the array before
+ // doing a full binary search.
+ if (right >= 0) {
+ int cmp = key.compareTo(entryList.get(right).getKey());
+ if (cmp > 0) {
+ return -(right + 2); // Insert point is after "right".
+ } else if (cmp == 0) {
+ return right;
+ }
+ }
+
+ while (left <= right) {
+ int mid = (left + right) / 2;
+ int cmp = key.compareTo(entryList.get(mid).getKey());
+ if (cmp < 0) {
+ right = mid - 1;
+ } else if (cmp > 0) {
+ left = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ return -(left + 1);
+ }
+
+ /**
+ * Similar to the AbstractMap implementation of {@code keySet()} and
+ * {@code values()}, the entry set is created the first time this method is
+ * called, and returned in response to all subsequent calls.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<Map.Entry<K, V>> entrySet() {
+ if (lazyEntrySet == null) {
+ lazyEntrySet = new EntrySet();
+ }
+ return lazyEntrySet;
+ }
+
+ /**
+ * @throws UnsupportedOperationException if {@link #makeImmutable()} has
+ * has been called.
+ */
+ private void checkMutable() {
+ if (isImmutable) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * @return a {@link SortedMap} to which overflow entries mappings can be
+ * added or removed.
+ * @throws UnsupportedOperationException if {@link #makeImmutable()} has been
+ * called.
+ */
+ @SuppressWarnings("unchecked")
+ private SortedMap<K, V> getOverflowEntriesMutable() {
+ checkMutable();
+ if (overflowEntries.isEmpty() && !(overflowEntries instanceof TreeMap)) {
+ overflowEntries = new TreeMap<K, V>();
+ }
+ return (SortedMap<K, V>) overflowEntries;
+ }
+
+ /**
+ * Lazily creates the entry list. Any code that adds to the list must first
+ * call this method.
+ */
+ private void ensureEntryArrayMutable() {
+ checkMutable();
+ if (entryList.isEmpty() && !(entryList instanceof ArrayList)) {
+ entryList = new ArrayList<Entry>(maxArraySize);
+ }
+ }
+
+ /**
+ * Entry implementation that implements Comparable in order to support
+ * binary search within the entry array. Also checks mutability in
+ * {@link #setValue()}.
+ */
+ private class Entry implements Map.Entry<K, V>, Comparable<Entry> {
+
+ private final K key;
+ private V value;
+
+ Entry(Map.Entry<K, V> copy) {
+ this(copy.getKey(), copy.getValue());
+ }
+
+ Entry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public K getKey() {
+ return key;
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public V getValue() {
+ return value;
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public int compareTo(Entry other) {
+ return getKey().compareTo(other.getKey());
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public V setValue(V newValue) {
+ checkMutable();
+ final V oldValue = this.value;
+ this.value = newValue;
+ return oldValue;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof Map.Entry)) {
+ return false;
+ }
+ @SuppressWarnings("unchecked")
+ Map.Entry<?, ?> other = (Map.Entry<?, ?>) o;
+ return equals(key, other.getKey()) && equals(value, other.getValue());
+ }
+
+ @Override
+ public int hashCode() {
+ return (key == null ? 0 : key.hashCode()) ^
+ (value == null ? 0 : value.hashCode());
+ }
+
+ @Override
+ public String toString() {
+ return key + "=" + value;
+ }
+
+ /** equals() that handles null values. */
+ private boolean equals(Object o1, Object o2) {
+ return o1 == null ? o2 == null : o1.equals(o2);
+ }
+ }
+
+ /**
+ * Stateless view of the entries in the field map.
+ */
+ private class EntrySet extends AbstractSet<Map.Entry<K, V>> {
+
+ @Override
+ public Iterator<Map.Entry<K, V>> iterator() {
+ return new EntryIterator();
+ }
+
+ @Override
+ public int size() {
+ return SmallSortedMap.this.size();
+ }
+
+ /**
+ * Throws a {@link ClassCastException} if o is not of the expected type.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean contains(Object o) {
+ @SuppressWarnings("unchecked")
+ final Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
+ final V existing = get(entry.getKey());
+ final V value = entry.getValue();
+ return existing == value ||
+ (existing != null && existing.equals(value));
+ }
+
+ @Override
+ public boolean add(Map.Entry<K, V> entry) {
+ if (!contains(entry)) {
+ put(entry.getKey(), entry.getValue());
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Throws a {@link ClassCastException} if o is not of the expected type.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean remove(Object o) {
+ @SuppressWarnings("unchecked")
+ final Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
+ if (contains(entry)) {
+ SmallSortedMap.this.remove(entry.getKey());
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void clear() {
+ SmallSortedMap.this.clear();
+ }
+ }
+
+ /**
+ * Iterator implementation that switches from the entry array to the overflow
+ * entries appropriately.
+ */
+ private class EntryIterator implements Iterator<Map.Entry<K, V>> {
+
+ private int pos = -1;
+ private boolean nextCalledBeforeRemove;
+ private Iterator<Map.Entry<K, V>> lazyOverflowIterator;
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean hasNext() {
+ return (pos + 1) < entryList.size() ||
+ getOverflowIterator().hasNext();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public Map.Entry<K, V> next() {
+ nextCalledBeforeRemove = true;
+ // Always increment pos so that we know whether the last returned value
+ // was from the array or from overflow.
+ if (++pos < entryList.size()) {
+ return entryList.get(pos);
+ }
+ return getOverflowIterator().next();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void remove() {
+ if (!nextCalledBeforeRemove) {
+ throw new IllegalStateException("remove() was called before next()");
+ }
+ nextCalledBeforeRemove = false;
+ checkMutable();
+
+ if (pos < entryList.size()) {
+ removeArrayEntryAt(pos--);
+ } else {
+ getOverflowIterator().remove();
+ }
+ }
+
+ /**
+ * It is important to create the overflow iterator only after the array
+ * entries have been iterated over because the overflow entry set changes
+ * when the client calls remove() on the array entries, which invalidates
+ * any existing iterators.
+ */
+ private Iterator<Map.Entry<K, V>> getOverflowIterator() {
+ if (lazyOverflowIterator == null) {
+ lazyOverflowIterator = overflowEntries.entrySet().iterator();
+ }
+ return lazyOverflowIterator;
+ }
+ }
+
+ /**
+ * Helper class that holds immutable instances of an Iterable/Iterator that
+ * we return when the overflow entries is empty. This eliminates the creation
+ * of an Iterator object when there is nothing to iterate over.
+ */
+ 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 Iterable<Object> ITERABLE = new Iterable<Object>() {
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public Iterator<Object> iterator() {
+ return ITERATOR;
+ }
+ };
+
+ @SuppressWarnings("unchecked")
+ static <T> Iterable<T> iterable() {
+ return (Iterable<T>) ITERABLE;
+ }
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/TextFormat.java b/java/src/main/java/com/google/protobuf/TextFormat.java
index cb23f0c..57d0ca6 100644
--- a/java/src/main/java/com/google/protobuf/TextFormat.java
+++ b/java/src/main/java/com/google/protobuf/TextFormat.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -31,63 +31,119 @@
package com.google.protobuf;
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.FieldDescriptor;
import java.io.IOException;
-import java.nio.CharBuffer;
import java.math.BigInteger;
+import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
- * Provide ascii text parsing and formatting support for proto2 instances.
+ * Provide text parsing and formatting support for proto2 instances.
* The implementation largely follows google/protobuf/text_format.cc.
*
* @author wenboz@google.com Wenbo Zhu
* @author kenton@google.com Kenton Varda
*/
public final class TextFormat {
- private TextFormat() {
- }
+ private TextFormat() {}
+
+ private static final Logger logger =
+ Logger.getLogger(TextFormat.class.getName());
+
+ private static final Printer DEFAULT_PRINTER = new Printer();
+ private static final Printer SINGLE_LINE_PRINTER =
+ (new Printer()).setSingleLineMode(true);
+ private static final Printer UNICODE_PRINTER =
+ (new Printer()).setEscapeNonAscii(false);
/**
* Outputs a textual representation of the Protocol Message supplied into
* the parameter output. (This representation is the new version of the
* classic "ProtocolPrinter" output from the original Protocol Buffer system)
*/
- public static void print(final Message message, final Appendable output)
- throws IOException {
- final TextGenerator generator = new TextGenerator(output);
- print(message, generator);
+ public static void print(
+ final MessageOrBuilder message, final Appendable output)
+ throws IOException {
+ DEFAULT_PRINTER.print(message, new TextGenerator(output));
}
/** Outputs a textual representation of {@code fields} to {@code output}. */
public static void print(final UnknownFieldSet fields,
final Appendable output)
throws IOException {
- final TextGenerator generator = new TextGenerator(output);
- printUnknownFields(fields, generator);
+ DEFAULT_PRINTER.printUnknownFields(fields, new TextGenerator(output));
+ }
+
+ /**
+ * Same as {@code print()}, except that non-ASCII characters are not
+ * escaped.
+ */
+ public static void printUnicode(
+ final MessageOrBuilder message, final Appendable output)
+ throws IOException {
+ UNICODE_PRINTER.print(message, new TextGenerator(output));
+ }
+
+ /**
+ * Same as {@code print()}, except that non-ASCII characters are not
+ * escaped.
+ */
+ public static void printUnicode(final UnknownFieldSet fields,
+ final Appendable output)
+ throws IOException {
+ UNICODE_PRINTER.printUnknownFields(fields, new TextGenerator(output));
+ }
+
+ /**
+ * Generates a human readable form of this message, useful for debugging and
+ * other purposes, with no newline characters.
+ */
+ public static String shortDebugString(final MessageOrBuilder message) {
+ try {
+ final StringBuilder sb = new StringBuilder();
+ SINGLE_LINE_PRINTER.print(message, new TextGenerator(sb));
+ // Single line mode currently might have an extra space at the end.
+ return sb.toString().trim();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * Generates a human readable form of the unknown fields, useful for debugging
+ * and other purposes, with no newline characters.
+ */
+ public static String shortDebugString(final UnknownFieldSet fields) {
+ try {
+ final StringBuilder sb = new StringBuilder();
+ SINGLE_LINE_PRINTER.printUnknownFields(fields, new TextGenerator(sb));
+ // Single line mode currently might have an extra space at the end.
+ return sb.toString().trim();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
}
/**
* Like {@code print()}, but writes directly to a {@code String} and
* returns it.
*/
- public static String printToString(final Message message) {
+ public static String printToString(final MessageOrBuilder message) {
try {
final StringBuilder text = new StringBuilder();
print(message, text);
return text.toString();
} catch (IOException e) {
- throw new RuntimeException(
- "Writing to a StringBuilder threw an IOException (should never " +
- "happen).", e);
+ throw new IllegalStateException(e);
}
}
@@ -101,28 +157,43 @@ public final class TextFormat {
print(fields, text);
return text.toString();
} catch (IOException e) {
- throw new RuntimeException(
- "Writing to a StringBuilder threw an IOException (should never " +
- "happen).", e);
+ throw new IllegalStateException(e);
}
}
- private static void print(final Message message,
- final TextGenerator generator)
- throws IOException {
- for (final Map.Entry<FieldDescriptor, Object> field :
- message.getAllFields().entrySet()) {
- printField(field.getKey(), field.getValue(), generator);
+ /**
+ * Same as {@code printToString()}, except that non-ASCII characters
+ * in string type fields are not escaped in backslash+octals.
+ */
+ public static String printToUnicodeString(final MessageOrBuilder message) {
+ try {
+ final StringBuilder text = new StringBuilder();
+ UNICODE_PRINTER.print(message, new TextGenerator(text));
+ return text.toString();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * Same as {@code printToString()}, except that non-ASCII characters
+ * in string type fields are not escaped in backslash+octals.
+ */
+ public static String printToUnicodeString(final UnknownFieldSet fields) {
+ try {
+ final StringBuilder text = new StringBuilder();
+ UNICODE_PRINTER.printUnknownFields(fields, new TextGenerator(text));
+ return text.toString();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
}
- printUnknownFields(message.getUnknownFields(), generator);
}
public static void printField(final FieldDescriptor field,
final Object value,
final Appendable output)
throws IOException {
- final TextGenerator generator = new TextGenerator(output);
- printField(field, value, generator);
+ DEFAULT_PRINTER.printField(field, value, new TextGenerator(output));
}
public static String printFieldToString(final FieldDescriptor field,
@@ -132,173 +203,298 @@ public final class TextFormat {
printField(field, value, text);
return text.toString();
} catch (IOException e) {
- throw new RuntimeException(
- "Writing to a StringBuilder threw an IOException (should never " +
- "happen).", e);
+ throw new IllegalStateException(e);
}
}
- private static void printField(final FieldDescriptor field,
- final Object value,
- final TextGenerator generator)
- throws IOException {
- if (field.isRepeated()) {
- // Repeated field. Print each element.
- for (final Object element : (List) value) {
- printSingleField(field, element, generator);
- }
- } else {
- printSingleField(field, value, generator);
+ /**
+ * Outputs a textual representation of the value of given field value.
+ *
+ * @param field the descriptor of the field
+ * @param value the value of the field
+ * @param output the output to which to append the formatted value
+ * @throws ClassCastException if the value is not appropriate for the
+ * given field descriptor
+ * @throws IOException if there is an exception writing to the output
+ */
+ public static void printFieldValue(final FieldDescriptor field,
+ final Object value,
+ final Appendable output)
+ throws IOException {
+ DEFAULT_PRINTER.printFieldValue(field, value, new TextGenerator(output));
+ }
+
+ /**
+ * Outputs a textual representation of the value of an unknown field.
+ *
+ * @param tag the field's tag number
+ * @param value the value of the field
+ * @param output the output to which to append the formatted value
+ * @throws ClassCastException if the value is not appropriate for the
+ * given field descriptor
+ * @throws IOException if there is an exception writing to the output
+ */
+ public static void printUnknownFieldValue(final int tag,
+ final Object value,
+ final Appendable output)
+ throws IOException {
+ printUnknownFieldValue(tag, value, new TextGenerator(output));
+ }
+
+ private static void printUnknownFieldValue(final int tag,
+ final Object value,
+ final TextGenerator generator)
+ throws IOException {
+ switch (WireFormat.getTagWireType(tag)) {
+ case WireFormat.WIRETYPE_VARINT:
+ generator.print(unsignedToString((Long) value));
+ break;
+ case WireFormat.WIRETYPE_FIXED32:
+ generator.print(
+ String.format((Locale) null, "0x%08x", (Integer) value));
+ break;
+ case WireFormat.WIRETYPE_FIXED64:
+ generator.print(String.format((Locale) null, "0x%016x", (Long) value));
+ break;
+ case WireFormat.WIRETYPE_LENGTH_DELIMITED:
+ generator.print("\"");
+ generator.print(escapeBytes((ByteString) value));
+ generator.print("\"");
+ break;
+ case WireFormat.WIRETYPE_START_GROUP:
+ DEFAULT_PRINTER.printUnknownFields((UnknownFieldSet) value, generator);
+ break;
+ default:
+ throw new IllegalArgumentException("Bad tag: " + tag);
}
}
- private static void printSingleField(final FieldDescriptor field,
- final Object value,
- final TextGenerator generator)
- throws IOException {
- if (field.isExtension()) {
- generator.print("[");
- // We special-case MessageSet elements for compatibility with proto1.
- if (field.getContainingType().getOptions().getMessageSetWireFormat()
- && (field.getType() == FieldDescriptor.Type.MESSAGE)
- && (field.isOptional())
- // object equality
- && (field.getExtensionScope() == field.getMessageType())) {
- generator.print(field.getMessageType().getFullName());
- } else {
- generator.print(field.getFullName());
+ /** Helper class for converting protobufs to text. */
+ private static final class Printer {
+ /** Whether to omit newlines from the output. */
+ boolean singleLineMode = false;
+
+ /** Whether to escape non ASCII characters with backslash and octal. */
+ boolean escapeNonAscii = true;
+
+ private Printer() {}
+
+ /** Setter of singleLineMode */
+ private Printer setSingleLineMode(boolean singleLineMode) {
+ this.singleLineMode = singleLineMode;
+ return this;
+ }
+
+ /** Setter of escapeNonAscii */
+ private Printer setEscapeNonAscii(boolean escapeNonAscii) {
+ this.escapeNonAscii = escapeNonAscii;
+ return this;
+ }
+
+ private void print(
+ final MessageOrBuilder message, final TextGenerator generator)
+ throws IOException {
+ for (Map.Entry<FieldDescriptor, Object> field
+ : message.getAllFields().entrySet()) {
+ printField(field.getKey(), field.getValue(), generator);
}
- generator.print("]");
- } else {
- if (field.getType() == FieldDescriptor.Type.GROUP) {
- // Groups must be serialized with their original capitalization.
- generator.print(field.getMessageType().getName());
+ printUnknownFields(message.getUnknownFields(), generator);
+ }
+
+ private void printField(final FieldDescriptor field, final Object value,
+ final TextGenerator generator) throws IOException {
+ if (field.isRepeated()) {
+ // Repeated field. Print each element.
+ for (Object element : (List<?>) value) {
+ printSingleField(field, element, generator);
+ }
} else {
- generator.print(field.getName());
+ printSingleField(field, value, generator);
}
}
- if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
- generator.print(" {\n");
- generator.indent();
- } else {
- generator.print(": ");
- }
+ private void printSingleField(final FieldDescriptor field,
+ final Object value,
+ final TextGenerator generator)
+ throws IOException {
+ if (field.isExtension()) {
+ generator.print("[");
+ // We special-case MessageSet elements for compatibility with proto1.
+ if (field.getContainingType().getOptions().getMessageSetWireFormat()
+ && (field.getType() == FieldDescriptor.Type.MESSAGE)
+ && (field.isOptional())
+ // object equality
+ && (field.getExtensionScope() == field.getMessageType())) {
+ generator.print(field.getMessageType().getFullName());
+ } else {
+ generator.print(field.getFullName());
+ }
+ generator.print("]");
+ } else {
+ if (field.getType() == FieldDescriptor.Type.GROUP) {
+ // Groups must be serialized with their original capitalization.
+ generator.print(field.getMessageType().getName());
+ } else {
+ generator.print(field.getName());
+ }
+ }
- printFieldValue(field, value, generator);
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (singleLineMode) {
+ generator.print(" { ");
+ } else {
+ generator.print(" {\n");
+ generator.indent();
+ }
+ } else {
+ generator.print(": ");
+ }
+
+ printFieldValue(field, value, generator);
- if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
- generator.outdent();
- generator.print("}");
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (singleLineMode) {
+ generator.print("} ");
+ } else {
+ generator.outdent();
+ generator.print("}\n");
+ }
+ } else {
+ if (singleLineMode) {
+ generator.print(" ");
+ } else {
+ generator.print("\n");
+ }
+ }
}
- generator.print("\n");
- }
- private static void printFieldValue(final FieldDescriptor field,
- final Object value,
- final TextGenerator generator)
- throws IOException {
- switch (field.getType()) {
- case INT32:
- case INT64:
- case SINT32:
- case SINT64:
- case SFIXED32:
- case SFIXED64:
- case FLOAT:
- case DOUBLE:
- case BOOL:
- // Good old toString() does what we want for these types.
- generator.print(value.toString());
- break;
+ private void printFieldValue(final FieldDescriptor field,
+ final Object value,
+ final TextGenerator generator)
+ throws IOException {
+ switch (field.getType()) {
+ case INT32:
+ case SINT32:
+ case SFIXED32:
+ generator.print(((Integer) value).toString());
+ break;
- case UINT32:
- case FIXED32:
- generator.print(unsignedToString((Integer) value));
- break;
+ case INT64:
+ case SINT64:
+ case SFIXED64:
+ generator.print(((Long) value).toString());
+ break;
- case UINT64:
- case FIXED64:
- generator.print(unsignedToString((Long) value));
- break;
+ case BOOL:
+ generator.print(((Boolean) value).toString());
+ break;
- case STRING:
- generator.print("\"");
- generator.print(escapeText((String) value));
- generator.print("\"");
- break;
+ case FLOAT:
+ generator.print(((Float) value).toString());
+ break;
- case BYTES:
- generator.print("\"");
- generator.print(escapeBytes((ByteString) value));
- generator.print("\"");
- break;
+ case DOUBLE:
+ generator.print(((Double) value).toString());
+ break;
- case ENUM:
- generator.print(((EnumValueDescriptor) value).getName());
- break;
+ case UINT32:
+ case FIXED32:
+ generator.print(unsignedToString((Integer) value));
+ break;
- case MESSAGE:
- case GROUP:
- print((Message) value, generator);
- break;
- }
- }
+ case UINT64:
+ case FIXED64:
+ generator.print(unsignedToString((Long) value));
+ break;
- private static void printUnknownFields(final UnknownFieldSet unknownFields,
- final TextGenerator generator)
- throws IOException {
- for (final Map.Entry<Integer, UnknownFieldSet.Field> entry :
- unknownFields.asMap().entrySet()) {
- final String prefix = entry.getKey().toString() + ": ";
- final UnknownFieldSet.Field field = entry.getValue();
+ case STRING:
+ generator.print("\"");
+ generator.print(escapeNonAscii ?
+ escapeText((String) value) :
+ escapeDoubleQuotesAndBackslashes((String) value));
+ generator.print("\"");
+ break;
- for (final long value : field.getVarintList()) {
- generator.print(entry.getKey().toString());
- generator.print(": ");
- generator.print(unsignedToString(value));
- generator.print("\n");
+ case BYTES:
+ generator.print("\"");
+ if (value instanceof ByteString) {
+ generator.print(escapeBytes((ByteString) value));
+ } else {
+ generator.print(escapeBytes((byte[]) value));
+ }
+ generator.print("\"");
+ break;
+
+ case ENUM:
+ generator.print(((EnumValueDescriptor) value).getName());
+ break;
+
+ case MESSAGE:
+ case GROUP:
+ print((Message) value, generator);
+ break;
}
- for (final int value : field.getFixed32List()) {
- generator.print(entry.getKey().toString());
- generator.print(": ");
- generator.print(String.format((Locale) null, "0x%08x", value));
- generator.print("\n");
+ }
+
+ private void printUnknownFields(final UnknownFieldSet unknownFields,
+ final TextGenerator generator)
+ throws IOException {
+ for (Map.Entry<Integer, UnknownFieldSet.Field> entry :
+ unknownFields.asMap().entrySet()) {
+ final int number = entry.getKey();
+ final UnknownFieldSet.Field field = entry.getValue();
+ printUnknownField(number, WireFormat.WIRETYPE_VARINT,
+ field.getVarintList(), generator);
+ printUnknownField(number, WireFormat.WIRETYPE_FIXED32,
+ field.getFixed32List(), generator);
+ printUnknownField(number, WireFormat.WIRETYPE_FIXED64,
+ field.getFixed64List(), generator);
+ printUnknownField(number, WireFormat.WIRETYPE_LENGTH_DELIMITED,
+ field.getLengthDelimitedList(), generator);
+ for (final UnknownFieldSet value : field.getGroupList()) {
+ generator.print(entry.getKey().toString());
+ if (singleLineMode) {
+ generator.print(" { ");
+ } else {
+ generator.print(" {\n");
+ generator.indent();
+ }
+ printUnknownFields(value, generator);
+ if (singleLineMode) {
+ generator.print("} ");
+ } else {
+ generator.outdent();
+ generator.print("}\n");
+ }
+ }
}
- for (final long value : field.getFixed64List()) {
- generator.print(entry.getKey().toString());
+ }
+
+ private void printUnknownField(final int number,
+ final int wireType,
+ final List<?> values,
+ final TextGenerator generator)
+ throws IOException {
+ for (final Object value : values) {
+ generator.print(String.valueOf(number));
generator.print(": ");
- generator.print(String.format((Locale) null, "0x%016x", value));
- generator.print("\n");
- }
- for (final ByteString value : field.getLengthDelimitedList()) {
- generator.print(entry.getKey().toString());
- generator.print(": \"");
- generator.print(escapeBytes(value));
- generator.print("\"\n");
- }
- for (final UnknownFieldSet value : field.getGroupList()) {
- generator.print(entry.getKey().toString());
- generator.print(" {\n");
- generator.indent();
- printUnknownFields(value, generator);
- generator.outdent();
- generator.print("}\n");
+ printUnknownFieldValue(wireType, value, generator);
+ generator.print(singleLineMode ? " " : "\n");
}
}
}
/** Convert an unsigned 32-bit integer to a string. */
- private static String unsignedToString(final int value) {
+ public static String unsignedToString(final int value) {
if (value >= 0) {
return Integer.toString(value);
} else {
- return Long.toString(((long) value) & 0x00000000FFFFFFFFL);
+ return Long.toString(value & 0x00000000FFFFFFFFL);
}
}
/** Convert an unsigned 64-bit integer to a string. */
- private static String unsignedToString(final long value) {
+ public static String unsignedToString(final long value) {
if (value >= 0) {
return Long.toString(value);
} else {
@@ -313,9 +509,9 @@ public final class TextFormat {
* An inner class for writing text to the output stream.
*/
private static final class TextGenerator {
- private Appendable output;
- private boolean atStartOfLine = true;
+ private final Appendable output;
private final StringBuilder indent = new StringBuilder();
+ private boolean atStartOfLine = true;
private TextGenerator(final Appendable output) {
this.output = output;
@@ -352,17 +548,16 @@ public final class TextFormat {
for (int i = 0; i < size; i++) {
if (text.charAt(i) == '\n') {
- write(text.subSequence(pos, size), i - pos + 1);
+ write(text.subSequence(pos, i + 1));
pos = i + 1;
atStartOfLine = true;
}
}
- write(text.subSequence(pos, size), size - pos);
+ write(text.subSequence(pos, size));
}
- private void write(final CharSequence data, final int size)
- throws IOException {
- if (size == 0) {
+ private void write(final CharSequence data) throws IOException {
+ if (data.length() == 0) {
return;
}
if (atStartOfLine) {
@@ -421,7 +616,7 @@ public final class TextFormat {
private int previousLine = 0;
private int previousColumn = 0;
- // We use possesive quantifiers (*+ and ++) because otherwise the Java
+ // We use possessive quantifiers (*+ and ++) because otherwise the Java
// regex matcher has stack overflows on large inputs.
private static final Pattern WHITESPACE =
Pattern.compile("(\\s|(#.*$))++", Pattern.MULTILINE);
@@ -539,6 +734,14 @@ public final class TextFormat {
}
/**
+ * Returns {@code true} if the current token's text is equal to that
+ * specified.
+ */
+ public boolean lookingAt(String text) {
+ return currentToken.equals(text);
+ }
+
+ /**
* If the next token is an identifier, consume it and return its value.
* Otherwise, throw a {@link ParseException}.
*/
@@ -551,7 +754,8 @@ public final class TextFormat {
(c == '_') || (c == '.')) {
// OK
} else {
- throw parseException("Expected identifier.");
+ throw parseException(
+ "Expected identifier. Found '" + currentToken + "'");
}
}
@@ -561,6 +765,19 @@ public final class TextFormat {
}
/**
+ * If the next token is an identifier, consume it and return {@code true}.
+ * Otherwise, return {@code false} without doing anything.
+ */
+ public boolean tryConsumeIdentifier() {
+ try {
+ consumeIdentifier();
+ return true;
+ } catch (ParseException e) {
+ return false;
+ }
+ }
+
+ /**
* If the next token is a 32-bit signed integer, consume it and return its
* value. Otherwise, throw a {@link ParseException}.
*/
@@ -603,6 +820,19 @@ public final class TextFormat {
}
/**
+ * If the next token is a 64-bit signed integer, consume it and return
+ * {@code true}. Otherwise, return {@code false} without doing anything.
+ */
+ public boolean tryConsumeInt64() {
+ try {
+ consumeInt64();
+ return true;
+ } catch (ParseException e) {
+ return false;
+ }
+ }
+
+ /**
* If the next token is a 64-bit unsigned integer, consume it and return its
* value. Otherwise, throw a {@link ParseException}.
*/
@@ -617,6 +847,19 @@ public final class TextFormat {
}
/**
+ * If the next token is a 64-bit unsigned integer, consume it and return
+ * {@code true}. Otherwise, return {@code false} without doing anything.
+ */
+ public boolean tryConsumeUInt64() {
+ try {
+ consumeUInt64();
+ return true;
+ } catch (ParseException e) {
+ return false;
+ }
+ }
+
+ /**
* If the next token is a double, consume it and return its value.
* Otherwise, throw a {@link ParseException}.
*/
@@ -642,6 +885,19 @@ public final class TextFormat {
}
/**
+ * If the next token is a double, consume it and return {@code true}.
+ * Otherwise, return {@code false} without doing anything.
+ */
+ public boolean tryConsumeDouble() {
+ try {
+ consumeDouble();
+ return true;
+ } catch (ParseException e) {
+ return false;
+ }
+ }
+
+ /**
* If the next token is a float, consume it and return its value.
* Otherwise, throw a {@link ParseException}.
*/
@@ -667,14 +923,31 @@ public final class TextFormat {
}
/**
+ * If the next token is a float, consume it and return {@code true}.
+ * Otherwise, return {@code false} without doing anything.
+ */
+ public boolean tryConsumeFloat() {
+ try {
+ consumeFloat();
+ return true;
+ } catch (ParseException e) {
+ return false;
+ }
+ }
+
+ /**
* If the next token is a boolean, consume it and return its value.
* Otherwise, throw a {@link ParseException}.
*/
public boolean consumeBoolean() throws ParseException {
- if (currentToken.equals("true")) {
+ if (currentToken.equals("true") ||
+ currentToken.equals("t") ||
+ currentToken.equals("1")) {
nextToken();
return true;
- } else if (currentToken.equals("false")) {
+ } else if (currentToken.equals("false") ||
+ currentToken.equals("f") ||
+ currentToken.equals("0")) {
nextToken();
return false;
} else {
@@ -691,6 +964,19 @@ public final class TextFormat {
}
/**
+ * If the next token is a string, consume it and return true. Otherwise,
+ * return false.
+ */
+ public boolean tryConsumeString() {
+ try {
+ consumeString();
+ return true;
+ } catch (ParseException e) {
+ return false;
+ }
+ }
+
+ /**
* If the next token is a string, consume it, unescape it as a
* {@link ByteString}, and return it. Otherwise, throw a
* {@link ParseException}.
@@ -710,7 +996,8 @@ public final class TextFormat {
* multiple adjacent tokens which are automatically concatenated, like in
* C or Python.
*/
- private void consumeByteString(List<ByteString> list) throws ParseException {
+ private void consumeByteString(List<ByteString> list)
+ throws ParseException {
final char quote = currentToken.length() > 0 ? currentToken.charAt(0)
: '\0';
if (quote != '\"' && quote != '\'') {
@@ -740,7 +1027,7 @@ public final class TextFormat {
public ParseException parseException(final String description) {
// Note: People generally prefer one-based line and column numbers.
return new ParseException(
- (line + 1) + ":" + (column + 1) + ": " + description);
+ line + 1, column + 1, description);
}
/**
@@ -751,7 +1038,7 @@ public final class TextFormat {
final String description) {
// Note: People generally prefer one-based line and column numbers.
return new ParseException(
- (previousLine + 1) + ":" + (previousColumn + 1) + ": " + description);
+ previousLine + 1, previousColumn + 1, description);
}
/**
@@ -776,11 +1063,58 @@ public final class TextFormat {
public static class ParseException extends IOException {
private static final long serialVersionUID = 3196188060225107702L;
+ private final int line;
+ private final int column;
+
+ /** Create a new instance, with -1 as the line and column numbers. */
public ParseException(final String message) {
- super(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.
+ */
+ public ParseException(final int line, final int column,
+ final String message) {
+ super(Integer.toString(line) + ":" + column + ": " + message);
+ this.line = line;
+ this.column = column;
+ }
+
+ /**
+ * Return the line where the parse exception occurred, or -1 when
+ * none is provided. The value is specified as 1-offset, so the first
+ * line is line 1.
+ */
+ public int getLine() {
+ return line;
+ }
+
+ /**
+ * Return the column where the parse exception occurred, or -1 when
+ * none is provided. The value is specified as 1-offset, so the first
+ * line is line 1.
+ */
+ public int getColumn() {
+ return column;
}
}
+ private static final Parser PARSER = Parser.newBuilder().build();
+
+ /**
+ * Return a {@link Parser} instance which can parse text-format
+ * messages. The returned instance is thread-safe.
+ */
+ public static Parser getParser() {
+ return PARSER;
+ }
+
/**
* Parse a text-format message from {@code input} and merge the contents
* into {@code builder}.
@@ -788,7 +1122,7 @@ public final class TextFormat {
public static void merge(final Readable input,
final Message.Builder builder)
throws IOException {
- merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+ PARSER.merge(input, builder);
}
/**
@@ -798,7 +1132,7 @@ public final class TextFormat {
public static void merge(final CharSequence input,
final Message.Builder builder)
throws ParseException {
- merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+ PARSER.merge(input, builder);
}
/**
@@ -810,35 +1144,9 @@ public final class TextFormat {
final ExtensionRegistry extensionRegistry,
final Message.Builder builder)
throws IOException {
- // Read the entire input to a String then parse that.
-
- // If StreamTokenizer were not quite so crippled, or if there were a kind
- // of Reader that could read in chunks that match some particular regex,
- // or if we wanted to write a custom Reader to tokenize our stream, then
- // we would not have to read to one big String. Alas, none of these is
- // the case. Oh well.
-
- merge(toStringBuilder(input), extensionRegistry, builder);
+ PARSER.merge(input, extensionRegistry, builder);
}
- private static final int BUFFER_SIZE = 4096;
-
- // TODO(chrisn): See if working around java.io.Reader#read(CharBuffer)
- // overhead is worthwhile
- private static StringBuilder toStringBuilder(final Readable input)
- throws IOException {
- final StringBuilder text = new StringBuilder();
- final CharBuffer buffer = CharBuffer.allocate(BUFFER_SIZE);
- while (true) {
- final int n = input.read(buffer);
- if (n == -1) {
- break;
- }
- buffer.flip();
- text.append(buffer, 0, n);
- }
- return text;
- }
/**
* Parse a text-format message from {@code input} and merge the contents
@@ -849,187 +1157,466 @@ public final class TextFormat {
final ExtensionRegistry extensionRegistry,
final Message.Builder builder)
throws ParseException {
- final Tokenizer tokenizer = new Tokenizer(input);
-
- while (!tokenizer.atEnd()) {
- mergeField(tokenizer, extensionRegistry, builder);
- }
+ PARSER.merge(input, extensionRegistry, builder);
}
+
/**
- * Parse a single field from {@code tokenizer} and merge it into
- * {@code builder}.
+ * Parser for text-format proto2 instances. This class is thread-safe.
+ * The implementation largely follows google/protobuf/text_format.cc.
+ *
+ * <p>Use {@link TextFormat#getParser()} to obtain the default parser, or
+ * {@link Builder} to control the parser behavior.
*/
- private static void mergeField(final Tokenizer tokenizer,
- final ExtensionRegistry extensionRegistry,
- final Message.Builder builder)
- throws ParseException {
- FieldDescriptor field;
- final Descriptor type = builder.getDescriptorForType();
- ExtensionRegistry.ExtensionInfo extension = null;
+ public static class Parser {
+ /**
+ * Determines if repeated values for non-repeated fields and
+ * oneofs are permitted. For example, given required/optional field "foo"
+ * and a oneof containing "baz" and "qux":
+ * <li>
+ * <ul>"foo: 1 foo: 2"
+ * <ul>"baz: 1 qux: 2"
+ * <ul>merging "foo: 2" into a proto in which foo is already set, or
+ * <ul>merging "qux: 2" into a proto in which baz is already set.
+ * </li>
+ */
+ public enum SingularOverwritePolicy {
+ /** The last value is retained. */
+ ALLOW_SINGULAR_OVERWRITES,
+ /** An error is issued. */
+ FORBID_SINGULAR_OVERWRITES
+ }
- if (tokenizer.tryConsume("[")) {
- // An extension.
- final StringBuilder name =
- new StringBuilder(tokenizer.consumeIdentifier());
- while (tokenizer.tryConsume(".")) {
- name.append('.');
- name.append(tokenizer.consumeIdentifier());
- }
+ private final boolean allowUnknownFields;
+ private final SingularOverwritePolicy singularOverwritePolicy;
+
+ private Parser(boolean allowUnknownFields,
+ SingularOverwritePolicy singularOverwritePolicy) {
+ this.allowUnknownFields = allowUnknownFields;
+ this.singularOverwritePolicy = singularOverwritePolicy;
+ }
+
+ /**
+ * Returns a new instance of {@link Builder}.
+ */
+ public static Builder newBuilder() {
+ return new Builder();
+ }
- extension = extensionRegistry.findExtensionByName(name.toString());
+ /**
+ * Builder that can be used to obtain new instances of {@link Parser}.
+ */
+ public static class Builder {
+ private boolean allowUnknownFields = false;
+ private SingularOverwritePolicy singularOverwritePolicy =
+ SingularOverwritePolicy.ALLOW_SINGULAR_OVERWRITES;
+
+ /**
+ * Sets parser behavior when a non-repeated field appears more than once.
+ */
+ public Builder setSingularOverwritePolicy(SingularOverwritePolicy p) {
+ this.singularOverwritePolicy = p;
+ return this;
+ }
- if (extension == null) {
- throw tokenizer.parseExceptionPreviousToken(
- "Extension \"" + name + "\" not found in the ExtensionRegistry.");
- } else if (extension.descriptor.getContainingType() != type) {
- throw tokenizer.parseExceptionPreviousToken(
- "Extension \"" + name + "\" does not extend message type \"" +
- type.getFullName() + "\".");
+ public Parser build() {
+ return new Parser(allowUnknownFields, singularOverwritePolicy);
}
+ }
- tokenizer.consume("]");
+ /**
+ * Parse a text-format message from {@code input} and merge the contents
+ * into {@code builder}.
+ */
+ public void merge(final Readable input,
+ final Message.Builder builder)
+ throws IOException {
+ merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+ }
- field = extension.descriptor;
- } else {
- final String name = tokenizer.consumeIdentifier();
- field = type.findFieldByName(name);
+ /**
+ * Parse a text-format message from {@code input} and merge the contents
+ * into {@code builder}.
+ */
+ public void merge(final CharSequence input,
+ final Message.Builder builder)
+ throws ParseException {
+ merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+ }
- // 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 (field == null) {
- // Explicitly specify US locale so that this code does not break when
- // executing in Turkey.
- final String lowerName = name.toLowerCase(Locale.US);
- field = type.findFieldByName(lowerName);
- // If the case-insensitive match worked but the field is NOT a group,
- if (field != null && field.getType() != FieldDescriptor.Type.GROUP) {
- field = null;
+ /**
+ * Parse a text-format message from {@code input} and merge the contents
+ * into {@code builder}. Extensions will be recognized if they are
+ * registered in {@code extensionRegistry}.
+ */
+ public void merge(final Readable input,
+ final ExtensionRegistry extensionRegistry,
+ final Message.Builder builder)
+ throws IOException {
+ // Read the entire input to a String then parse that.
+
+ // If StreamTokenizer were not quite so crippled, or if there were a kind
+ // of Reader that could read in chunks that match some particular regex,
+ // or if we wanted to write a custom Reader to tokenize our stream, then
+ // we would not have to read to one big String. Alas, none of these is
+ // the case. Oh well.
+
+ merge(toStringBuilder(input), extensionRegistry, builder);
+ }
+
+
+ private static final int BUFFER_SIZE = 4096;
+
+ // TODO(chrisn): See if working around java.io.Reader#read(CharBuffer)
+ // overhead is worthwhile
+ private static StringBuilder toStringBuilder(final Readable input)
+ throws IOException {
+ final StringBuilder text = new StringBuilder();
+ final CharBuffer buffer = CharBuffer.allocate(BUFFER_SIZE);
+ while (true) {
+ final int n = input.read(buffer);
+ if (n == -1) {
+ break;
}
+ buffer.flip();
+ text.append(buffer, 0, n);
}
- // Again, special-case group names as described above.
- if (field != null && field.getType() == FieldDescriptor.Type.GROUP &&
- !field.getMessageType().getName().equals(name)) {
- field = null;
- }
+ return text;
+ }
- if (field == null) {
- throw tokenizer.parseExceptionPreviousToken(
- "Message type \"" + type.getFullName() +
- "\" has no field named \"" + name + "\".");
+ /**
+ * Parse a text-format message from {@code input} and merge the contents
+ * into {@code builder}. Extensions will be recognized if they are
+ * registered in {@code extensionRegistry}.
+ */
+ public void merge(final CharSequence input,
+ final ExtensionRegistry extensionRegistry,
+ final Message.Builder builder)
+ throws ParseException {
+ final Tokenizer tokenizer = new Tokenizer(input);
+ MessageReflection.BuilderAdapter target =
+ new MessageReflection.BuilderAdapter(builder);
+
+ while (!tokenizer.atEnd()) {
+ mergeField(tokenizer, extensionRegistry, target);
}
}
- Object value = null;
- if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
- tokenizer.tryConsume(":"); // optional
+ /**
+ * 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)
+ throws ParseException {
+ FieldDescriptor field = null;
+ final Descriptor type = target.getDescriptorForType();
+ ExtensionRegistry.ExtensionInfo extension = null;
+
+ if (tokenizer.tryConsume("[")) {
+ // An extension.
+ final StringBuilder name =
+ new StringBuilder(tokenizer.consumeIdentifier());
+ while (tokenizer.tryConsume(".")) {
+ name.append('.');
+ name.append(tokenizer.consumeIdentifier());
+ }
- final String endToken;
- if (tokenizer.tryConsume("<")) {
- endToken = ">";
- } else {
- tokenizer.consume("{");
- endToken = "}";
- }
+ extension = target.findExtensionByName(
+ 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.");
+ }
+ } else {
+ if (extension.descriptor.getContainingType() != type) {
+ throw tokenizer.parseExceptionPreviousToken(
+ "Extension \"" + name + "\" does not extend message type \"" +
+ type.getFullName() + "\".");
+ }
+ field = extension.descriptor;
+ }
- final Message.Builder subBuilder;
- if (extension == null) {
- subBuilder = builder.newBuilderForField(field);
+ tokenizer.consume("]");
} else {
- subBuilder = extension.defaultInstance.newBuilderForType();
- }
+ final String name = tokenizer.consumeIdentifier();
+ field = type.findFieldByName(name);
+
+ // 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 (field == null) {
+ // Explicitly specify US locale so that this code does not break when
+ // executing in Turkey.
+ final String lowerName = name.toLowerCase(Locale.US);
+ field = type.findFieldByName(lowerName);
+ // If the case-insensitive match worked but the field is NOT a group,
+ if (field != null && field.getType() != FieldDescriptor.Type.GROUP) {
+ field = null;
+ }
+ }
+ // Again, special-case group names as described above.
+ if (field != null && field.getType() == FieldDescriptor.Type.GROUP &&
+ !field.getMessageType().getName().equals(name)) {
+ field = null;
+ }
- while (!tokenizer.tryConsume(endToken)) {
- if (tokenizer.atEnd()) {
- throw tokenizer.parseException(
- "Expected \"" + endToken + "\".");
+ 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 + "\".");
+ }
}
- mergeField(tokenizer, extensionRegistry, subBuilder);
}
- value = subBuilder.build();
-
- } else {
- tokenizer.consume(":");
+ // Skips unknown fields.
+ if (field == null) {
+ // 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 begining 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(":") && !tokenizer.lookingAt("{") &&
+ !tokenizer.lookingAt("<")) {
+ skipFieldValue(tokenizer);
+ } else {
+ skipFieldMessage(tokenizer);
+ }
+ return;
+ }
- switch (field.getType()) {
- case INT32:
- case SINT32:
- case SFIXED32:
- value = tokenizer.consumeInt32();
- break;
+ // Handle potential ':'.
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ tokenizer.tryConsume(":"); // optional
+ } else {
+ tokenizer.consume(":"); // required
+ }
+ // 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);
+ if (tokenizer.tryConsume("]")) {
+ // End of list.
+ break;
+ }
+ tokenizer.consume(",");
+ }
+ } else {
+ consumeFieldValue(tokenizer, extensionRegistry, target, field, extension);
+ }
+ }
- case INT64:
- case SINT64:
- case SFIXED64:
- value = tokenizer.consumeInt64();
- break;
+ /**
+ * Parse a single field value from {@code tokenizer} and merge it into
+ * {@code builder}.
+ */
+ private void consumeFieldValue(
+ final Tokenizer tokenizer,
+ final ExtensionRegistry extensionRegistry,
+ final MessageReflection.MergeTarget target,
+ final FieldDescriptor field,
+ final ExtensionRegistry.ExtensionInfo extension)
+ throws ParseException {
+ Object value = null;
+
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ final String endToken;
+ if (tokenizer.tryConsume("<")) {
+ endToken = ">";
+ } else {
+ tokenizer.consume("{");
+ endToken = "}";
+ }
- case UINT32:
- case FIXED32:
- value = tokenizer.consumeUInt32();
- break;
+ final MessageReflection.MergeTarget subField;
+ subField = target.newMergeTargetForField(field,
+ (extension == null) ? null : extension.defaultInstance);
- case UINT64:
- case FIXED64:
- value = tokenizer.consumeUInt64();
- break;
+ while (!tokenizer.tryConsume(endToken)) {
+ if (tokenizer.atEnd()) {
+ throw tokenizer.parseException(
+ "Expected \"" + endToken + "\".");
+ }
+ mergeField(tokenizer, extensionRegistry, subField);
+ }
- case FLOAT:
- value = tokenizer.consumeFloat();
- break;
+ value = subField.finish();
- case DOUBLE:
- value = tokenizer.consumeDouble();
- break;
+ } else {
+ switch (field.getType()) {
+ case INT32:
+ case SINT32:
+ case SFIXED32:
+ value = tokenizer.consumeInt32();
+ break;
+
+ case INT64:
+ case SINT64:
+ case SFIXED64:
+ value = tokenizer.consumeInt64();
+ break;
+
+ case UINT32:
+ case FIXED32:
+ value = tokenizer.consumeUInt32();
+ break;
+
+ case UINT64:
+ case FIXED64:
+ value = tokenizer.consumeUInt64();
+ break;
+
+ case FLOAT:
+ value = tokenizer.consumeFloat();
+ break;
+
+ case DOUBLE:
+ value = tokenizer.consumeDouble();
+ break;
+
+ case BOOL:
+ value = tokenizer.consumeBoolean();
+ break;
+
+ case STRING:
+ value = tokenizer.consumeString();
+ break;
+
+ case BYTES:
+ value = tokenizer.consumeByteString();
+ break;
+
+ case ENUM:
+ final EnumDescriptor enumType = field.getEnumType();
+
+ if (tokenizer.lookingAtInteger()) {
+ final int number = tokenizer.consumeInt32();
+ value = enumType.findValueByNumber(number);
+ if (value == null) {
+ throw tokenizer.parseExceptionPreviousToken(
+ "Enum type \"" + enumType.getFullName() +
+ "\" has no value with number " + number + '.');
+ }
+ } else {
+ final String id = tokenizer.consumeIdentifier();
+ value = enumType.findValueByName(id);
+ if (value == null) {
+ throw tokenizer.parseExceptionPreviousToken(
+ "Enum type \"" + enumType.getFullName() +
+ "\" has no value named \"" + id + "\".");
+ }
+ }
- case BOOL:
- value = tokenizer.consumeBoolean();
- break;
+ break;
- case STRING:
- value = tokenizer.consumeString();
- break;
+ case MESSAGE:
+ case GROUP:
+ throw new RuntimeException("Can't get here.");
+ }
+ }
- case BYTES:
- value = tokenizer.consumeByteString();
- break;
+ if (field.isRepeated()) {
+ target.addRepeatedField(field, value);
+ } else if ((singularOverwritePolicy
+ == SingularOverwritePolicy.FORBID_SINGULAR_OVERWRITES)
+ && target.hasField(field)) {
+ throw tokenizer.parseExceptionPreviousToken("Non-repeated field \""
+ + field.getFullName() + "\" cannot be overwritten.");
+ } else if ((singularOverwritePolicy
+ == SingularOverwritePolicy.FORBID_SINGULAR_OVERWRITES)
+ && field.getContainingOneof() != null
+ && target.hasOneof(field.getContainingOneof())) {
+ Descriptors.OneofDescriptor oneof = field.getContainingOneof();
+ throw tokenizer.parseExceptionPreviousToken("Field \""
+ + field.getFullName() + "\" is specified along with field \""
+ + target.getOneofFieldDescriptor(oneof).getFullName()
+ + "\", another member of oneof \"" + oneof.getName() + "\".");
+ } else {
+ target.setField(field, value);
+ }
+ }
- case ENUM:
- final EnumDescriptor enumType = field.getEnumType();
-
- if (tokenizer.lookingAtInteger()) {
- final int number = tokenizer.consumeInt32();
- value = enumType.findValueByNumber(number);
- if (value == null) {
- throw tokenizer.parseExceptionPreviousToken(
- "Enum type \"" + enumType.getFullName() +
- "\" has no value with number " + number + '.');
- }
- } else {
- final String id = tokenizer.consumeIdentifier();
- value = enumType.findValueByName(id);
- if (value == null) {
- throw tokenizer.parseExceptionPreviousToken(
- "Enum type \"" + enumType.getFullName() +
- "\" has no value named \"" + id + "\".");
- }
- }
+ /**
+ * Skips the next field including the field's name and value.
+ */
+ private void skipField(Tokenizer tokenizer) throws ParseException {
+ if (tokenizer.tryConsume("[")) {
+ // Extension name.
+ do {
+ tokenizer.consumeIdentifier();
+ } while (tokenizer.tryConsume("."));
+ tokenizer.consume("]");
+ } else {
+ tokenizer.consumeIdentifier();
+ }
- break;
+ // 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 begining 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(":") && !tokenizer.lookingAt("<") &&
+ !tokenizer.lookingAt("{")) {
+ skipFieldValue(tokenizer);
+ } else {
+ skipFieldMessage(tokenizer);
+ }
+ // For historical reasons, fields may optionally be separated by commas or
+ // semicolons.
+ if (!tokenizer.tryConsume(";")) {
+ tokenizer.tryConsume(",");
+ }
+ }
- case MESSAGE:
- case GROUP:
- throw new RuntimeException("Can't get here.");
+ /**
+ * Skips the whole body of a message including the beginning delimeter and
+ * the ending delimeter.
+ */
+ private void skipFieldMessage(Tokenizer tokenizer) throws ParseException {
+ final String delimiter;
+ if (tokenizer.tryConsume("<")) {
+ delimiter = ">";
+ } else {
+ tokenizer.consume("{");
+ delimiter = "}";
}
+ while (!tokenizer.lookingAt(">") && !tokenizer.lookingAt("}")) {
+ skipField(tokenizer);
+ }
+ tokenizer.consume(delimiter);
}
- if (field.isRepeated()) {
- builder.addRepeatedField(field, value);
- } else {
- builder.setField(field, value);
+ /**
+ * Skips a field value.
+ */
+ private void skipFieldValue(Tokenizer tokenizer) throws ParseException {
+ if (tokenizer.tryConsumeString()) {
+ while (tokenizer.tryConsumeString()) {}
+ return;
+ }
+ if (!tokenizer.tryConsumeIdentifier() && // includes enum & boolean
+ !tokenizer.tryConsumeInt64() && // includes int32
+ !tokenizer.tryConsumeUInt64() && // includes uint32
+ !tokenizer.tryConsumeDouble() &&
+ !tokenizer.tryConsumeFloat()) {
+ throw tokenizer.parseException(
+ "Invalid field value: " + tokenizer.currentToken);
+ }
}
}
@@ -1039,6 +1626,11 @@ 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
@@ -1047,7 +1639,7 @@ public final class TextFormat {
* which no defined short-hand escape sequence is defined will be escaped
* using 3-digit octal sequences.
*/
- static String escapeBytes(final ByteString input) {
+ private 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);
@@ -1064,6 +1656,9 @@ public final class TextFormat {
case '\'': builder.append("\\\'"); break;
case '"' : builder.append("\\\""); break;
default:
+ // Note: Bytes with the high-order bit set should be escaped. Since
+ // bytes are signed, such bytes will compare less than 0x20, hence
+ // the following line is correct.
if (b >= 0x20) {
builder.append((char) b);
} else {
@@ -1079,31 +1674,74 @@ public final class TextFormat {
}
/**
+ * 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() {
+ public int size() {
+ return input.size();
+ }
+ 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() {
+ public int size() {
+ return input.length;
+ }
+ public byte byteAt(int offset) {
+ return input[offset];
+ }
+ });
+ }
+
+ /**
* Un-escape a byte sequence as escaped using
* {@link #escapeBytes(ByteString)}. Two-digit hex escapes (starting with
* "\x") are also recognized.
*/
- static ByteString unescapeBytes(final CharSequence input)
+ static ByteString unescapeBytes(final CharSequence charString)
throws InvalidEscapeSequenceException {
- final byte[] result = new byte[input.length()];
+ // First convert the Java character sequence to UTF-8 bytes.
+ ByteString input = ByteString.copyFromUtf8(charString.toString());
+ // Then unescape certain byte sequences introduced by ASCII '\\'. The valid
+ // escapes can all be expressed with ASCII characters, so it is safe to
+ // operate on bytes here.
+ //
+ // Unescaping the input byte array will result in a byte sequence that's no
+ // longer than the input. That's because each escape sequence is between
+ // two and four bytes long and stands for a single byte.
+ final byte[] result = new byte[input.size()];
int pos = 0;
- for (int i = 0; i < input.length(); i++) {
- char c = input.charAt(i);
+ for (int i = 0; i < input.size(); i++) {
+ byte c = input.byteAt(i);
if (c == '\\') {
- if (i + 1 < input.length()) {
+ if (i + 1 < input.size()) {
++i;
- c = input.charAt(i);
+ c = input.byteAt(i);
if (isOctal(c)) {
// Octal escape.
int code = digitValue(c);
- if (i + 1 < input.length() && isOctal(input.charAt(i + 1))) {
+ if (i + 1 < input.size() && isOctal(input.byteAt(i + 1))) {
++i;
- code = code * 8 + digitValue(input.charAt(i));
+ code = code * 8 + digitValue(input.byteAt(i));
}
- if (i + 1 < input.length() && isOctal(input.charAt(i + 1))) {
+ if (i + 1 < input.size() && isOctal(input.byteAt(i + 1))) {
++i;
- code = code * 8 + digitValue(input.charAt(i));
+ code = code * 8 + digitValue(input.byteAt(i));
}
+ // TODO: Check that 0 <= code && code <= 0xFF.
result[pos++] = (byte)code;
} else {
switch (c) {
@@ -1121,31 +1759,31 @@ public final class TextFormat {
case 'x':
// hex escape
int code = 0;
- if (i + 1 < input.length() && isHex(input.charAt(i + 1))) {
+ if (i + 1 < input.size() && isHex(input.byteAt(i + 1))) {
++i;
- code = digitValue(input.charAt(i));
+ code = digitValue(input.byteAt(i));
} else {
throw new InvalidEscapeSequenceException(
- "Invalid escape sequence: '\\x' with no digits");
+ "Invalid escape sequence: '\\x' with no digits");
}
- if (i + 1 < input.length() && isHex(input.charAt(i + 1))) {
+ if (i + 1 < input.size() && isHex(input.byteAt(i + 1))) {
++i;
- code = code * 16 + digitValue(input.charAt(i));
+ code = code * 16 + digitValue(input.byteAt(i));
}
result[pos++] = (byte)code;
break;
default:
throw new InvalidEscapeSequenceException(
- "Invalid escape sequence: '\\" + c + '\'');
+ "Invalid escape sequence: '\\" + (char)c + '\'');
}
}
} else {
throw new InvalidEscapeSequenceException(
- "Invalid escape sequence: '\\' at end of string.");
+ "Invalid escape sequence: '\\' at end of string.");
}
} else {
- result[pos++] = (byte)c;
+ result[pos++] = c;
}
}
@@ -1174,6 +1812,13 @@ 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("\"", "\\\"");
+ }
+
+ /**
* Un-escape a text string as escaped using {@link #escapeText(String)}.
* Two-digit hex escapes (starting with "\x") are also recognized.
*/
@@ -1183,12 +1828,12 @@ public final class TextFormat {
}
/** Is this an octal digit? */
- private static boolean isOctal(final char c) {
+ private static boolean isOctal(final byte c) {
return '0' <= c && c <= '7';
}
/** Is this a hex digit? */
- private static boolean isHex(final char c) {
+ private static boolean isHex(final byte c) {
return ('0' <= c && c <= '9') ||
('a' <= c && c <= 'f') ||
('A' <= c && c <= 'F');
@@ -1199,7 +1844,7 @@ public final class TextFormat {
* numeric value. This is like {@code Character.digit()} but we don't accept
* non-ASCII digits.
*/
- private static int digitValue(final char c) {
+ private static int digitValue(final byte c) {
if ('0' <= c && c <= '9') {
return c - '0';
} else if ('a' <= c && c <= 'z') {
@@ -1212,7 +1857,7 @@ public final class TextFormat {
/**
* Parse a 32-bit signed integer from the text. Unlike the Java standard
* {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
- * and "0" to signify hexidecimal and octal numbers, respectively.
+ * and "0" to signify hexadecimal and octal numbers, respectively.
*/
static int parseInt32(final String text) throws NumberFormatException {
return (int) parseInteger(text, true, false);
@@ -1221,7 +1866,7 @@ public final class TextFormat {
/**
* Parse a 32-bit unsigned integer from the text. Unlike the Java standard
* {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
- * and "0" to signify hexidecimal and octal numbers, respectively. The
+ * and "0" to signify hexadecimal and octal numbers, respectively. The
* result is coerced to a (signed) {@code int} when returned since Java has
* no unsigned integer type.
*/
@@ -1232,7 +1877,7 @@ public final class TextFormat {
/**
* Parse a 64-bit signed integer from the text. Unlike the Java standard
* {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
- * and "0" to signify hexidecimal and octal numbers, respectively.
+ * and "0" to signify hexadecimal and octal numbers, respectively.
*/
static long parseInt64(final String text) throws NumberFormatException {
return parseInteger(text, true, true);
@@ -1241,7 +1886,7 @@ public final class TextFormat {
/**
* Parse a 64-bit unsigned integer from the text. Unlike the Java standard
* {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
- * and "0" to signify hexidecimal and octal numbers, respectively. The
+ * and "0" to signify hexadecimal and octal numbers, respectively. The
* result is coerced to a (signed) {@code long} when returned since Java has
* no unsigned long type.
*/
diff --git a/java/src/main/java/com/google/protobuf/UninitializedMessageException.java b/java/src/main/java/com/google/protobuf/UninitializedMessageException.java
index 8743c12..5714c06 100644
--- a/java/src/main/java/com/google/protobuf/UninitializedMessageException.java
+++ b/java/src/main/java/com/google/protobuf/UninitializedMessageException.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/java/src/main/java/com/google/protobuf/UnknownFieldSet.java b/java/src/main/java/com/google/protobuf/UnknownFieldSet.java
index 26a15d0..99de373 100644
--- a/java/src/main/java/com/google/protobuf/UnknownFieldSet.java
+++ b/java/src/main/java/com/google/protobuf/UnknownFieldSet.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -46,7 +46,7 @@ import java.util.TreeMap;
* {@code UnknownFieldSet} is used to keep track of fields which were seen when
* parsing a protocol message but whose field numbers or types are unrecognized.
* This most frequently occurs when new fields are added to a message type
- * and then messages containing those feilds are read by old software that was
+ * and then messages containing those fields are read by old software that was
* compiled before the new types were added.
*
* <p>Every {@link Message} contains an {@code UnknownFieldSet} (and every
@@ -91,6 +91,7 @@ public final class UnknownFieldSet implements MessageLite {
}
private Map<Integer, Field> fields;
+
@Override
public boolean equals(final Object other) {
if (this == other) {
@@ -367,6 +368,22 @@ public final class UnknownFieldSet implements MessageLite {
reinitialize();
return this;
}
+
+ /** Clear fields from the set with a given field number. */
+ public Builder clearField(final int number) {
+ if (number == 0) {
+ throw new IllegalArgumentException("Zero is not a valid field number.");
+ }
+ if (lastField != null && lastFieldNumber == number) {
+ // Discard this.
+ lastField = null;
+ lastFieldNumber = 0;
+ }
+ if (fields.containsKey(number)) {
+ fields.remove(number);
+ }
+ return this;
+ }
/**
* Merge the fields from {@code other} into this set. If a field number
@@ -468,7 +485,7 @@ public final class UnknownFieldSet implements MessageLite {
/**
* Parse a single field from {@code input} and merge it into this set.
* @param tag The field's tag number, which was already parsed.
- * @return {@code false} if the tag is an engroup tag.
+ * @return {@code false} if the tag is an end group tag.
*/
public boolean mergeFieldFrom(final int tag, final CodedInputStream input)
throws IOException {
@@ -950,4 +967,29 @@ public final class UnknownFieldSet implements MessageLite {
}
}
}
+
+ /**
+ * Parser to implement MessageLite interface.
+ */
+ public static final class Parser extends AbstractParser<UnknownFieldSet> {
+ public UnknownFieldSet parsePartialFrom(
+ CodedInputStream input, ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ Builder builder = newBuilder();
+ try {
+ builder.mergeFrom(input);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(builder.buildPartial());
+ } catch (IOException e) {
+ throw new InvalidProtocolBufferException(e.getMessage())
+ .setUnfinishedMessage(builder.buildPartial());
+ }
+ return builder.buildPartial();
+ }
+ }
+
+ private static final Parser PARSER = new Parser();
+ public final Parser getParserForType() {
+ return PARSER;
+ }
}
diff --git a/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java b/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java
new file mode 100644
index 0000000..5cc005d
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java
@@ -0,0 +1,205 @@
+// 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.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.RandomAccess;
+
+/**
+ * An implementation of {@link LazyStringList} that wraps another
+ * {@link LazyStringList} such that it cannot be modified via the wrapper.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class UnmodifiableLazyStringList extends AbstractList<String>
+ implements LazyStringList, RandomAccess {
+
+ private final LazyStringList list;
+
+ public UnmodifiableLazyStringList(LazyStringList list) {
+ this.list = list;
+ }
+
+ @Override
+ public String get(int index) {
+ return list.get(index);
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public ByteString getByteString(int index) {
+ return list.getByteString(index);
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void add(ByteString element) {
+ throw new UnsupportedOperationException();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void set(int index, ByteString element) {
+ throw new UnsupportedOperationException();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean addAllByteString(Collection<? extends ByteString> element) {
+ throw new UnsupportedOperationException();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public byte[] getByteArray(int index) {
+ return list.getByteArray(index);
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void add(byte[] element) {
+ throw new UnsupportedOperationException();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void set(int index, byte[] element) {
+ throw new UnsupportedOperationException();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean addAllByteArray(Collection<byte[]> element) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ListIterator<String> listIterator(final int index) {
+ return new ListIterator<String>() {
+ ListIterator<String> iter = list.listIterator(index);
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean hasNext() {
+ return iter.hasNext();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public String next() {
+ return iter.next();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean hasPrevious() {
+ return iter.hasPrevious();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public String previous() {
+ return iter.previous();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public int nextIndex() {
+ return iter.nextIndex();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public int previousIndex() {
+ return iter.previousIndex();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void set(String o) {
+ throw new UnsupportedOperationException();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void add(String o) {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ @Override
+ public Iterator<String> iterator() {
+ return new Iterator<String>() {
+ Iterator<String> iter = list.iterator();
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean hasNext() {
+ return iter.hasNext();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public String next() {
+ return iter.next();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public List<?> getUnderlyingElements() {
+ // The returned value is already unmodifiable.
+ return list.getUnderlyingElements();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void mergeFrom(LazyStringList other) {
+ throw new UnsupportedOperationException();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public List<byte[]> asByteArrayList() {
+ return Collections.unmodifiableList(list.asByteArrayList());
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public List<ByteString> asByteStringList() {
+ return Collections.unmodifiableList(list.asByteStringList());
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public LazyStringList getUnmodifiableView() {
+ return this;
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/Utf8.java b/java/src/main/java/com/google/protobuf/Utf8.java
new file mode 100644
index 0000000..4d0ef53
--- /dev/null
+++ b/java/src/main/java/com/google/protobuf/Utf8.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;
+
+/**
+ * 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, "UTF-8").getBytes("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() {}
+
+ /**
+ * 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();
+ }
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/WireFormat.java b/java/src/main/java/com/google/protobuf/WireFormat.java
index c46f7b0..eba2528 100644
--- a/java/src/main/java/com/google/protobuf/WireFormat.java
+++ b/java/src/main/java/com/google/protobuf/WireFormat.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -45,12 +45,12 @@ public final class WireFormat {
// Do not allow instantiation.
private WireFormat() {}
- static final int WIRETYPE_VARINT = 0;
- static final int WIRETYPE_FIXED64 = 1;
- static final int WIRETYPE_LENGTH_DELIMITED = 2;
- static final int WIRETYPE_START_GROUP = 3;
- static final int WIRETYPE_END_GROUP = 4;
- static final int WIRETYPE_FIXED32 = 5;
+ public static final int WIRETYPE_VARINT = 0;
+ public static final int WIRETYPE_FIXED64 = 1;
+ public static final int WIRETYPE_LENGTH_DELIMITED = 2;
+ public static final int WIRETYPE_START_GROUP = 3;
+ public static final int WIRETYPE_END_GROUP = 4;
+ public static final int WIRETYPE_FIXED32 = 5;
static final int TAG_TYPE_BITS = 3;
static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1;
@@ -146,7 +146,7 @@ public final class WireFormat {
public boolean isPackable() { return true; }
}
- // Field numbers for feilds in MessageSet wire format.
+ // Field numbers for fields in MessageSet wire format.
static final int MESSAGE_SET_ITEM = 1;
static final int MESSAGE_SET_TYPE_ID = 2;
static final int MESSAGE_SET_MESSAGE = 3;
diff --git a/java/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java b/java/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java
index 88df38d..324a63f 100644
--- a/java/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java
+++ b/java/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java
@@ -31,7 +31,9 @@
package com.google.protobuf.nano;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
/**
* Encodes and writes protocol message fields.
@@ -48,15 +50,17 @@ import java.io.UnsupportedEncodingException;
* @author kneton@google.com Kenton Varda
*/
public final class CodedOutputByteBufferNano {
- private final byte[] buffer;
- private final int limit;
- private int position;
+ /* max bytes per java UTF-16 char in UTF-8 */
+ private static final int MAX_UTF8_EXPANSION = 3;
+ private final ByteBuffer buffer;
private CodedOutputByteBufferNano(final byte[] buffer, final int offset,
final int length) {
+ this(ByteBuffer.wrap(buffer, offset, length));
+ }
+
+ private CodedOutputByteBufferNano(final ByteBuffer buffer) {
this.buffer = buffer;
- position = offset;
- limit = offset + length;
}
/**
@@ -288,14 +292,203 @@ public final class CodedOutputByteBufferNano {
/** Write a {@code string} field to the stream. */
public void writeStringNoTag(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.
- final byte[] bytes = value.getBytes("UTF-8");
- writeRawVarint32(bytes.length);
- writeRawBytes(bytes);
+ // 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. Optimize for the case where we know this length results in a
+ // constant varint length - saves measuring length of the string.
+ try {
+ final int minLengthVarIntSize = computeRawVarint32Size(value.length());
+ final int maxLengthVarIntSize = computeRawVarint32Size(value.length() * MAX_UTF8_EXPANSION);
+ if (minLengthVarIntSize == maxLengthVarIntSize) {
+ int oldPosition = buffer.position();
+ buffer.position(oldPosition + minLengthVarIntSize);
+ encode(value, buffer);
+ int newPosition = buffer.position();
+ buffer.position(oldPosition);
+ writeRawVarint32(newPosition - oldPosition - minLengthVarIntSize);
+ buffer.position(newPosition);
+ } else {
+ writeRawVarint32(encodedLength(value));
+ encode(value, buffer);
+ }
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(buffer.position(), buffer.limit());
+ }
+ }
+
+ // These UTF-8 handling methods are copied from Guava's Utf8 class.
+ /**
+ * 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)
+ */
+ private 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 IllegalArgumentException("Unpaired surrogate at index " + i);
+ }
+ i++;
+ }
+ }
+ }
+ return utf8Length;
+ }
+
+ /**
+ * Encodes {@code sequence} into UTF-8, in {@code byteBuffer}. For a string, this method is
+ * equivalent to {@code buffer.put(string.getBytes(UTF_8))}, but is more efficient in both time
+ * and space. Bytes are written starting at the current position. 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 3 * sequence.length()}, which is the
+ * largest possible number of bytes that any input can be encoded to.
+ *
+ * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
+ * surrogates)
+ * @throws BufferOverflowException if {@code sequence} encoded in UTF-8 does not fit in
+ * {@code byteBuffer}'s remaining space.
+ * @throws ReadOnlyBufferException if {@code byteBuffer} is a read-only buffer.
+ */
+ private static void encode(CharSequence sequence, ByteBuffer byteBuffer) {
+ if (byteBuffer.isReadOnly()) {
+ throw new ReadOnlyBufferException();
+ } else if (byteBuffer.hasArray()) {
+ try {
+ int encoded = encode(sequence,
+ byteBuffer.array(),
+ byteBuffer.arrayOffset() + byteBuffer.position(),
+ byteBuffer.remaining());
+ byteBuffer.position(encoded - byteBuffer.arrayOffset());
+ } catch (ArrayIndexOutOfBoundsException e) {
+ BufferOverflowException boe = new BufferOverflowException();
+ boe.initCause(e);
+ throw boe;
+ }
+ } else {
+ encodeDirect(sequence, byteBuffer);
+ }
+ }
+
+ private static void encodeDirect(CharSequence sequence, ByteBuffer byteBuffer) {
+ int utf16Length = sequence.length();
+ for (int i = 0; i < utf16Length; i++) {
+ final char c = sequence.charAt(i);
+ if (c < 0x80) { // ASCII
+ byteBuffer.put((byte) c);
+ } else if (c < 0x800) { // 11 bits, two UTF-8 bytes
+ byteBuffer.put((byte) ((0xF << 6) | (c >>> 6)));
+ byteBuffer.put((byte) (0x80 | (0x3F & c)));
+ } else if (c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) {
+ // Maximium single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
+ byteBuffer.put((byte) ((0xF << 5) | (c >>> 12)));
+ byteBuffer.put((byte) (0x80 | (0x3F & (c >>> 6))));
+ byteBuffer.put((byte) (0x80 | (0x3F & c)));
+ } else {
+ final char low;
+ if (i + 1 == sequence.length()
+ || !Character.isSurrogatePair(c, (low = sequence.charAt(++i)))) {
+ throw new IllegalArgumentException("Unpaired surrogate at index " + (i - 1));
+ }
+ int codePoint = Character.toCodePoint(c, low);
+ byteBuffer.put((byte) ((0xF << 4) | (codePoint >>> 18)));
+ byteBuffer.put((byte) (0x80 | (0x3F & (codePoint >>> 12))));
+ byteBuffer.put((byte) (0x80 | (0x3F & (codePoint >>> 6))));
+ byteBuffer.put((byte) (0x80 | (0x3F & codePoint)));
+ }
+ }
+ }
+
+ private 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 IllegalArgumentException("Unpaired surrogate at index " + (i - 1));
+ }
+ 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 {
+ throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + j);
+ }
+ }
+ return j;
}
+ // End guava UTF-8 methods
+
/** Write a {@code group} field to the stream. */
public void writeGroupNoTag(final MessageNano value) throws IOException {
value.writeTo(this);
@@ -603,13 +796,8 @@ public final class CodedOutputByteBufferNano {
* {@code string} field.
*/
public static int computeStringSizeNoTag(final String value) {
- try {
- final byte[] bytes = value.getBytes("UTF-8");
- return computeRawVarint32Size(bytes.length) +
- bytes.length;
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException("UTF-8 not supported.");
- }
+ final int length = encodedLength(value);
+ return computeRawVarint32Size(length) + length;
}
/**
@@ -692,7 +880,7 @@ public final class CodedOutputByteBufferNano {
* Otherwise, throws {@code UnsupportedOperationException}.
*/
public int spaceLeft() {
- return limit - position;
+ return buffer.remaining();
}
/**
@@ -710,6 +898,23 @@ public final class CodedOutputByteBufferNano {
}
/**
+ * Returns the position within the internal buffer.
+ */
+ public int position() {
+ return buffer.position();
+ }
+
+ /**
+ * Resets the position within the internal buffer to zero.
+ *
+ * @see #position
+ * @see #spaceLeft
+ */
+ public void reset() {
+ buffer.clear();
+ }
+
+ /**
* 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.
@@ -725,12 +930,12 @@ public final class CodedOutputByteBufferNano {
/** Write a single byte. */
public void writeRawByte(final byte value) throws IOException {
- if (position == limit) {
+ if (!buffer.hasRemaining()) {
// We're writing to a single buffer.
- throw new OutOfSpaceException(position, limit);
+ throw new OutOfSpaceException(buffer.position(), buffer.limit());
}
- buffer[position++] = value;
+ buffer.put(value);
}
/** Write a single byte, represented by an integer value. */
@@ -746,13 +951,11 @@ public final class CodedOutputByteBufferNano {
/** 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;
+ if (buffer.remaining() >= length) {
+ buffer.put(value, offset, length);
} else {
// We're writing to a single buffer.
- throw new OutOfSpaceException(position, limit);
+ throw new OutOfSpaceException(buffer.position(), buffer.limit());
}
}
diff --git a/java/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java b/java/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java
index 46cd86f..4fe8dce 100644
--- a/java/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java
+++ b/java/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java
@@ -160,28 +160,10 @@ public abstract class ExtendableMessageNano<M extends ExtendableMessageNano<M>>
return true;
}
- /**
- * Returns whether the stored unknown field data in this message is equivalent to that in the
- * other message.
- *
- * @param other the other message.
- * @return whether the two sets of unknown field data are equal.
- */
- protected final boolean unknownFieldDataEquals(M other) {
- if (unknownFieldData == null || unknownFieldData.isEmpty()) {
- return other.unknownFieldData == null || other.unknownFieldData.isEmpty();
- } else {
- return unknownFieldData.equals(other.unknownFieldData);
- }
- }
-
- /**
- * Computes the hashcode representing the unknown field data stored in this message.
- *
- * @return the hashcode for the unknown field data.
- */
- protected final int unknownFieldDataHashCode() {
- return (unknownFieldData == null || unknownFieldData.isEmpty()
- ? 0 : unknownFieldData.hashCode());
+ @Override
+ public M clone() throws CloneNotSupportedException {
+ M cloned = (M) super.clone();
+ InternalNano.cloneUnknownFieldData(this, cloned);
+ return cloned;
}
}
diff --git a/java/src/main/java/com/google/protobuf/nano/Extension.java b/java/src/main/java/com/google/protobuf/nano/Extension.java
index a851daf..6e2202e 100644
--- a/java/src/main/java/com/google/protobuf/nano/Extension.java
+++ b/java/src/main/java/com/google/protobuf/nano/Extension.java
@@ -79,12 +79,30 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
* Should be used by the generated code only.
*
* @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
+ * @deprecated use {@link #createMessageTyped(int, Class, long)} instead.
*/
+ @Deprecated
public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
Extension<M, T> createMessageTyped(int type, Class<T> clazz, int tag) {
return new Extension<M, T>(type, clazz, tag, false);
}
+ // Note: these create...() methods take a long for the tag parameter,
+ // because tags are represented as unsigned ints, and these values exist
+ // in generated code as long values. However, they can fit in 32-bits, so
+ // it's safe to cast them to int without loss of precision.
+
+ /**
+ * Creates an {@code Extension} of the given message type and tag number.
+ * Should be used by the generated code only.
+ *
+ * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
+ */
+ public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
+ Extension<M, T> createMessageTyped(int type, Class<T> clazz, long tag) {
+ return new Extension<M, T>(type, clazz, (int) tag, false);
+ }
+
/**
* Creates a repeated {@code Extension} of the given message type and tag number.
* Should be used by the generated code only.
@@ -92,8 +110,8 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
* @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
*/
public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
- Extension<M, T[]> createRepeatedMessageTyped(int type, Class<T[]> clazz, int tag) {
- return new Extension<M, T[]>(type, clazz, tag, true);
+ Extension<M, T[]> createRepeatedMessageTyped(int type, Class<T[]> clazz, long tag) {
+ return new Extension<M, T[]>(type, clazz, (int) tag, true);
}
/**
@@ -104,8 +122,8 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
* @param clazz the boxed Java type of this extension
*/
public static <M extends ExtendableMessageNano<M>, T>
- Extension<M, T> createPrimitiveTyped(int type, Class<T> clazz, int tag) {
- return new PrimitiveExtension<M, T>(type, clazz, tag, false, 0, 0);
+ Extension<M, T> createPrimitiveTyped(int type, Class<T> clazz, long tag) {
+ return new PrimitiveExtension<M, T>(type, clazz, (int) tag, false, 0, 0);
}
/**
@@ -117,8 +135,9 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
*/
public static <M extends ExtendableMessageNano<M>, T>
Extension<M, T> createRepeatedPrimitiveTyped(
- int type, Class<T> clazz, int tag, int nonPackedTag, int packedTag) {
- return new PrimitiveExtension<M, T>(type, clazz, tag, true, nonPackedTag, packedTag);
+ int type, Class<T> clazz, long tag, long nonPackedTag, long packedTag) {
+ return new PrimitiveExtension<M, T>(type, clazz, (int) tag, true,
+ (int) nonPackedTag, (int) packedTag);
}
/**
@@ -136,7 +155,7 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
protected final Class<T> clazz;
/**
- * Tag number of this extension.
+ * Tag number of this extension. The data should be viewed as an unsigned 32-bit value.
*/
public final int tag;
diff --git a/java/src/main/java/com/google/protobuf/nano/FieldArray.java b/java/src/main/java/com/google/protobuf/nano/FieldArray.java
index ab923a4..5e8856d 100644
--- a/java/src/main/java/com/google/protobuf/nano/FieldArray.java
+++ b/java/src/main/java/com/google/protobuf/nano/FieldArray.java
@@ -35,9 +35,12 @@ package com.google.protobuf.nano;
* A custom version of {@link 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}.
*/
-class FieldArray {
+public final class FieldArray implements Cloneable {
private static final FieldData DELETED = new FieldData();
private boolean mGarbage = false;
@@ -48,7 +51,7 @@ class FieldArray {
/**
* Creates a new FieldArray containing no fields.
*/
- public FieldArray() {
+ FieldArray() {
this(10);
}
@@ -57,7 +60,7 @@ class FieldArray {
* require any additional memory allocation to store the specified
* number of mappings.
*/
- public FieldArray(int initialCapacity) {
+ FieldArray(int initialCapacity) {
initialCapacity = idealIntArraySize(initialCapacity);
mFieldNumbers = new int[initialCapacity];
mData = new FieldData[initialCapacity];
@@ -68,7 +71,7 @@ class FieldArray {
* Gets the FieldData mapped from the specified fieldNumber, or <code>null</code>
* if no such mapping has been made.
*/
- public FieldData get(int fieldNumber) {
+ FieldData get(int fieldNumber) {
int i = binarySearch(fieldNumber);
if (i < 0 || mData[i] == DELETED) {
@@ -81,7 +84,7 @@ class FieldArray {
/**
* Removes the data from the specified fieldNumber, if there was any.
*/
- public void remove(int fieldNumber) {
+ void remove(int fieldNumber) {
int i = binarySearch(fieldNumber);
if (i >= 0 && mData[i] != DELETED) {
@@ -118,7 +121,7 @@ class FieldArray {
* Adds a mapping from the specified fieldNumber to the specified data,
* replacing the previous mapping if there was one.
*/
- public void put(int fieldNumber, FieldData data) {
+ void put(int fieldNumber, FieldData data) {
int i = binarySearch(fieldNumber);
if (i >= 0) {
@@ -167,7 +170,7 @@ class FieldArray {
* Returns the number of key-value mappings that this FieldArray
* currently stores.
*/
- public int size() {
+ int size() {
if (mGarbage) {
gc();
}
@@ -184,7 +187,7 @@ class FieldArray {
* the value from the <code>index</code>th key-value mapping that this
* FieldArray stores.
*/
- public FieldData dataAt(int index) {
+ FieldData dataAt(int index) {
if (mGarbage) {
gc();
}
@@ -270,4 +273,19 @@ class FieldArray {
}
return true;
}
+
+ @Override
+ public final FieldArray clone() {
+ // Trigger GC so we compact and don't copy DELETED elements.
+ int size = size();
+ FieldArray clone = new FieldArray(size);
+ System.arraycopy(mFieldNumbers, 0, clone.mFieldNumbers, 0, size);
+ for (int i = 0; i < size; i++) {
+ if (mData[i] != null) {
+ clone.mData[i] = mData[i].clone();
+ }
+ }
+ clone.mSize = size;
+ return clone;
+ }
}
diff --git a/java/src/main/java/com/google/protobuf/nano/FieldData.java b/java/src/main/java/com/google/protobuf/nano/FieldData.java
index 7a5eb4c..20a5142 100644
--- a/java/src/main/java/com/google/protobuf/nano/FieldData.java
+++ b/java/src/main/java/com/google/protobuf/nano/FieldData.java
@@ -39,7 +39,7 @@ import java.util.List;
* Stores unknown fields. These might be extensions or fields that the generated API doesn't
* know about yet.
*/
-class FieldData {
+class FieldData implements Cloneable {
private Extension<?, ?> cachedExtension;
private Object value;
/** The serialised values for this object. Will be cleared if getValue is called */
@@ -58,6 +58,23 @@ class FieldData {
unknownFieldData.add(unknownField);
}
+ UnknownFieldData getUnknownField(int index) {
+ if (unknownFieldData == null) {
+ return null;
+ }
+ if (index < unknownFieldData.size()) {
+ return unknownFieldData.get(index);
+ }
+ return null;
+ }
+
+ int getUnknownFieldSize() {
+ if (unknownFieldData == null) {
+ return 0;
+ }
+ return unknownFieldData.size();
+ }
+
<T> T getValue(Extension<?, T> extension) {
if (value != null){
if (cachedExtension != extension) { // Extension objects are singletons.
@@ -170,4 +187,54 @@ class FieldData {
return result;
}
+ @Override
+ public final FieldData clone() {
+ FieldData clone = new FieldData();
+ try {
+ clone.cachedExtension = cachedExtension;
+ if (unknownFieldData == null) {
+ clone.unknownFieldData = null;
+ } else {
+ clone.unknownFieldData.addAll(unknownFieldData);
+ }
+
+ // Whether we need to deep clone value depends on its type. Primitive reference types
+ // (e.g. Integer, Long etc.) are ok, since they're immutable. We need to clone arrays
+ // and messages.
+ if (value == null) {
+ // No cloning required.
+ } else if (value instanceof MessageNano) {
+ clone.value = ((MessageNano) value).clone();
+ } else if (value instanceof byte[]) {
+ clone.value = ((byte[]) value).clone();
+ } else if (value instanceof byte[][]) {
+ byte[][] valueArray = (byte[][]) value;
+ byte[][] cloneArray = new byte[valueArray.length][];
+ clone.value = cloneArray;
+ for (int i = 0; i < valueArray.length; i++) {
+ cloneArray[i] = valueArray[i].clone();
+ }
+ } else if (value instanceof boolean[]) {
+ clone.value = ((boolean[]) value).clone();
+ } else if (value instanceof int[]) {
+ clone.value = ((int[]) value).clone();
+ } else if (value instanceof long[]) {
+ clone.value = ((long[]) value).clone();
+ } else if (value instanceof float[]) {
+ clone.value = ((float[]) value).clone();
+ } else if (value instanceof double[]) {
+ clone.value = ((double[]) value).clone();
+ } else if (value instanceof MessageNano[]) {
+ MessageNano[] valueArray = (MessageNano[]) value;
+ MessageNano[] cloneArray = new MessageNano[valueArray.length];
+ clone.value = cloneArray;
+ for (int i = 0; i < valueArray.length; i++) {
+ cloneArray[i] = valueArray[i].clone();
+ }
+ }
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ throw new AssertionError(e);
+ }
+ }
}
diff --git a/java/src/main/java/com/google/protobuf/nano/InternalNano.java b/java/src/main/java/com/google/protobuf/nano/InternalNano.java
index 90ca11d..c4adfa5 100644
--- a/java/src/main/java/com/google/protobuf/nano/InternalNano.java
+++ b/java/src/main/java/com/google/protobuf/nano/InternalNano.java
@@ -330,4 +330,12 @@ public final class InternalNano {
return result;
}
+ // This avoids having to make FieldArray public.
+ public static void cloneUnknownFieldData(ExtendableMessageNano original,
+ ExtendableMessageNano cloned) {
+ if (original.unknownFieldData != null) {
+ cloned.unknownFieldData = (FieldArray) original.unknownFieldData.clone();
+ }
+ }
+
}
diff --git a/java/src/main/java/com/google/protobuf/nano/MessageNano.java b/java/src/main/java/com/google/protobuf/nano/MessageNano.java
index 164f317..ea91b21 100644
--- a/java/src/main/java/com/google/protobuf/nano/MessageNano.java
+++ b/java/src/main/java/com/google/protobuf/nano/MessageNano.java
@@ -187,4 +187,12 @@ public abstract class MessageNano {
public String toString() {
return MessageNanoPrinter.print(this);
}
+
+ /**
+ * Provides support for cloning. This only works if you specify the generate_clone method.
+ */
+ @Override
+ public MessageNano clone() throws CloneNotSupportedException {
+ return (MessageNano) super.clone();
+ }
}
diff --git a/java/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java b/java/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
index 4cca3d5..a30f2f3 100644
--- a/java/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
+++ b/java/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
@@ -108,6 +108,10 @@ public final class MessageNanoPrinter {
for (Field field : clazz.getFields()) {
int modifiers = field.getModifiers();
String fieldName = field.getName();
+ if ("cachedSize".equals(fieldName)) {
+ // TODO(bduff): perhaps cachedSize should have a more obscure name.
+ continue;
+ }
if ((modifiers & Modifier.PUBLIC) == Modifier.PUBLIC
&& (modifiers & Modifier.STATIC) != Modifier.STATIC
diff --git a/java/src/main/java/com/google/protobuf/nano/UnknownFieldData.java b/java/src/main/java/com/google/protobuf/nano/UnknownFieldData.java
index 2032e1a..bf34bed 100644
--- a/java/src/main/java/com/google/protobuf/nano/UnknownFieldData.java
+++ b/java/src/main/java/com/google/protobuf/nano/UnknownFieldData.java
@@ -42,6 +42,10 @@ import java.util.Arrays;
final class UnknownFieldData {
final int tag;
+ /**
+ * Important: this should be treated as immutable, even though it's possible
+ * to change the array values.
+ */
final byte[] bytes;
UnknownFieldData(int tag, byte[] bytes) {
diff --git a/java/src/test/java/com/google/protobuf/AbstractMessageTest.java b/java/src/test/java/com/google/protobuf/AbstractMessageTest.java
index c44d660..d964ef5 100644
--- a/java/src/test/java/com/google/protobuf/AbstractMessageTest.java
+++ b/java/src/test/java/com/google/protobuf/AbstractMessageTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -30,6 +30,7 @@
package com.google.protobuf;
+import com.google.protobuf.Descriptors.FieldDescriptor;
import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
import protobuf_unittest.UnittestProto;
import protobuf_unittest.UnittestProto.ForeignMessage;
@@ -167,6 +168,13 @@ public class AbstractMessageTest extends TestCase {
wrappedBuilder.setUnknownFields(unknownFields);
return this;
}
+ @Override
+ public Message.Builder getFieldBuilder(FieldDescriptor field) {
+ return wrappedBuilder.getFieldBuilder(field);
+ }
+ }
+ public Parser<? extends Message> getParserForType() {
+ return wrappedMessage.getParserForType();
}
}
@@ -220,6 +228,34 @@ public class AbstractMessageTest extends TestCase {
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());
@@ -298,12 +334,16 @@ public class AbstractMessageTest extends TestCase {
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 {
@@ -312,18 +352,27 @@ public class AbstractMessageTest extends TestCase {
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());
}
// -----------------------------------------------------------------
@@ -366,7 +415,7 @@ public class AbstractMessageTest extends TestCase {
// -----------------------------------------------------------------
// Tests for equals and hashCode
-
+
public void testEqualsAndHashCode() throws Exception {
TestAllTypes a = TestUtil.getAllSet();
TestAllTypes b = TestAllTypes.newBuilder().build();
@@ -382,7 +431,7 @@ public class AbstractMessageTest extends TestCase {
checkEqualsIsConsistent(d);
checkEqualsIsConsistent(e);
checkEqualsIsConsistent(f);
-
+
checkNotEqual(a, b);
checkNotEqual(a, c);
checkNotEqual(a, d);
@@ -413,19 +462,20 @@ public class AbstractMessageTest extends TestCase {
checkEqualsIsConsistent(eUnknownFields);
checkEqualsIsConsistent(fUnknownFields);
- // Subseqent reconstitutions should be identical
+ // Subsequent reconstitutions should be identical
UnittestProto.TestEmptyMessage eUnknownFields2 =
UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray());
checkEqualsIsConsistent(eUnknownFields, eUnknownFields2);
}
-
+
+
/**
- * Asserts that the given proto has symetric equals and hashCode methods.
+ * 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);
@@ -442,7 +492,7 @@ public class AbstractMessageTest extends TestCase {
/**
* 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.
@@ -456,4 +506,22 @@ public class AbstractMessageTest extends TestCase {
String.format("%s should have a different hash code from %s", m1, m2),
m1.hashCode() == m2.hashCode());
}
+
+ public void testCheckByteStringIsUtf8OnUtf8() {
+ ByteString byteString = ByteString.copyFromUtf8("some text");
+ AbstractMessageLite.checkByteStringIsUtf8(byteString);
+ // No exception thrown.
+ }
+
+ public void testCheckByteStringIsUtf8OnNonUtf8() {
+ ByteString byteString =
+ ByteString.copyFrom(new byte[]{(byte) 0x80}); // A lone continuation byte.
+ try {
+ AbstractMessageLite.checkByteStringIsUtf8(byteString);
+ fail("Expected AbstractMessageLite.checkByteStringIsUtf8 to throw IllegalArgumentException");
+ } catch (IllegalArgumentException exception) {
+ assertEquals("Byte string is not UTF-8.", exception.getMessage());
+ }
+ }
+
}
diff --git a/java/src/test/java/com/google/protobuf/BoundedByteStringTest.java b/java/src/test/java/com/google/protobuf/BoundedByteStringTest.java
new file mode 100644
index 0000000..2b71cfb
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/BoundedByteStringTest.java
@@ -0,0 +1,68 @@
+// 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.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;
+ }
+
+ @Override
+ public void testToString() throws UnsupportedEncodingException {
+ String testString = "I love unicode \u1234\u5678 characters";
+ LiteralByteString unicode = new LiteralByteString(testString.getBytes(UTF_8));
+ ByteString chopped = unicode.substring(2, unicode.size() - 6);
+ assertEquals(classUnderTest + ".substring() must have the expected type",
+ classUnderTest, getActualClassName(chopped));
+
+ String roundTripString = chopped.toString(UTF_8);
+ assertEquals(classUnderTest + " unicode bytes must match",
+ testString.substring(2, testString.length() - 6), roundTripString);
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/ByteStringTest.java b/java/src/test/java/com/google/protobuf/ByteStringTest.java
new file mode 100644
index 0000000..15de17c
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/ByteStringTest.java
@@ -0,0 +1,759 @@
+// 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.ByteString.Output;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+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.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 near the rope copy-out threshold.
+ public void testReadFrom_mediumStream() throws IOException {
+ assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE - 1));
+ assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE));
+ assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE + 1));
+ assertReadFrom(getTestBytes(200));
+ }
+
+ // 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 sizes that are near the read buffer size.
+ public void testReadFrom_byteBoundaries() throws IOException {
+ final int min = ByteString.MIN_READ_FROM_CHUNK_SIZE;
+ final int max = ByteString.MAX_READ_FROM_CHUNK_SIZE;
+
+ assertReadFrom(getTestBytes(min - 1));
+ assertReadFrom(getTestBytes(min));
+ assertReadFrom(getTestBytes(min + 1));
+
+ assertReadFrom(getTestBytes(min * 2 - 1));
+ assertReadFrom(getTestBytes(min * 2));
+ assertReadFrom(getTestBytes(min * 2 + 1));
+
+ assertReadFrom(getTestBytes(min * 4 - 1));
+ assertReadFrom(getTestBytes(min * 4));
+ assertReadFrom(getTestBytes(min * 4 + 1));
+
+ assertReadFrom(getTestBytes(min * 8 - 1));
+ assertReadFrom(getTestBytes(min * 8));
+ assertReadFrom(getTestBytes(min * 8 + 1));
+
+ assertReadFrom(getTestBytes(max - 1));
+ assertReadFrom(getTestBytes(max));
+ assertReadFrom(getTestBytes(max + 1));
+
+ assertReadFrom(getTestBytes(max * 2 - 1));
+ assertReadFrom(getTestBytes(max * 2));
+ assertReadFrom(getTestBytes(max * 2 + 1));
+ }
+
+ // 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 testNewCodedBuilder() throws IOException {
+ byte[] bytes = getTestBytes();
+ ByteString.CodedBuilder builder = ByteString.newCodedBuilder(bytes.length);
+ builder.getCodedOutput().writeRawBytes(bytes);
+ ByteString byteString = builder.build();
+ assertTrue("String built from newCodedBuilder() must contain the expected bytes",
+ isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
+ }
+
+ 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());
+ }
+
+ /**
+ * Test the Rope implementation can deal with Empty nodes, even though we
+ * guard against them. See also {@link LiteralByteStringTest#testConcat_empty()}.
+ */
+ public void testConcat_empty() {
+ byte[] referenceBytes = getTestBytes(7748, 113344L);
+ ByteString literalString = ByteString.copyFrom(referenceBytes);
+
+ ByteString duo = RopeByteString.newInstanceForTest(literalString, literalString);
+ ByteString temp = RopeByteString.newInstanceForTest(
+ RopeByteString.newInstanceForTest(literalString, ByteString.EMPTY),
+ RopeByteString.newInstanceForTest(ByteString.EMPTY, literalString));
+ ByteString quintet = RopeByteString.newInstanceForTest(temp, ByteString.EMPTY);
+
+ assertTrue("String with concatenated nulls must equal simple concatenate",
+ duo.equals(quintet));
+ assertEquals("String with concatenated nulls have same hashcode as simple concatenate",
+ duo.hashCode(), quintet.hashCode());
+
+ ByteString.ByteIterator duoIter = duo.iterator();
+ ByteString.ByteIterator quintetIter = quintet.iterator();
+ boolean stillEqual = true;
+ while (stillEqual && quintetIter.hasNext()) {
+ stillEqual = (duoIter.nextByte() == quintetIter.nextByte());
+ }
+ assertTrue("We must get the same characters by iterating", stillEqual);
+ assertFalse("Iterator must be exhausted", duoIter.hasNext());
+ try {
+ duoIter.nextByte();
+ fail("Should have thrown an exception.");
+ } catch (NoSuchElementException e) {
+ // This is success
+ }
+ try {
+ quintetIter.nextByte();
+ fail("Should have thrown an exception.");
+ } catch (NoSuchElementException e) {
+ // This is success
+ }
+
+ // Test that even if we force empty strings in as rope leaves in this
+ // configuration, we always get a (possibly Bounded) LiteralByteString
+ // for a length 1 substring.
+ //
+ // It is possible, using the testing factory method to create deeply nested
+ // 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);
+ }
+ for (int i = 1; i < quintet.size(); ++i) {
+ assertTrue("Substrings of size() < 2 must not be RopeByteStrings",
+ quintet.substring(i - 1, i) instanceof LiteralByteString);
+ }
+ }
+
+ 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));
+ }
+
+ public void testEndsWith() {
+ 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.endsWith(ByteString.EMPTY));
+ assertTrue(string.endsWith(string));
+ assertTrue(string.endsWith(suffix));
+ assertFalse(string.endsWith(prefix));
+ assertFalse(suffix.endsWith(prefix));
+ assertFalse(prefix.endsWith(suffix));
+ assertFalse(ByteString.EMPTY.endsWith(suffix));
+ assertTrue(ByteString.EMPTY.endsWith(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;
+ }
+
+ private byte[] substringUsingWriteTo(
+ ByteString data, int offset, int length) throws IOException {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ data.writeTo(output, offset, length);
+ return output.toByteArray();
+ }
+
+ public void testWriteToOutputStream() throws Exception {
+ // Choose a size large enough so when two ByteStrings are concatenated they
+ // won't be merged into one byte array due to some optimizations.
+ final int dataSize = ByteString.CONCATENATE_BY_COPY_SIZE + 1;
+ byte[] data1 = new byte[dataSize];
+ for (int i = 0; i < data1.length; i++) {
+ data1[i] = (byte) 1;
+ }
+ data1[1] = (byte) 11;
+ // Test LiteralByteString.writeTo(OutputStream,int,int)
+ LiteralByteString left = new LiteralByteString(data1);
+ byte[] result = substringUsingWriteTo(left, 1, 1);
+ assertEquals(1, result.length);
+ assertEquals((byte) 11, result[0]);
+
+ byte[] data2 = new byte[dataSize];
+ for (int i = 0; i < data1.length; i++) {
+ data2[i] = (byte) 2;
+ }
+ LiteralByteString right = new LiteralByteString(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
+ // structure.
+ assertEquals(1, root.getTreeDepth());
+ // Write parts of the left node.
+ result = substringUsingWriteTo(root, 0, dataSize);
+ assertEquals(dataSize, result.length);
+ assertEquals((byte) 1, result[0]);
+ assertEquals((byte) 1, result[dataSize - 1]);
+ // Write parts of the right node.
+ result = substringUsingWriteTo(root, dataSize, dataSize);
+ assertEquals(dataSize, result.length);
+ assertEquals((byte) 2, result[0]);
+ assertEquals((byte) 2, result[dataSize - 1]);
+ // Write a segment of bytes that runs across both nodes.
+ result = substringUsingWriteTo(root, dataSize / 2, dataSize);
+ assertEquals(dataSize, result.length);
+ assertEquals((byte) 1, result[0]);
+ assertEquals((byte) 1, result[dataSize - dataSize / 2 - 1]);
+ assertEquals((byte) 2, result[dataSize - dataSize / 2]);
+ assertEquals((byte) 2, result[dataSize - 1]);
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/CheckUtf8Test.java b/java/src/test/java/com/google/protobuf/CheckUtf8Test.java
new file mode 100644
index 0000000..6470e9c
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/CheckUtf8Test.java
@@ -0,0 +1,141 @@
+// 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 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;
+
+/**
+ * Test that protos generated with file option java_string_check_utf8 do in
+ * fact perform appropriate UTF-8 checks.
+ *
+ * @author jbaum@google.com (Jacob Butcher)
+ */
+public class CheckUtf8Test extends TestCase {
+
+ private static final String UTF8_BYTE_STRING_TEXT = "some text";
+ private static final ByteString UTF8_BYTE_STRING =
+ ByteString.copyFromUtf8(UTF8_BYTE_STRING_TEXT);
+ private static final ByteString NON_UTF8_BYTE_STRING =
+ ByteString.copyFrom(new byte[]{(byte) 0x80}); // A lone continuation byte.
+
+ public void testBuildRequiredStringWithGoodUtf8() throws Exception {
+ assertEquals(UTF8_BYTE_STRING_TEXT,
+ StringWrapper.newBuilder().setReqBytes(UTF8_BYTE_STRING).getReq());
+ }
+
+ public void testParseRequiredStringWithGoodUtf8() throws Exception {
+ ByteString serialized =
+ BytesWrapper.newBuilder().setReq(UTF8_BYTE_STRING).build().toByteString();
+ assertEquals(UTF8_BYTE_STRING_TEXT,
+ StringWrapper.PARSER.parseFrom(serialized).getReq());
+ }
+
+ public void testBuildRequiredStringWithBadUtf8() throws Exception {
+ try {
+ StringWrapper.newBuilder().setReqBytes(NON_UTF8_BYTE_STRING);
+ fail("Expected IllegalArgumentException for non UTF-8 byte string.");
+ } catch (IllegalArgumentException exception) {
+ assertEquals("Byte string is not UTF-8.", exception.getMessage());
+ }
+ }
+
+ public void testBuildOptionalStringWithBadUtf8() throws Exception {
+ try {
+ StringWrapper.newBuilder().setOptBytes(NON_UTF8_BYTE_STRING);
+ fail("Expected IllegalArgumentException for non UTF-8 byte string.");
+ } catch (IllegalArgumentException exception) {
+ assertEquals("Byte string is not UTF-8.", exception.getMessage());
+ }
+ }
+
+ public void testBuildRepeatedStringWithBadUtf8() throws Exception {
+ try {
+ StringWrapper.newBuilder().addRepBytes(NON_UTF8_BYTE_STRING);
+ fail("Expected IllegalArgumentException for non UTF-8 byte string.");
+ } catch (IllegalArgumentException exception) {
+ assertEquals("Byte string is not UTF-8.", exception.getMessage());
+ }
+ }
+
+ public void testParseRequiredStringWithBadUtf8() throws Exception {
+ ByteString serialized =
+ BytesWrapper.newBuilder().setReq(NON_UTF8_BYTE_STRING).build().toByteString();
+ try {
+ StringWrapper.PARSER.parseFrom(serialized);
+ fail("Expected InvalidProtocolBufferException for non UTF-8 byte string.");
+ } catch (InvalidProtocolBufferException exception) {
+ assertEquals("Protocol message had invalid UTF-8.", exception.getMessage());
+ }
+ }
+
+ public void testBuildRequiredStringWithBadUtf8Size() throws Exception {
+ try {
+ StringWrapperSize.newBuilder().setReqBytes(NON_UTF8_BYTE_STRING);
+ fail("Expected IllegalArgumentException for non UTF-8 byte string.");
+ } catch (IllegalArgumentException exception) {
+ assertEquals("Byte string is not UTF-8.", exception.getMessage());
+ }
+ }
+
+ public void testBuildOptionalStringWithBadUtf8Size() throws Exception {
+ try {
+ StringWrapperSize.newBuilder().setOptBytes(NON_UTF8_BYTE_STRING);
+ fail("Expected IllegalArgumentException for non UTF-8 byte string.");
+ } catch (IllegalArgumentException exception) {
+ assertEquals("Byte string is not UTF-8.", exception.getMessage());
+ }
+ }
+
+ public void testBuildRepeatedStringWithBadUtf8Size() throws Exception {
+ try {
+ StringWrapperSize.newBuilder().addRepBytes(NON_UTF8_BYTE_STRING);
+ fail("Expected IllegalArgumentException for non UTF-8 byte string.");
+ } catch (IllegalArgumentException exception) {
+ assertEquals("Byte string is not UTF-8.", exception.getMessage());
+ }
+ }
+
+ public void testParseRequiredStringWithBadUtf8Size() throws Exception {
+ ByteString serialized =
+ BytesWrapperSize.newBuilder().setReq(NON_UTF8_BYTE_STRING).build().toByteString();
+ try {
+ StringWrapperSize.PARSER.parseFrom(serialized);
+ fail("Expected InvalidProtocolBufferException for non UTF-8 byte string.");
+ } catch (InvalidProtocolBufferException exception) {
+ assertEquals("Protocol message had invalid UTF-8.", exception.getMessage());
+ }
+ }
+
+}
diff --git a/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java
index 33d60d1..3f656e2 100644
--- a/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java
+++ b/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -30,15 +30,20 @@
package com.google.protobuf;
+import protobuf_unittest.UnittestProto.BoolMessage;
+import protobuf_unittest.UnittestProto.Int32Message;
+import protobuf_unittest.UnittestProto.Int64Message;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestRecursiveMessage;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.FilterInputStream;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
/**
* Unit test for {@link CodedInputStream}.
@@ -85,28 +90,54 @@ public class CodedInputStreamTest extends TestCase {
}
}
+ private void assertDataConsumed(byte[] data, CodedInputStream input)
+ throws IOException {
+ assertEquals(data.length, input.getTotalBytesRead());
+ assertTrue(input.isAtEnd());
+ }
+
/**
* 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());
+ assertEquals((int) value, input.readRawVarint32());
+ assertDataConsumed(data, input);
input = CodedInputStream.newInstance(data);
assertEquals(value, input.readRawVarint64());
- assertTrue(input.isAtEnd());
+ assertDataConsumed(data, input);
+
+ input = CodedInputStream.newInstance(data);
+ assertEquals(value, input.readRawVarint64SlowPath());
+ assertDataConsumed(data, input);
+
+ input = CodedInputStream.newInstance(data);
+ assertTrue(input.skipField(WireFormat.WIRETYPE_VARINT));
+ assertDataConsumed(data, input);
// Try different block sizes.
for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
input = CodedInputStream.newInstance(
new SmallBlockInputStream(data, blockSize));
- assertEquals((int)value, input.readRawVarint32());
+ assertEquals((int) value, input.readRawVarint32());
+ assertDataConsumed(data, input);
input = CodedInputStream.newInstance(
new SmallBlockInputStream(data, blockSize));
assertEquals(value, input.readRawVarint64());
- assertTrue(input.isAtEnd());
+ assertDataConsumed(data, input);
+
+ input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(data, blockSize));
+ assertEquals(value, input.readRawVarint64SlowPath());
+ assertDataConsumed(data, input);
+
+ input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(data, blockSize));
+ assertTrue(input.skipField(WireFormat.WIRETYPE_VARINT));
+ assertDataConsumed(data, input);
}
// Try reading direct from an InputStream. We want to verify that it
@@ -115,7 +146,7 @@ public class CodedInputStreamTest extends TestCase {
byte[] longerData = new byte[data.length + 1];
System.arraycopy(data, 0, longerData, 0, data.length);
InputStream rawInput = new ByteArrayInputStream(longerData);
- assertEquals((int)value, CodedInputStream.readRawVarint32(rawInput));
+ assertEquals((int) value, CodedInputStream.readRawVarint32(rawInput));
assertEquals(1, rawInput.available());
}
@@ -143,6 +174,14 @@ public class CodedInputStreamTest extends TestCase {
assertEquals(expected.getMessage(), e.getMessage());
}
+ input = CodedInputStream.newInstance(data);
+ try {
+ input.readRawVarint64SlowPath();
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ assertEquals(expected.getMessage(), e.getMessage());
+ }
+
// Make sure we get the same error when reading direct from an InputStream.
try {
CodedInputStream.readRawVarint32(new ByteArrayInputStream(data));
@@ -311,6 +350,7 @@ public class CodedInputStreamTest extends TestCase {
}
}
+
/**
* Test that a bug in skipRawBytes() has been fixed: if the skip skips
* exactly up to a limit, this should not break things.
@@ -331,14 +371,11 @@ public class CodedInputStreamTest extends TestCase {
* that buffer, this should not break things.
*/
public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception {
- System.out.printf("testSkipRawBytesPastEndOfBufferWithLimit: E ...\n");
-
byte[] rawBytes = new byte[] { 1, 2, 3, 4, 5 };
CodedInputStream input = CodedInputStream.newInstance(
new SmallBlockInputStream(rawBytes, 3));
int limit = input.pushLimit(4);
- System.out.printf("testSkipRawBytesPastEndOfBufferWithLimit: limit=%d\n", limit);
// 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());
@@ -347,15 +384,13 @@ public class CodedInputStreamTest extends TestCase {
assertTrue(input.isAtEnd());
input.popLimit(limit);
assertEquals(5, input.readRawByte());
-
- System.out.printf("testSkipRawBytesPastEndOfBufferWithLimit: X ...\n");
}
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;
+ blob[i] = (byte) i;
}
// Make a message containing it.
@@ -442,16 +477,23 @@ public class CodedInputStreamTest extends TestCase {
}
}
+ private void checkSizeLimitExceeded(InvalidProtocolBufferException e) {
+ assertEquals(
+ InvalidProtocolBufferException.sizeLimitExceeded().getMessage(),
+ e.getMessage());
+ }
+
public void testSizeLimit() throws Exception {
CodedInputStream input = CodedInputStream.newInstance(
- TestUtil.getAllSet().toByteString().newInput());
+ new SmallBlockInputStream(
+ TestUtil.getAllSet().toByteString().newInput(), 16));
input.setSizeLimit(16);
try {
TestAllTypes.parseFrom(input);
fail("Should have thrown an exception!");
- } catch (InvalidProtocolBufferException e) {
- // success.
+ } catch (InvalidProtocolBufferException expected) {
+ checkSizeLimitExceeded(expected);
}
}
@@ -465,8 +507,8 @@ public class CodedInputStreamTest extends TestCase {
try {
input.readRawByte();
fail("Should have thrown an exception!");
- } catch (InvalidProtocolBufferException e) {
- // success.
+ } catch (InvalidProtocolBufferException expected) {
+ checkSizeLimitExceeded(expected);
}
input.resetSizeCounter();
@@ -474,28 +516,50 @@ public class CodedInputStreamTest extends TestCase {
input.readRawByte(); // No exception thrown.
input.resetSizeCounter();
assertEquals(0, input.getTotalBytesRead());
+ input.readRawBytes(16);
+ assertEquals(16, input.getTotalBytesRead());
+ input.resetSizeCounter();
try {
- input.readRawBytes(16); // Hits limit again.
+ input.readRawBytes(17); // Hits limit again.
fail("Should have thrown an exception!");
- } catch (InvalidProtocolBufferException e) {
- // success.
+ } catch (InvalidProtocolBufferException expected) {
+ checkSizeLimitExceeded(expected);
+ }
+ }
+
+ public void testSizeLimitMultipleMessages() throws Exception {
+ byte[] bytes = new byte[256];
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[i] = (byte) i;
+ }
+ CodedInputStream input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(bytes, 7));
+ input.setSizeLimit(16);
+ for (int i = 0; i < 256 / 16; i++) {
+ byte[] message = input.readRawBytes(16);
+ for (int j = 0; j < message.length; j++) {
+ assertEquals(i * 16 + j, message[j] & 0xff);
+ }
+ assertEquals(16, input.getTotalBytesRead());
+ input.resetSizeCounter();
+ assertEquals(0, input.getTotalBytesRead());
}
}
/**
- * Tests that if we read an string that contains invalid UTF-8, no exception
+ * Tests that if we readString invalid UTF-8 bytes, no exception
* is thrown. Instead, the invalid bytes are replaced with the Unicode
* "replacement character" U+FFFD.
*/
- public void testReadInvalidUtf8() throws Exception {
+ public void testReadStringInvalidUtf8() throws Exception {
ByteString.Output rawOutput = ByteString.newOutput();
CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
output.writeRawVarint32(tag);
output.writeRawVarint32(1);
- output.writeRawBytes(new byte[] { (byte)0x80 });
+ output.writeRawBytes(new byte[] { (byte) 0x80 });
output.flush();
CodedInputStream input = rawOutput.toByteString().newCodedInput();
@@ -504,13 +568,37 @@ public class CodedInputStreamTest extends TestCase {
assertEquals(0xfffd, text.charAt(0));
}
+ /**
+ * Tests that if we readStringRequireUtf8 invalid UTF-8 bytes, an
+ * InvalidProtocolBufferException is thrown.
+ */
+ public void testReadStringRequireUtf8InvalidUtf8() throws Exception {
+ ByteString.Output rawOutput = ByteString.newOutput();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+
+ int tag = WireFormat.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());
+ try {
+ input.readStringRequireUtf8();
+ fail("Expected invalid UTF-8 exception.");
+ } catch (InvalidProtocolBufferException exception) {
+ assertEquals("Protocol message had invalid UTF-8.", exception.getMessage());
+ }
+ }
+
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());
+ assertEquals(i - 2, in.getTotalBytesRead());
}
// eof
assertEquals(0, in.readTag());
@@ -530,4 +618,152 @@ public class CodedInputStreamTest extends TestCase {
}
}
}
+
+ public void testReadByteArray() throws Exception {
+ ByteString.Output rawOutput = ByteString.newOutput();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+ // Zero-sized bytes field.
+ output.writeRawVarint32(0);
+ // One one-byte bytes field
+ output.writeRawVarint32(1);
+ output.writeRawBytes(new byte[] { (byte) 23 });
+ // Another one-byte bytes field
+ output.writeRawVarint32(1);
+ output.writeRawBytes(new byte[] { (byte) 45 });
+ // A bytes field large enough that won't fit into the 4K buffer.
+ final int bytesLength = 16 * 1024;
+ byte[] bytes = new byte[bytesLength];
+ bytes[0] = (byte) 67;
+ bytes[bytesLength - 1] = (byte) 89;
+ output.writeRawVarint32(bytesLength);
+ output.writeRawBytes(bytes);
+
+ output.flush();
+ CodedInputStream inputStream = rawOutput.toByteString().newCodedInput();
+
+ byte[] result = inputStream.readByteArray();
+ assertEquals(0, result.length);
+ result = inputStream.readByteArray();
+ assertEquals(1, result.length);
+ assertEquals((byte) 23, result[0]);
+ result = inputStream.readByteArray();
+ assertEquals(1, result.length);
+ assertEquals((byte) 45, result[0]);
+ result = inputStream.readByteArray();
+ assertEquals(bytesLength, result.length);
+ assertEquals((byte) 67, result[0]);
+ assertEquals((byte) 89, result[bytesLength - 1]);
+ }
+
+ public void testReadByteBuffer() throws Exception {
+ ByteString.Output rawOutput = ByteString.newOutput();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+ // Zero-sized bytes field.
+ output.writeRawVarint32(0);
+ // One one-byte bytes field
+ output.writeRawVarint32(1);
+ output.writeRawBytes(new byte[]{(byte) 23});
+ // Another one-byte bytes field
+ output.writeRawVarint32(1);
+ output.writeRawBytes(new byte[]{(byte) 45});
+ // A bytes field large enough that won't fit into the 4K buffer.
+ final int bytesLength = 16 * 1024;
+ byte[] bytes = new byte[bytesLength];
+ bytes[0] = (byte) 67;
+ bytes[bytesLength - 1] = (byte) 89;
+ output.writeRawVarint32(bytesLength);
+ output.writeRawBytes(bytes);
+
+ output.flush();
+ CodedInputStream inputStream = rawOutput.toByteString().newCodedInput();
+
+ ByteBuffer result = inputStream.readByteBuffer();
+ assertEquals(0, result.capacity());
+ result = inputStream.readByteBuffer();
+ assertEquals(1, result.capacity());
+ assertEquals((byte) 23, result.get());
+ result = inputStream.readByteBuffer();
+ assertEquals(1, result.capacity());
+ assertEquals((byte) 45, result.get());
+ result = inputStream.readByteBuffer();
+ assertEquals(bytesLength, result.capacity());
+ assertEquals((byte) 67, result.get());
+ result.position(bytesLength - 1);
+ assertEquals((byte) 89, result.get());
+ }
+
+ public void testReadByteBufferAliasing() throws Exception {
+ ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
+ CodedOutputStream output = CodedOutputStream.newInstance(byteArrayStream);
+ // Zero-sized bytes field.
+ output.writeRawVarint32(0);
+ // One one-byte bytes field
+ output.writeRawVarint32(1);
+ output.writeRawBytes(new byte[]{(byte) 23});
+ // Another one-byte bytes field
+ output.writeRawVarint32(1);
+ output.writeRawBytes(new byte[]{(byte) 45});
+ // A bytes field large enough that won't fit into the 4K buffer.
+ final int bytesLength = 16 * 1024;
+ byte[] bytes = new byte[bytesLength];
+ bytes[0] = (byte) 67;
+ bytes[bytesLength - 1] = (byte) 89;
+ output.writeRawVarint32(bytesLength);
+ output.writeRawBytes(bytes);
+ output.flush();
+ byte[] data = byteArrayStream.toByteArray();
+
+ // Without aliasing
+ CodedInputStream inputStream = CodedInputStream.newInstance(data);
+ ByteBuffer result = inputStream.readByteBuffer();
+ assertEquals(0, result.capacity());
+ result = inputStream.readByteBuffer();
+ assertTrue(result.array() != data);
+ assertEquals(1, result.capacity());
+ assertEquals((byte) 23, result.get());
+ result = inputStream.readByteBuffer();
+ assertTrue(result.array() != data);
+ assertEquals(1, result.capacity());
+ assertEquals((byte) 45, result.get());
+ result = inputStream.readByteBuffer();
+ assertTrue(result.array() != data);
+ assertEquals(bytesLength, result.capacity());
+ assertEquals((byte) 67, result.get());
+ result.position(bytesLength - 1);
+ assertEquals((byte) 89, result.get());
+
+ // Enable aliasing
+ inputStream = CodedInputStream.newInstance(data);
+ inputStream.enableAliasing(true);
+ result = inputStream.readByteBuffer();
+ assertEquals(0, result.capacity());
+ result = inputStream.readByteBuffer();
+ assertTrue(result.array() == data);
+ assertEquals(1, result.capacity());
+ assertEquals((byte) 23, result.get());
+ result = inputStream.readByteBuffer();
+ assertTrue(result.array() == data);
+ assertEquals(1, result.capacity());
+ assertEquals((byte) 45, result.get());
+ result = inputStream.readByteBuffer();
+ assertTrue(result.array() == data);
+ assertEquals(bytesLength, result.capacity());
+ assertEquals((byte) 67, result.get());
+ result.position(bytesLength - 1);
+ assertEquals((byte) 89, result.get());
+ }
+
+ public void testCompatibleTypes() throws Exception {
+ long data = 0x100000000L;
+ Int64Message message = Int64Message.newBuilder().setData(data).build();
+ ByteString serialized = message.toByteString();
+
+ // Test int64(long) is compatible with bool(boolean)
+ BoolMessage msg2 = BoolMessage.parseFrom(serialized);
+ assertTrue(msg2.getData());
+
+ // Test int64(long) is compatible with int32(int)
+ Int32Message msg3 = Int32Message.parseFrom(serialized);
+ assertEquals((int) data, msg3.getData());
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java b/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
index c42b485..0785cc9 100644
--- a/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
+++ b/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -30,14 +30,16 @@
package com.google.protobuf;
+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.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
/**
@@ -301,4 +303,99 @@ public class CodedOutputStreamTest extends TestCase {
assertEqualBytes(TestUtil.getGoldenPackedFieldsMessage().toByteArray(),
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);
+ byte[] rawBytes = message.toByteArray();
+ 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("UTF-8");
+ for (int i = 0; i < 1024; ++i) {
+ codedStream.writeRawBytes(value, 0, value.length);
+ }
+ // Make sure we have written more bytes than the buffer could hold. This is
+ // to make the test complete.
+ assertTrue(codedStream.getTotalBytesWritten() > BUFFER_SIZE);
+ assertEquals(value.length * 1024, codedStream.getTotalBytesWritten());
+ }
+
+ 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("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());
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java b/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java
new file mode 100644
index 0000000..e7905f7
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java
@@ -0,0 +1,80 @@
+// 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.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/src/test/java/com/google/protobuf/DescriptorsTest.java b/java/src/test/java/com/google/protobuf/DescriptorsTest.java
index f41d070..0092771 100644
--- a/java/src/test/java/com/google/protobuf/DescriptorsTest.java
+++ b/java/src/test/java/com/google/protobuf/DescriptorsTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -31,12 +31,15 @@
package 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.OneofDescriptor;
import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.ServiceDescriptor;
@@ -51,15 +54,19 @@ import protobuf_unittest.UnittestProto.ForeignMessage;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestExtremeDefaultValues;
+import protobuf_unittest.UnittestProto.TestMultipleExtensionRanges;
import protobuf_unittest.UnittestProto.TestRequired;
import protobuf_unittest.UnittestProto.TestService;
import protobuf_unittest.UnittestCustomOptions;
+import protobuf_unittest.TestCustomOptions;
+
import junit.framework.TestCase;
import java.util.Arrays;
import java.util.Collections;
+import java.util.List;
/**
* Unit test for {@link Descriptors}.
@@ -71,6 +78,7 @@ 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 {
@@ -304,6 +312,7 @@ public class DescriptorsTest extends TestCase {
EnumValueDescriptor value = ForeignEnum.FOREIGN_FOO.getValueDescriptor();
assertEquals(value, enumType.getValues().get(0));
assertEquals("FOREIGN_FOO", value.getName());
+ assertEquals("FOREIGN_FOO", value.toString());
assertEquals(4, value.getNumber());
assertEquals(value, enumType.findValueByName("FOREIGN_FOO"));
assertEquals(value, enumType.findValueByNumber(4));
@@ -320,7 +329,6 @@ public class DescriptorsTest extends TestCase {
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());
@@ -347,8 +355,12 @@ public class DescriptorsTest extends TestCase {
public void testCustomOptions() throws Exception {
+ // Get the descriptor indirectly from a dependent proto class. This is to
+ // ensure that when a proto class is loaded, custom options defined in its
+ // dependencies are also properly initialized.
Descriptor descriptor =
- UnittestCustomOptions.TestMessageWithCustomOptions.getDescriptor();
+ TestCustomOptions.TestMessageWithCustomOptionsContainer.getDescriptor()
+ .findFieldByName("field").getMessageType();
assertTrue(
descriptor.getOptions().hasExtension(UnittestCustomOptions.messageOpt1));
@@ -425,7 +437,7 @@ public class DescriptorsTest extends TestCase {
UnittestEnormousDescriptor.getDescriptor()
.toProto().getSerializedSize() > 65536);
}
-
+
/**
* Tests that the DescriptorValidationException works as intended.
*/
@@ -444,7 +456,7 @@ public class DescriptorsTest extends TestCase {
.build())
.build();
try {
- Descriptors.FileDescriptor.buildFrom(fileDescriptorProto,
+ Descriptors.FileDescriptor.buildFrom(fileDescriptorProto,
new FileDescriptor[0]);
fail("DescriptorValidationException expected");
} catch (DescriptorValidationException e) {
@@ -456,4 +468,268 @@ public class DescriptorsTest extends TestCase {
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 testDependencyOrder() throws Exception {
+ FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
+ .setName("foo.proto").build();
+ FileDescriptorProto barProto = FileDescriptorProto.newBuilder()
+ .setName("bar.proto")
+ .addDependency("foo.proto")
+ .build();
+ FileDescriptorProto bazProto = FileDescriptorProto.newBuilder()
+ .setName("baz.proto")
+ .addDependency("foo.proto")
+ .addDependency("bar.proto")
+ .addPublicDependency(0)
+ .addPublicDependency(1)
+ .build();
+ FileDescriptor fooFile = Descriptors.FileDescriptor.buildFrom(fooProto,
+ new FileDescriptor[0]);
+ FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom(barProto,
+ new FileDescriptor[] {fooFile});
+
+ // Items in the FileDescriptor array can be in any order.
+ Descriptors.FileDescriptor.buildFrom(bazProto,
+ new FileDescriptor[] {fooFile, barFile});
+ Descriptors.FileDescriptor.buildFrom(bazProto,
+ new FileDescriptor[] {barFile, fooFile});
+ }
+
+ 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"));
+ }
+ }
+
+ public void testOneofDescriptor() throws Exception {
+ Descriptor messageType = TestAllTypes.getDescriptor();
+ FieldDescriptor field =
+ messageType.findFieldByName("oneof_nested_message");
+ OneofDescriptor oneofDescriptor = field.getContainingOneof();
+ assertNotNull(oneofDescriptor);
+ assertSame(oneofDescriptor, messageType.getOneofs().get(0));
+ assertEquals("oneof_field", oneofDescriptor.getName());
+
+ assertEquals(4, oneofDescriptor.getFieldCount());
+ assertSame(oneofDescriptor.getField(1), field);
+ }
+
+ public void testMessageDescriptorExtensions() throws Exception {
+ assertFalse(TestAllTypes.getDescriptor().isExtendable());
+ assertTrue(TestAllExtensions.getDescriptor().isExtendable());
+ assertTrue(TestMultipleExtensionRanges.getDescriptor().isExtendable());
+
+ assertFalse(TestAllTypes.getDescriptor().isExtensionNumber(3));
+ assertTrue(TestAllExtensions.getDescriptor().isExtensionNumber(3));
+ assertTrue(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(42));
+ assertFalse(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(43));
+ assertFalse(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(4142));
+ assertTrue(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(4143));
+ }
+
+ public void testPackedEnumField() throws Exception {
+ FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder()
+ .setName("foo.proto")
+ .addEnumType(EnumDescriptorProto.newBuilder()
+ .setName("Enum")
+ .addValue(EnumValueDescriptorProto.newBuilder()
+ .setName("FOO")
+ .setNumber(1)
+ .build())
+ .build())
+ .addMessageType(DescriptorProto.newBuilder()
+ .setName("Message")
+ .addField(FieldDescriptorProto.newBuilder()
+ .setName("foo")
+ .setTypeName("Enum")
+ .setNumber(1)
+ .setLabel(FieldDescriptorProto.Label.LABEL_REPEATED)
+ .setOptions(DescriptorProtos.FieldOptions.newBuilder()
+ .setPacked(true)
+ .build())
+ .build())
+ .build())
+ .build();
+ Descriptors.FileDescriptor.buildFrom(
+ fileDescriptorProto, new FileDescriptor[0]);
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/DynamicMessageTest.java b/java/src/test/java/com/google/protobuf/DynamicMessageTest.java
index aabccda..55144e7 100644
--- a/java/src/test/java/com/google/protobuf/DynamicMessageTest.java
+++ b/java/src/test/java/com/google/protobuf/DynamicMessageTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -30,8 +30,13 @@
package com.google.protobuf;
-import protobuf_unittest.UnittestProto.TestAllTypes;
+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;
@@ -61,28 +66,44 @@ public class DynamicMessageTest extends TestCase {
reflectionTester.assertAllFieldsSetViaReflection(message);
}
- public void testDoubleBuildError() throws Exception {
+ public void testSettersAfterBuild() throws Exception {
Message.Builder builder =
DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ Message firstMessage = builder.build();
+ // double build()
builder.build();
- try {
- builder.build();
- fail("Should have thrown exception.");
- } catch (IllegalStateException e) {
- // Success.
- }
+ // 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 testClearAfterBuildError() throws Exception {
+ public void testUnknownFields() throws Exception {
Message.Builder builder =
- DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
- builder.build();
- try {
- builder.clear();
- fail("Should have thrown exception.");
- } catch (IllegalStateException e) {
- // Success.
- }
+ 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 {
@@ -167,6 +188,23 @@ public class DynamicMessageTest extends TestCase {
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 {
@@ -194,6 +232,10 @@ public class DynamicMessageTest extends TestCase {
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 {
@@ -203,6 +245,19 @@ public class DynamicMessageTest extends TestCase {
DynamicMessage copy = DynamicMessage.newBuilder(message).build();
reflectionTester.assertAllFieldsSetViaReflection(copy);
+
+ // Test oneof behavior
+ FieldDescriptor bytesField =
+ TestAllTypes.getDescriptor().findFieldByName("oneof_bytes");
+ FieldDescriptor uint32Field =
+ TestAllTypes.getDescriptor().findFieldByName("oneof_uint32");
+ assertTrue(copy.hasField(bytesField));
+ assertFalse(copy.hasField(uint32Field));
+ DynamicMessage copy2 =
+ DynamicMessage.newBuilder(message).setField(uint32Field, 123).build();
+ assertFalse(copy2.hasField(bytesField));
+ assertTrue(copy2.hasField(uint32Field));
+ assertEquals(123, copy2.getField(uint32Field));
}
public void testToBuilder() throws Exception {
@@ -223,4 +278,49 @@ public class DynamicMessageTest extends TestCase {
assertEquals(Arrays.asList(unknownFieldVal),
derived.getUnknownFields().getField(unknownFieldNum).getVarintList());
}
+
+ public void testDynamicOneofMessage() throws Exception {
+ DynamicMessage.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ OneofDescriptor oneof = TestAllTypes.getDescriptor().getOneofs().get(0);
+ assertFalse(builder.hasOneof(oneof));
+ assertSame(null, builder.getOneofFieldDescriptor(oneof));
+
+ reflectionTester.setAllFieldsViaReflection(builder);
+ assertTrue(builder.hasOneof(oneof));
+ FieldDescriptor field = oneof.getField(3);
+ assertSame(field, builder.getOneofFieldDescriptor(oneof));
+
+ DynamicMessage message = builder.buildPartial();
+ assertTrue(message.hasOneof(oneof));
+
+ DynamicMessage.Builder mergedBuilder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ FieldDescriptor mergedField = oneof.getField(0);
+ mergedBuilder.setField(mergedField, 123);
+ assertTrue(mergedBuilder.hasField(mergedField));
+ mergedBuilder.mergeFrom(message);
+ assertTrue(mergedBuilder.hasField(field));
+ assertFalse(mergedBuilder.hasField(mergedField));
+
+ builder.clearOneof(oneof);
+ assertSame(null, builder.getOneofFieldDescriptor(oneof));
+ message = builder.build();
+ assertSame(null, message.getOneofFieldDescriptor(oneof));
+ }
+
+ // Regression test for a bug that makes setField() not work for repeated
+ // enum fields.
+ public void testSettersForRepeatedEnumField() throws Exception {
+ DynamicMessage.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ FieldDescriptor repeatedEnumField =
+ TestAllTypes.getDescriptor().findFieldByName(
+ "repeated_nested_enum");
+ EnumDescriptor enumDescriptor = TestAllTypes.NestedEnum.getDescriptor();
+ builder.setField(repeatedEnumField, enumDescriptor.getValues());
+ DynamicMessage message = builder.build();
+ assertEquals(
+ enumDescriptor.getValues(), message.getField(repeatedEnumField));
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java b/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java
new file mode 100644
index 0000000..a92ba37
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java
@@ -0,0 +1,48 @@
+// 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 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/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
index 73c71f3..0b3482c 100644
--- a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
+++ b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -30,26 +30,51 @@
package com.google.protobuf;
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
+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.NestedExtensionLite.MyNestedExtensionLite;
+import protobuf_unittest.NonNestedExtension;
+import protobuf_unittest.NonNestedExtension.MessageToBeExtended;
+import protobuf_unittest.NonNestedExtension.MyNonNestedExtension;
+import protobuf_unittest.NonNestedExtensionLite;
+import protobuf_unittest.NonNestedExtensionLite.MessageLiteToBeExtended;
+import protobuf_unittest.NonNestedExtensionLite.MyNonNestedExtensionLite;
+import protobuf_unittest.OuterClassNameTest2OuterClass;
+import protobuf_unittest.OuterClassNameTest3OuterClass;
+import protobuf_unittest.OuterClassNameTestOuterClass;
+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.ForeignMessage;
import protobuf_unittest.UnittestProto.ForeignEnum;
-import protobuf_unittest.UnittestProto.TestAllTypes;
+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.TestOneof2;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestProto.TestUnpackedTypes;
-import protobuf_unittest.MultipleFilesTestProto;
-import protobuf_unittest.MessageWithNoOuter;
-import protobuf_unittest.EnumWithNoOuter;
-import protobuf_unittest.ServiceWithNoOuter;
-import com.google.protobuf.UnittestLite;
-import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
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.Iterator;
+import java.util.List;
/**
* Unit test for generated messages and generated code. See also
@@ -68,32 +93,138 @@ public class GeneratedMessageTest extends TestCase {
TestAllTypes.newBuilder().getDefaultInstanceForType());
}
- public void testAccessors() throws Exception {
+ public void testMessageOrBuilder() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
TestUtil.setAllFields(builder);
TestAllTypes message = builder.build();
TestUtil.assertAllFieldsSet(message);
}
- public void testDoubleBuildError() throws Exception {
+ public void testUsingBuilderMultipleTimes() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
- builder.build();
- try {
- builder.build();
- fail("Should have thrown exception.");
- } catch (IllegalStateException e) {
- // Success.
- }
+ // 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 testClearAfterBuildError() throws Exception {
+ public void testProtosShareRepeatedArraysIfDidntChange() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
- builder.build();
- try {
- builder.clear();
- fail("Should have thrown exception.");
- } catch (IllegalStateException e) {
- // Success.
+ builder.addRepeatedInt32(100);
+ builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
+ builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance());
+
+ TestAllTypes value1 = builder.build();
+ TestAllTypes value2 = value1.toBuilder().build();
+
+ assertSame(value1.getRepeatedInt32List(), value2.getRepeatedInt32List());
+ assertSame(value1.getRepeatedImportEnumList(),
+ value2.getRepeatedImportEnumList());
+ assertSame(value1.getRepeatedForeignMessageList(),
+ value2.getRepeatedForeignMessageList());
+ }
+
+ 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
+ }
}
}
@@ -273,6 +404,44 @@ public class GeneratedMessageTest extends TestCase {
// We expect this exception.
}
}
+
+ public void testRepeatedAppendIterateOnlyOnce() throws Exception {
+ // Create a Iterable that can only be iterated once.
+ Iterable<String> stringIterable = new Iterable<String>() {
+ private boolean called = false;
+ @Override
+ public Iterator<String> iterator() {
+ if (called) {
+ throw new IllegalStateException();
+ }
+ called = true;
+ return Arrays.asList("one", "two", "three").iterator();
+ }
+ };
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ builder.addAllRepeatedString(stringIterable);
+ assertEquals(3, builder.getRepeatedStringCount());
+ assertEquals("one", builder.getRepeatedString(0));
+ assertEquals("two", builder.getRepeatedString(1));
+ assertEquals("three", builder.getRepeatedString(2));
+
+ try {
+ builder.addAllRepeatedString(stringIterable);
+ fail("Exception was not thrown");
+ } catch (IllegalStateException e) {
+ // We expect this exception.
+ }
+ }
+
+ public void testMergeFromOtherRejectsNull() throws Exception {
+ try {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ builder.mergeFrom((TestAllTypes) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
public void testSettingForeignMessageUsingBuilder() throws Exception {
TestAllTypes message = TestAllTypes.newBuilder()
@@ -314,11 +483,22 @@ public class GeneratedMessageTest extends TestCase {
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);
}
@@ -326,6 +506,8 @@ public class GeneratedMessageTest extends TestCase {
public void testReflectionSetters() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
reflectionTester.setAllFieldsViaReflection(builder);
+ TestUtil.assertAllFieldsSet(builder);
+
TestAllTypes message = builder.build();
TestUtil.assertAllFieldsSet(message);
}
@@ -339,6 +521,8 @@ public class GeneratedMessageTest extends TestCase {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
reflectionTester.setAllFieldsViaReflection(builder);
reflectionTester.modifyRepeatedFieldsViaReflection(builder);
+ TestUtil.assertRepeatedFieldsModified(builder);
+
TestAllTypes message = builder.build();
TestUtil.assertRepeatedFieldsModified(message);
}
@@ -355,6 +539,34 @@ public class GeneratedMessageTest extends TestCase {
TestAllTypes.newBuilder().build());
}
+ public void testReflectionGetOneof() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ reflectionTester.setAllFieldsViaReflection(builder);
+ Descriptors.OneofDescriptor oneof =
+ TestAllTypes.getDescriptor().getOneofs().get(0);
+ Descriptors.FieldDescriptor field =
+ TestAllTypes.getDescriptor().findFieldByName("oneof_bytes");
+ assertSame(field, builder.getOneofFieldDescriptor(oneof));
+
+ TestAllTypes message = builder.build();
+ assertSame(field, message.getOneofFieldDescriptor(oneof));
+ }
+
+ public void testReflectionClearOneof() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ reflectionTester.setAllFieldsViaReflection(builder);
+ Descriptors.OneofDescriptor oneof =
+ TestAllTypes.getDescriptor().getOneofs().get(0);
+ Descriptors.FieldDescriptor field =
+ TestAllTypes.getDescriptor().findFieldByName("oneof_bytes");
+
+ assertTrue(builder.hasOneof(oneof));
+ assertTrue(builder.hasField(field));
+ builder.clearOneof(oneof);
+ assertFalse(builder.hasOneof(oneof));
+ assertFalse(builder.hasField(field));
+ }
+
public void testEnumInterface() throws Exception {
assertTrue(TestAllTypes.getDefaultInstance().getDefaultNestedEnum()
instanceof ProtocolMessageEnum);
@@ -391,7 +603,7 @@ public class GeneratedMessageTest extends TestCase {
new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
TestUtil.getExtensionRegistry());
- public void testExtensionAccessors() throws Exception {
+ public void testExtensionMessageOrBuilder() throws Exception {
TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
TestUtil.setAllExtensions(builder);
TestAllExtensions message = builder.build();
@@ -414,6 +626,8 @@ public class GeneratedMessageTest extends TestCase {
public void testExtensionReflectionGetters() throws Exception {
TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
TestUtil.setAllExtensions(builder);
+ extensionsReflectionTester.assertAllFieldsSetViaReflection(builder);
+
TestAllExtensions message = builder.build();
extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
}
@@ -421,6 +635,8 @@ public class GeneratedMessageTest extends TestCase {
public void testExtensionReflectionSetters() throws Exception {
TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
extensionsReflectionTester.setAllFieldsViaReflection(builder);
+ TestUtil.assertAllExtensionsSet(builder);
+
TestAllExtensions message = builder.build();
TestUtil.assertAllExtensionsSet(message);
}
@@ -434,6 +650,8 @@ public class GeneratedMessageTest extends TestCase {
TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
extensionsReflectionTester.setAllFieldsViaReflection(builder);
extensionsReflectionTester.modifyRepeatedFieldsViaReflection(builder);
+ TestUtil.assertRepeatedExtensionsModified(builder);
+
TestAllExtensions message = builder.build();
TestUtil.assertRepeatedExtensionsModified(message);
}
@@ -491,9 +709,11 @@ public class GeneratedMessageTest extends TestCase {
// lite fields directly since they are implemented exactly the same as
// regular fields.
- public void testLiteExtensionAccessors() throws Exception {
+ public void testLiteExtensionMessageOrBuilder() throws Exception {
TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
TestUtil.setAllExtensions(builder);
+ TestUtil.assertAllExtensionsSet(builder);
+
TestAllExtensionsLite message = builder.build();
TestUtil.assertAllExtensionsSet(message);
}
@@ -502,6 +722,8 @@ public class GeneratedMessageTest extends TestCase {
TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
TestUtil.setAllExtensions(builder);
TestUtil.modifyRepeatedExtensions(builder);
+ TestUtil.assertRepeatedExtensionsModified(builder);
+
TestAllExtensionsLite message = builder.build();
TestUtil.assertRepeatedExtensionsModified(message);
}
@@ -546,6 +768,15 @@ public class GeneratedMessageTest extends TestCase {
// =================================================================
// multiple_files_test
+ // Test that custom options of an file level enum are properly initialized.
+ // This test needs to be put before any other access to MultipleFilesTestProto
+ // or messages defined in multiple_files_test.proto because the class loading
+ // order affects initialization process of custom options.
+ public void testEnumValueOptionsInMultipleFilesMode() throws Exception {
+ assertEquals(12345, EnumWithNoOuter.FOO.getValueDescriptor().getOptions()
+ .getExtension(MultipleFilesTestProto.enumValueOption).intValue());
+ }
+
public void testMultipleFilesOption() throws Exception {
// We mostly just want to check that things compile.
MessageWithNoOuter message =
@@ -609,6 +840,7 @@ public class GeneratedMessageTest extends TestCase {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
TestUtil.setAllFields(builder);
TestAllTypes message = builder.build();
+ TestUtil.assertAllFieldsSet(message);
TestUtil.assertAllFieldsSet(message.toBuilder().build());
}
@@ -643,7 +875,641 @@ public class GeneratedMessageTest extends TestCase {
UnittestProto.TestRecursiveMessage message =
UnittestProto.TestRecursiveMessage.getDefaultInstance();
assertTrue(message != null);
- assertTrue(message.getA() != null);
+ assertNotNull(message.getA());
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 testNonNestedExtensionLiteInitialization() {
+ assertTrue(NonNestedExtensionLite.nonNestedExtensionLite
+ .getMessageDefaultInstance() instanceof MyNonNestedExtensionLite);
+ }
+
+ public void testNestedExtensionLiteInitialization() {
+ assertTrue(MyNestedExtensionLite.recursiveExtensionLite
+ .getMessageDefaultInstance() instanceof MessageLiteToBeExtended);
+ }
+
+ public void testInvalidations() throws Exception {
+ GeneratedMessage.enableAlwaysUseFieldBuildersForTesting();
+ TestAllTypes.NestedMessage nestedMessage1 =
+ TestAllTypes.NestedMessage.newBuilder().build();
+ TestAllTypes.NestedMessage nestedMessage2 =
+ TestAllTypes.NestedMessage.newBuilder().build();
+
+ // Set all three flavors (enum, primitive, message and singular/repeated)
+ // and verify no invalidations fired
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+
+ TestAllTypes.Builder builder = (TestAllTypes.Builder)
+ ((GeneratedMessage) TestAllTypes.getDefaultInstance()).
+ newBuilderForType(mockParent);
+ builder.setOptionalInt32(1);
+ builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR);
+ builder.setOptionalNestedMessage(nestedMessage1);
+ builder.addRepeatedInt32(1);
+ builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR);
+ builder.addRepeatedNestedMessage(nestedMessage1);
+ assertEquals(0, mockParent.getInvalidationCount());
+
+ // Now tell it we want changes and make sure it's only fired once
+ // And do this for each flavor
+
+ // primitive single
+ builder.buildPartial();
+ builder.setOptionalInt32(2);
+ builder.setOptionalInt32(3);
+ assertEquals(1, mockParent.getInvalidationCount());
+
+ // enum single
+ builder.buildPartial();
+ builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAZ);
+ builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR);
+ assertEquals(2, mockParent.getInvalidationCount());
+
+ // message single
+ builder.buildPartial();
+ builder.setOptionalNestedMessage(nestedMessage2);
+ builder.setOptionalNestedMessage(nestedMessage1);
+ assertEquals(3, mockParent.getInvalidationCount());
+
+ // primitive repeated
+ builder.buildPartial();
+ builder.addRepeatedInt32(2);
+ builder.addRepeatedInt32(3);
+ assertEquals(4, mockParent.getInvalidationCount());
+
+ // enum repeated
+ builder.buildPartial();
+ builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ);
+ builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ);
+ assertEquals(5, mockParent.getInvalidationCount());
+
+ // message repeated
+ builder.buildPartial();
+ builder.addRepeatedNestedMessage(nestedMessage2);
+ builder.addRepeatedNestedMessage(nestedMessage1);
+ assertEquals(6, mockParent.getInvalidationCount());
+
+ }
+
+ public void testInvalidations_Extensions() throws Exception {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+
+ TestAllExtensions.Builder builder = (TestAllExtensions.Builder)
+ ((GeneratedMessage) TestAllExtensions.getDefaultInstance()).
+ newBuilderForType(mockParent);
+
+ builder.addExtension(UnittestProto.repeatedInt32Extension, 1);
+ builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 2);
+ builder.clearExtension(UnittestProto.repeatedInt32Extension);
+ assertEquals(0, mockParent.getInvalidationCount());
+
+ // Now tell it we want changes and make sure it's only fired once
+ builder.buildPartial();
+ builder.addExtension(UnittestProto.repeatedInt32Extension, 2);
+ builder.addExtension(UnittestProto.repeatedInt32Extension, 3);
+ assertEquals(1, mockParent.getInvalidationCount());
+
+ builder.buildPartial();
+ builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 4);
+ builder.setExtension(UnittestProto.repeatedInt32Extension, 1, 5);
+ assertEquals(2, mockParent.getInvalidationCount());
+
+ builder.buildPartial();
+ builder.clearExtension(UnittestProto.repeatedInt32Extension);
+ builder.clearExtension(UnittestProto.repeatedInt32Extension);
+ assertEquals(3, mockParent.getInvalidationCount());
+ }
+
+ 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.
+ }
+ }
+
+ // Test that when the default outer class name conflicts with another type
+ // defined in the proto the compiler will append a suffix to avoid the
+ // conflict.
+ public void testConflictingOuterClassName() {
+ // We just need to make sure we can refer to the outer class with the
+ // expected name. There is nothing else to test.
+ OuterClassNameTestOuterClass.OuterClassNameTest message =
+ OuterClassNameTestOuterClass.OuterClassNameTest.newBuilder().build();
+ assertTrue(message.getDescriptorForType() ==
+ OuterClassNameTestOuterClass.OuterClassNameTest.getDescriptor());
+
+ OuterClassNameTest2OuterClass.TestMessage2.NestedMessage.OuterClassNameTest2
+ message2 = OuterClassNameTest2OuterClass.TestMessage2.NestedMessage
+ .OuterClassNameTest2.newBuilder().build();
+ assertEquals(0, message2.getSerializedSize());
+
+ OuterClassNameTest3OuterClass.TestMessage3.NestedMessage.OuterClassNameTest3
+ enumValue = OuterClassNameTest3OuterClass.TestMessage3.NestedMessage
+ .OuterClassNameTest3.DUMMY_VALUE;
+ assertEquals(1, enumValue.getNumber());
+ }
+
+ // =================================================================
+ // oneof generated code test
+ public void testOneofEnumCase() throws Exception {
+ TestOneof2 message = TestOneof2.newBuilder()
+ .setFooInt(123).setFooString("foo").setFooCord("bar").build();
+ TestUtil.assertAtMostOneFieldSetOneof(message);
+ }
+
+ public void testClearOneof() throws Exception {
+ TestOneof2.Builder builder = TestOneof2.newBuilder().setFooInt(123);
+ assertEquals(TestOneof2.FooCase.FOO_INT, builder.getFooCase());
+ builder.clearFoo();
+ assertEquals(TestOneof2.FooCase.FOO_NOT_SET, builder.getFooCase());
+ }
+
+ public void testSetOneofClearsOthers() throws Exception {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ TestOneof2 message =
+ builder.setFooInt(123).setFooString("foo").buildPartial();
+ assertTrue(message.hasFooString());
+ TestUtil.assertAtMostOneFieldSetOneof(message);
+
+ message = builder.setFooCord("bar").buildPartial();
+ assertTrue(message.hasFooCord());
+ TestUtil.assertAtMostOneFieldSetOneof(message);
+
+ message = builder.setFooStringPiece("baz").buildPartial();
+ assertTrue(message.hasFooStringPiece());
+ TestUtil.assertAtMostOneFieldSetOneof(message);
+
+ message = builder.setFooBytes(TestUtil.toBytes("qux")).buildPartial();
+ assertTrue(message.hasFooBytes());
+ TestUtil.assertAtMostOneFieldSetOneof(message);
+
+ message = builder.setFooEnum(TestOneof2.NestedEnum.FOO).buildPartial();
+ assertTrue(message.hasFooEnum());
+ TestUtil.assertAtMostOneFieldSetOneof(message);
+
+ message = builder.setFooMessage(
+ TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()).buildPartial();
+ assertTrue(message.hasFooMessage());
+ TestUtil.assertAtMostOneFieldSetOneof(message);
+
+ message = builder.setFooInt(123).buildPartial();
+ assertTrue(message.hasFooInt());
+ TestUtil.assertAtMostOneFieldSetOneof(message);
+ }
+
+ public void testOneofTypes() throws Exception {
+ // Primitive
+ {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ assertEquals(builder.getFooInt(), 0);
+ assertFalse(builder.hasFooInt());
+ assertTrue(builder.setFooInt(123).hasFooInt());
+ assertEquals(builder.getFooInt(), 123);
+ TestOneof2 message = builder.buildPartial();
+ assertTrue(message.hasFooInt());
+ assertEquals(message.getFooInt(), 123);
+
+ assertFalse(builder.clearFooInt().hasFooInt());
+ TestOneof2 message2 = builder.build();
+ assertFalse(message2.hasFooInt());
+ assertEquals(message2.getFooInt(), 0);
+ }
+
+ // Enum
+ {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ assertEquals(builder.getFooEnum(), TestOneof2.NestedEnum.FOO);
+ assertTrue(builder.setFooEnum(TestOneof2.NestedEnum.BAR).hasFooEnum());
+ assertEquals(builder.getFooEnum(), TestOneof2.NestedEnum.BAR);
+ TestOneof2 message = builder.buildPartial();
+ assertTrue(message.hasFooEnum());
+ assertEquals(message.getFooEnum(), TestOneof2.NestedEnum.BAR);
+
+ assertFalse(builder.clearFooEnum().hasFooEnum());
+ TestOneof2 message2 = builder.build();
+ assertFalse(message2.hasFooEnum());
+ assertEquals(message2.getFooEnum(), TestOneof2.NestedEnum.FOO);
+ }
+
+ // String
+ {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ assertEquals(builder.getFooString(), "");
+ builder.setFooString("foo");
+ assertTrue(builder.hasFooString());
+ assertEquals(builder.getFooString(), "foo");
+ TestOneof2 message = builder.buildPartial();
+ assertTrue(message.hasFooString());
+ assertEquals(message.getFooString(), "foo");
+ assertEquals(message.getFooStringBytes(), TestUtil.toBytes("foo"));
+
+ assertFalse(builder.clearFooString().hasFooString());
+ TestOneof2 message2 = builder.buildPartial();
+ assertFalse(message2.hasFooString());
+ assertEquals(message2.getFooString(), "");
+ assertEquals(message2.getFooStringBytes(), TestUtil.toBytes(""));
+
+ // Get method should not change the oneof value.
+ builder.setFooInt(123);
+ assertEquals(builder.getFooString(), "");
+ assertEquals(builder.getFooStringBytes(), TestUtil.toBytes(""));
+ assertEquals(123, builder.getFooInt());
+
+ message = builder.build();
+ assertEquals(message.getFooString(), "");
+ assertEquals(message.getFooStringBytes(), TestUtil.toBytes(""));
+ assertEquals(123, message.getFooInt());
+ }
+
+ // Cord
+ {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ assertEquals(builder.getFooCord(), "");
+ builder.setFooCord("foo");
+ assertTrue(builder.hasFooCord());
+ assertEquals(builder.getFooCord(), "foo");
+ TestOneof2 message = builder.buildPartial();
+ assertTrue(message.hasFooCord());
+ assertEquals(message.getFooCord(), "foo");
+ assertEquals(message.getFooCordBytes(), TestUtil.toBytes("foo"));
+
+ assertFalse(builder.clearFooCord().hasFooCord());
+ TestOneof2 message2 = builder.build();
+ assertFalse(message2.hasFooCord());
+ assertEquals(message2.getFooCord(), "");
+ assertEquals(message2.getFooCordBytes(), TestUtil.toBytes(""));
+ }
+
+ // StringPiece
+ {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ assertEquals(builder.getFooStringPiece(), "");
+ builder.setFooStringPiece("foo");
+ assertTrue(builder.hasFooStringPiece());
+ assertEquals(builder.getFooStringPiece(), "foo");
+ TestOneof2 message = builder.buildPartial();
+ assertTrue(message.hasFooStringPiece());
+ assertEquals(message.getFooStringPiece(), "foo");
+ assertEquals(message.getFooStringPieceBytes(), TestUtil.toBytes("foo"));
+
+ assertFalse(builder.clearFooStringPiece().hasFooStringPiece());
+ TestOneof2 message2 = builder.build();
+ assertFalse(message2.hasFooStringPiece());
+ assertEquals(message2.getFooStringPiece(), "");
+ assertEquals(message2.getFooStringPieceBytes(), TestUtil.toBytes(""));
+ }
+
+ // Message
+ {
+ // set
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ assertEquals(builder.getFooMessage().getQuxInt(), 0);
+ builder.setFooMessage(
+ TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build());
+ assertTrue(builder.hasFooMessage());
+ assertEquals(builder.getFooMessage().getQuxInt(), 234);
+ TestOneof2 message = builder.buildPartial();
+ assertTrue(message.hasFooMessage());
+ assertEquals(message.getFooMessage().getQuxInt(), 234);
+
+ // clear
+ assertFalse(builder.clearFooMessage().hasFooString());
+ message = builder.build();
+ assertFalse(message.hasFooMessage());
+ assertEquals(message.getFooMessage().getQuxInt(), 0);
+
+ // nested builder
+ builder = TestOneof2.newBuilder();
+ assertSame(builder.getFooMessageOrBuilder(),
+ TestOneof2.NestedMessage.getDefaultInstance());
+ assertFalse(builder.hasFooMessage());
+ builder.getFooMessageBuilder().setQuxInt(123);
+ assertTrue(builder.hasFooMessage());
+ assertEquals(builder.getFooMessage().getQuxInt(), 123);
+ message = builder.build();
+ assertTrue(message.hasFooMessage());
+ assertEquals(message.getFooMessage().getQuxInt(), 123);
+ }
+
+ // LazyMessage is tested in LazyMessageLiteTest.java
+ }
+
+ public void testOneofMerge() throws Exception {
+ // Primitive Type
+ {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ TestOneof2 message = builder.setFooInt(123).build();
+ TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
+ assertTrue(message2.hasFooInt());
+ assertEquals(message2.getFooInt(), 123);
+ }
+
+ // String
+ {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ TestOneof2 message = builder.setFooString("foo").build();
+ TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
+ assertTrue(message2.hasFooString());
+ assertEquals(message2.getFooString(), "foo");
+ }
+
+ // Enum
+ {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build();
+ TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
+ assertTrue(message2.hasFooEnum());
+ assertEquals(message2.getFooEnum(), TestOneof2.NestedEnum.BAR);
+ }
+
+ // Message
+ {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ TestOneof2 message = builder.setFooMessage(
+ TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()).build();
+ TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
+ assertTrue(message2.hasFooMessage());
+ assertEquals(message2.getFooMessage().getQuxInt(), 234);
+ }
+ }
+
+ public void testOneofSerialization() throws Exception {
+ // Primitive Type
+ {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ TestOneof2 message = builder.setFooInt(123).build();
+ ByteString serialized = message.toByteString();
+ TestOneof2 message2 = TestOneof2.parseFrom(serialized);
+ assertTrue(message2.hasFooInt());
+ assertEquals(message2.getFooInt(), 123);
+ }
+
+ // String
+ {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ TestOneof2 message = builder.setFooString("foo").build();
+ ByteString serialized = message.toByteString();
+ TestOneof2 message2 = TestOneof2.parseFrom(serialized);
+ assertTrue(message2.hasFooString());
+ assertEquals(message2.getFooString(), "foo");
+ }
+
+ // Enum
+ {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build();
+ ByteString serialized = message.toByteString();
+ TestOneof2 message2 = TestOneof2.parseFrom(serialized);
+ assertTrue(message2.hasFooEnum());
+ assertEquals(message2.getFooEnum(), TestOneof2.NestedEnum.BAR);
+ }
+
+ // Message
+ {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ TestOneof2 message = builder.setFooMessage(
+ TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()).build();
+ ByteString serialized = message.toByteString();
+ TestOneof2 message2 = TestOneof2.parseFrom(serialized);
+ assertTrue(message2.hasFooMessage());
+ assertEquals(message2.getFooMessage().getQuxInt(), 234);
+ }
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/IsValidUtf8Test.java b/java/src/test/java/com/google/protobuf/IsValidUtf8Test.java
new file mode 100644
index 0000000..89b6451
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/IsValidUtf8Test.java
@@ -0,0 +1,180 @@
+// 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.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,
+ * and three byte sequences to ensure that the method produces the right result
+ * for every possible byte encoding where "right" means it's consistent with
+ * java's UTF-8 string encoding/decoding such that the method returns true for
+ * any sequence that will round trip when converted to a String and then back to
+ * bytes and will return false for any sequence that will not round trip.
+ * See also {@link IsValidUtf8FourByteTest}. It also includes some
+ * other more targeted tests.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ * @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);
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * Tests that round tripping of all three byte permutations work.
+ */
+ public void testIsValidUtf8_3Bytes() throws UnsupportedEncodingException {
+ IsValidUtf8TestUtil.testBytes(3,
+ IsValidUtf8TestUtil.EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT);
+ }
+
+ /**
+ * Tests that round tripping of a sample of four byte permutations work.
+ * All permutations are prohibitively expensive to test for automated runs;
+ * {@link IsValidUtf8FourByteTest} is used for full coverage. This method
+ * tests specific four-byte cases.
+ */
+ public void testIsValidUtf8_4BytesSamples()
+ throws UnsupportedEncodingException {
+ // Valid 4 byte.
+ assertValidUtf8(0xF0, 0xA4, 0xAD, 0xA2);
+
+ // Bad trailing bytes
+ assertInvalidUtf8(0xF0, 0xA4, 0xAD, 0x7F);
+ assertInvalidUtf8(0xF0, 0xA4, 0xAD, 0xC0);
+
+ // Special cases for byte2
+ assertInvalidUtf8(0xF0, 0x8F, 0xAD, 0xA2);
+ assertInvalidUtf8(0xF4, 0x90, 0xAD, 0xA2);
+ }
+
+ /**
+ * Tests some hard-coded test cases.
+ */
+ public void testSomeSequences() {
+ // Empty
+ assertTrue(asBytes("").isValidUtf8());
+
+ // One-byte characters, including control characters
+ assertTrue(asBytes("\u0000abc\u007f").isValidUtf8());
+
+ // Two-byte characters
+ assertTrue(asBytes("\u00a2\u00a2").isValidUtf8());
+
+ // Three-byte characters
+ assertTrue(asBytes("\u020ac\u020ac").isValidUtf8());
+
+ // Four-byte characters
+ assertTrue(asBytes("\u024B62\u024B62").isValidUtf8());
+
+ // Mixed string
+ assertTrue(
+ asBytes("a\u020ac\u00a2b\\u024B62u020acc\u00a2de\u024B62")
+ .isValidUtf8());
+
+ // Not a valid string
+ assertInvalidUtf8(-1, 0, -1, 0);
+ }
+
+ private byte[] toByteArray(int... bytes) {
+ byte[] realBytes = new byte[bytes.length];
+ for (int i = 0; i < bytes.length; i++) {
+ realBytes[i] = (byte) bytes[i];
+ }
+ return realBytes;
+ }
+
+ private ByteString toByteString(int... bytes) {
+ return ByteString.copyFrom(toByteArray(bytes));
+ }
+
+ private void assertValidUtf8(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());
+ 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)
+ };
+ for (ByteString rope : ropes) {
+ assertTrue(not ^ rope.isValidUtf8());
+ }
+ }
+
+ private void assertValidUtf8(int... bytes) {
+ assertValidUtf8(bytes, false);
+ }
+
+ private void assertInvalidUtf8(int... bytes) {
+ assertValidUtf8(bytes, true);
+ }
+
+ private static ByteString asBytes(String s) {
+ return ByteString.copyFromUtf8(s);
+ }
+
+ public void testShardsHaveExpectedRoundTrippables() {
+ // A sanity check.
+ int actual = 0;
+ for (Shard shard : IsValidUtf8TestUtil.FOUR_BYTE_SHARDS) {
+ actual += shard.expected;
+ }
+ assertEquals(IsValidUtf8TestUtil.EXPECTED_FOUR_BYTE_ROUNDTRIPPABLE_COUNT,
+ actual);
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java b/java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java
new file mode 100644
index 0000000..f41595e
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java
@@ -0,0 +1,421 @@
+// 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 junit.framework.Assert.*;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import java.util.logging.Logger;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.Charset;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+
+/**
+ * Shared testing code for {@link IsValidUtf8Test} and
+ * {@link IsValidUtf8FourByteTest}.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ * @author martinrb@google.com (Martin Buchholz)
+ */
+class IsValidUtf8TestUtil {
+ private static Logger logger = Logger.getLogger(
+ IsValidUtf8TestUtil.class.getName());
+
+ // 128 - [chars 0x0000 to 0x007f]
+ static long ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x007f - 0x0000 + 1;
+
+ // 128
+ static long EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT =
+ ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS;
+
+ // 1920 [chars 0x0080 to 0x07FF]
+ static long TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x07FF - 0x0080 + 1;
+
+ // 18,304
+ static 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;
+
+ // 61,440 [chars 0x0800 to 0xFFFF, minus surrogates]
+ static long THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS =
+ 0xFFFF - 0x0800 + 1 - THREE_BYTE_SURROGATES;
+
+ // 2,650,112
+ static 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
+ THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS;
+
+ // 1,048,576 [chars 0x10000L to 0x10FFFF]
+ static long FOUR_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x10FFFF - 0x10000L + 1;
+
+ // 289,571,839
+ static 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 +
+ // 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 +
+ // Four byte characters
+ FOUR_BYTE_ROUNDTRIPPABLE_CHARACTERS;
+
+ static class Shard {
+ final long index;
+ final long start;
+ final long lim;
+ final long expected;
+
+
+ public Shard(long index, long start, long lim, long expected) {
+ assertTrue(start < lim);
+ this.index = index;
+ this.start = start;
+ this.lim = lim;
+ this.expected = expected;
+ }
+ }
+
+ static final long[] FOUR_BYTE_SHARDS_EXPECTED_ROUNTRIPPABLES =
+ generateFourByteShardsExpectedRunnables();
+
+ private static long[] generateFourByteShardsExpectedRunnables() {
+ long[] expected = new long[128];
+
+ // 0-63 are all 5300224
+ for (int i = 0; i <= 63; i++) {
+ expected[i] = 5300224;
+ }
+
+ // 97-111 are all 2342912
+ for (int i = 97; i <= 111; i++) {
+ expected[i] = 2342912;
+ }
+
+ // 113-117 are all 1048576
+ for (int i = 113; i <= 117; i++) {
+ expected[i] = 1048576;
+ }
+
+ // One offs
+ expected[112] = 786432;
+ expected[118] = 786432;
+ expected[119] = 1048576;
+ expected[120] = 458752;
+ expected[121] = 524288;
+ expected[122] = 65536;
+
+ // Anything not assigned was the default 0.
+ return expected;
+ }
+
+ static final List<Shard> FOUR_BYTE_SHARDS = generateFourByteShards(
+ 128, FOUR_BYTE_SHARDS_EXPECTED_ROUNTRIPPABLES);
+
+
+ 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]));
+ }
+ return shards;
+ }
+
+ /**
+ * Helper to run the loop to test all the permutations for the number of bytes
+ * specified.
+ *
+ * @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);
+ }
+
+ /**
+ * Helper to run the loop to test all the permutations for the number of bytes
+ * specified. This overload is useful for debugging to get the loop to start
+ * at a certain character.
+ *
+ * @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 {
+ Random rnd = new Random();
+ byte[] bytes = new byte[numBytes];
+
+ if (lim == -1) {
+ lim = 1L << (numBytes * 8);
+ }
+ long count = 0;
+ long countRoundTripped = 0;
+ for (long byteChar = start; byteChar < lim; byteChar++) {
+ long tmpByteChar = byteChar;
+ for (int i = 0; i < numBytes; i++) {
+ bytes[bytes.length - i - 1] = (byte) tmpByteChar;
+ tmpByteChar = tmpByteChar >> 8;
+ }
+ ByteString bs = ByteString.copyFrom(bytes);
+ boolean isRoundTrippable = bs.isValidUtf8();
+ String s = new String(bytes, "UTF-8");
+ byte[] bytesReencoded = s.getBytes("UTF-8");
+ boolean bytesEqual = Arrays.equals(bytes, bytesReencoded);
+
+ if (bytesEqual != isRoundTrippable) {
+ outputFailure(byteChar, bytes, bytesReencoded);
+ }
+
+ // Check agreement with static Utf8 methods.
+ assertEquals(isRoundTrippable, Utf8.isValidUtf8(bytes));
+ assertEquals(isRoundTrippable, Utf8.isValidUtf8(bytes, 0, numBytes));
+
+ // Test partial sequences.
+ // Partition numBytes into three segments (not necessarily non-empty).
+ int i = rnd.nextInt(numBytes);
+ int j = rnd.nextInt(numBytes);
+ if (j < i) {
+ 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);
+ outputFailure(byteChar, bytes, bytesReencoded);
+ }
+ assertEquals(isRoundTrippable, (state3 == Utf8.COMPLETE));
+
+ // 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)));
+ assertSame(RopeByteString.class, rope.getClass());
+
+ 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));
+ }
+
+ // ByteString reduplication should not affect its UTF-8 validity.
+ ByteString ropeADope =
+ RopeByteString.newInstanceForTest(bs, bs.substring(0, numBytes));
+ assertEquals(isRoundTrippable, ropeADope.isValidUtf8());
+
+ if (isRoundTrippable) {
+ countRoundTripped++;
+ }
+ count++;
+ if (byteChar != 0 && byteChar % 1000000L == 0) {
+ logger.info("Processed " + (byteChar / 1000000L) +
+ " million characters");
+ }
+ }
+ logger.info("Round tripped " + countRoundTripped + " of " + count);
+ assertEquals(expectedCount, countRoundTripped);
+ }
+
+ /**
+ * Variation of {@link #testBytes} that does less allocation using the
+ * low-level encoders/decoders directly. Checked in because it's useful for
+ * debugging when trying to process bytes faster, but since it doesn't use the
+ * actual String class, it's possible for incompatibilities to develop
+ * (although unlikely).
+ *
+ * @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 = Charset.forName("UTF-8").newDecoder()
+ .onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE);
+ CharsetEncoder encoder = Charset.forName("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];
+ int maxBytes = (int) (encoder.maxBytesPerChar() * maxChars) + 1;
+ byte[] bytesReencoded = new byte[maxBytes];
+
+ ByteBuffer bb = ByteBuffer.wrap(bytes);
+ CharBuffer cb = CharBuffer.wrap(charsDecoded);
+ ByteBuffer bbReencoded = ByteBuffer.wrap(bytesReencoded);
+ if (lim == -1) {
+ lim = 1L << (numBytes * 8);
+ }
+ long count = 0;
+ long countRoundTripped = 0;
+ for (long byteChar = start; byteChar < lim; byteChar++) {
+ bb.rewind();
+ bb.limit(bytes.length);
+ cb.rewind();
+ cb.limit(charsDecoded.length);
+ bbReencoded.rewind();
+ bbReencoded.limit(bytesReencoded.length);
+ encoder.reset();
+ decoder.reset();
+ long tmpByteChar = byteChar;
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[bytes.length - i - 1] = (byte) tmpByteChar;
+ tmpByteChar = tmpByteChar >> 8;
+ }
+ boolean isRoundTrippable = ByteString.copyFrom(bytes).isValidUtf8();
+ CoderResult result = decoder.decode(bb, cb, true);
+ assertFalse(result.isError());
+ result = decoder.flush(cb);
+ assertFalse(result.isError());
+
+ int charLen = cb.position();
+ cb.rewind();
+ cb.limit(charLen);
+ result = encoder.encode(cb, bbReencoded, true);
+ assertFalse(result.isError());
+ result = encoder.flush(bbReencoded);
+ assertFalse(result.isError());
+
+ boolean bytesEqual = true;
+ int bytesLen = bbReencoded.position();
+ if (bytesLen != numBytes) {
+ bytesEqual = false;
+ } else {
+ for (int i = 0; i < numBytes; i++) {
+ if (bytes[i] != bytesReencoded[i]) {
+ bytesEqual = false;
+ break;
+ }
+ }
+ }
+ if (bytesEqual != isRoundTrippable) {
+ outputFailure(byteChar, bytes, bytesReencoded, bytesLen);
+ }
+
+ count++;
+ if (isRoundTrippable) {
+ countRoundTripped++;
+ }
+ if (byteChar != 0 && byteChar % 1000000 == 0) {
+ logger.info("Processed " + (byteChar / 1000000) +
+ " million characters");
+ }
+ }
+ logger.info("Round tripped " + countRoundTripped + " of " + count);
+ assertEquals(expectedCount, countRoundTripped);
+ }
+
+ private static void outputFailure(long byteChar, byte[] bytes, byte[] after) {
+ 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 String toHexString(byte[] b) {
+ return toHexString(b, b.length);
+ }
+
+ private static String toHexString(byte[] b, int len) {
+ StringBuilder s = new StringBuilder();
+ s.append("\"");
+ for (int i = 0; i < len; i++) {
+ if (i > 0) {
+ s.append(" ");
+ }
+ s.append(String.format("%02x", b[i] & 0xFF));
+ }
+ s.append("\"");
+ return s.toString();
+ }
+
+}
diff --git a/java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java b/java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java
new file mode 100644
index 0000000..e67c6d2
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java
@@ -0,0 +1,134 @@
+// 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.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+
+import java.io.IOException;
+import junit.framework.TestCase;
+
+/**
+ * Unit test for {@link LazyFieldLite}.
+ *
+ * @author xiangl@google.com (Xiang Li)
+ */
+public class LazyFieldLiteTest extends TestCase {
+
+ public void testGetValue() {
+ MessageLite message = TestUtil.getAllSet();
+ LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+ assertEquals(message, lazyField.getValue(TestAllTypes.getDefaultInstance()));
+ changeValue(lazyField);
+ assertNotEqual(message, lazyField.getValue(TestAllTypes.getDefaultInstance()));
+ }
+
+ public void testGetValueEx() throws Exception {
+ TestAllExtensions message = TestUtil.getAllExtensionsSet();
+ LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+ assertEquals(message, lazyField.getValue(TestAllExtensions.getDefaultInstance()));
+ changeValue(lazyField);
+ assertNotEqual(message, lazyField.getValue(TestAllExtensions.getDefaultInstance()));
+ }
+
+ public void testSetValue() {
+ MessageLite message = TestUtil.getAllSet();
+ LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+ changeValue(lazyField);
+ assertNotEqual(message, lazyField.getValue(TestAllTypes.getDefaultInstance()));
+ message = lazyField.getValue(TestAllTypes.getDefaultInstance());
+ changeValue(lazyField);
+ assertEquals(message, lazyField.getValue(TestAllTypes.getDefaultInstance()));
+ }
+
+ public void testSetValueEx() throws Exception {
+ TestAllExtensions message = TestUtil.getAllExtensionsSet();
+ LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+ changeValue(lazyField);
+ assertNotEqual(message, lazyField.getValue(TestAllExtensions.getDefaultInstance()));
+ MessageLite value = lazyField.getValue(TestAllExtensions.getDefaultInstance());
+ changeValue(lazyField);
+ assertEquals(value, lazyField.getValue(TestAllExtensions.getDefaultInstance()));
+ }
+
+ public void testGetSerializedSize() {
+ MessageLite message = TestUtil.getAllSet();
+ LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+ assertEquals(message.getSerializedSize(), lazyField.getSerializedSize());
+ changeValue(lazyField);
+ assertNotEqual(message.getSerializedSize(), lazyField.getSerializedSize());
+ }
+
+ public void testGetSerializedSizeEx() throws Exception {
+ TestAllExtensions message = TestUtil.getAllExtensionsSet();
+ LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+ assertEquals(message.getSerializedSize(), lazyField.getSerializedSize());
+ changeValue(lazyField);
+ assertNotEqual(message.getSerializedSize(), lazyField.getSerializedSize());
+ }
+
+ public void testGetByteString() {
+ MessageLite message = TestUtil.getAllSet();
+ LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+ assertEquals(message.toByteString(), lazyField.toByteString());
+ changeValue(lazyField);
+ assertNotEqual(message.toByteString(), lazyField.toByteString());
+ }
+
+ public void testGetByteStringEx() throws Exception {
+ TestAllExtensions message = TestUtil.getAllExtensionsSet();
+ LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+ assertEquals(message.toByteString(), lazyField.toByteString());
+ changeValue(lazyField);
+ assertNotEqual(message.toByteString(), lazyField.toByteString());
+ }
+
+
+ // Help methods.
+
+ private LazyFieldLite createLazyFieldLiteFromMessage(MessageLite message) {
+ ByteString bytes = message.toByteString();
+ return new LazyFieldLite(TestUtil.getExtensionRegistry(), bytes);
+ }
+
+ private void changeValue(LazyFieldLite lazyField) {
+ TestAllTypes.Builder builder = TestUtil.getAllSet().toBuilder();
+ builder.addRepeatedBool(true);
+ MessageLite newMessage = builder.build();
+ lazyField.setValue(newMessage);
+ }
+
+ private void assertNotEqual(Object unexpected, Object actual) {
+ assertFalse(unexpected == actual
+ || (unexpected != null && unexpected.equals(actual)));
+ }
+
+}
diff --git a/java/src/test/java/com/google/protobuf/LazyFieldTest.java b/java/src/test/java/com/google/protobuf/LazyFieldTest.java
new file mode 100644
index 0000000..2b90006
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/LazyFieldTest.java
@@ -0,0 +1,121 @@
+// 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.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+
+import java.io.IOException;
+import junit.framework.TestCase;
+
+/**
+ * Unit test for {@link LazyField}.
+ *
+ * @author xiangl@google.com (Xiang Li)
+ */
+public class LazyFieldTest extends TestCase {
+ public void testHashCode() {
+ MessageLite message = TestUtil.getAllSet();
+ LazyField lazyField =
+ createLazyFieldFromMessage(message);
+ assertEquals(message.hashCode(), lazyField.hashCode());
+ lazyField.getValue();
+ assertEquals(message.hashCode(), lazyField.hashCode());
+ changeValue(lazyField);
+ // make sure two messages have different hash code
+ assertNotEqual(message.hashCode(), lazyField.hashCode());
+ }
+
+ public void testHashCodeEx() throws Exception {
+ TestAllExtensions message = TestUtil.getAllExtensionsSet();
+ LazyField lazyField = createLazyFieldFromMessage(message);
+ assertEquals(message.hashCode(), lazyField.hashCode());
+ lazyField.getValue();
+ assertEquals(message.hashCode(), lazyField.hashCode());
+ changeValue(lazyField);
+ // make sure two messages have different hash code
+ assertNotEqual(message.hashCode(), lazyField.hashCode());
+ }
+
+ public void testGetValue() {
+ MessageLite message = TestUtil.getAllSet();
+ LazyField lazyField = createLazyFieldFromMessage(message);
+ assertEquals(message, lazyField.getValue());
+ changeValue(lazyField);
+ assertNotEqual(message, lazyField.getValue());
+ }
+
+ public void testGetValueEx() throws Exception {
+ TestAllExtensions message = TestUtil.getAllExtensionsSet();
+ LazyField lazyField = createLazyFieldFromMessage(message);
+ assertEquals(message, lazyField.getValue());
+ changeValue(lazyField);
+ assertNotEqual(message, lazyField.getValue());
+ }
+
+ public void testEqualsObject() {
+ MessageLite message = TestUtil.getAllSet();
+ LazyField lazyField = createLazyFieldFromMessage(message);
+ assertTrue(lazyField.equals(message));
+ changeValue(lazyField);
+ assertFalse(lazyField.equals(message));
+ assertFalse(message.equals(lazyField.getValue()));
+ }
+
+ public void testEqualsObjectEx() throws Exception {
+ TestAllExtensions message = TestUtil.getAllExtensionsSet();
+ LazyField lazyField = createLazyFieldFromMessage(message);
+ assertTrue(lazyField.equals(message));
+ changeValue(lazyField);
+ assertFalse(lazyField.equals(message));
+ assertFalse(message.equals(lazyField.getValue()));
+ }
+
+ // Help methods.
+
+ private LazyField createLazyFieldFromMessage(MessageLite message) {
+ ByteString bytes = message.toByteString();
+ return new LazyField(message.getDefaultInstanceForType(),
+ TestUtil.getExtensionRegistry(), bytes);
+ }
+
+ private void changeValue(LazyField lazyField) {
+ TestAllTypes.Builder builder = TestUtil.getAllSet().toBuilder();
+ builder.addRepeatedBool(true);
+ MessageLite newMessage = builder.build();
+ lazyField.setValue(newMessage);
+ }
+
+ private void assertNotEqual(Object unexpected, Object actual) {
+ assertFalse(unexpected == actual
+ || (unexpected != null && unexpected.equals(actual)));
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java b/java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java
new file mode 100644
index 0000000..00e3a84
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java
@@ -0,0 +1,319 @@
+// 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.LazyFieldsLite.LazyInnerMessageLite;
+import protobuf_unittest.LazyFieldsLite.LazyMessageLite;
+import protobuf_unittest.LazyFieldsLite.LazyNestedInnerMessageLite;
+
+import junit.framework.TestCase;
+
+import org.easymock.classextension.EasyMock;
+
+import java.util.ArrayList;
+
+/**
+ * Unit test for messages with lazy fields.
+ *
+ * @author niwasaki@google.com (Naoki Iwasaki)
+ */
+public class LazyMessageLiteTest extends TestCase {
+
+ private Parser<LazyInnerMessageLite> originalLazyInnerMessageLiteParser;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ originalLazyInnerMessageLiteParser = LazyInnerMessageLite.PARSER;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ LazyInnerMessageLite.PARSER = originalLazyInnerMessageLiteParser;
+
+ super.tearDown();
+ }
+
+ public void testSetValues() {
+ LazyNestedInnerMessageLite nested = LazyNestedInnerMessageLite.newBuilder()
+ .setNum(3)
+ .build();
+ LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder()
+ .setNum(2)
+ .setNested(nested)
+ .build();
+ LazyMessageLite outer = LazyMessageLite.newBuilder()
+ .setNum(1)
+ .setInner(inner)
+ .setOneofNum(123)
+ .setOneofInner(inner)
+ .build();
+
+ assertEquals(1, outer.getNum());
+ assertEquals(421, outer.getNumWithDefault());
+
+ assertEquals(2, outer.getInner().getNum());
+ assertEquals(42, outer.getInner().getNumWithDefault());
+
+ assertEquals(3, outer.getInner().getNested().getNum());
+ assertEquals(4, outer.getInner().getNested().getNumWithDefault());
+
+ assertFalse(outer.hasOneofNum());
+ assertTrue(outer.hasOneofInner());
+
+ assertEquals(2, outer.getOneofInner().getNum());
+ assertEquals(42, outer.getOneofInner().getNumWithDefault());
+ assertEquals(3, outer.getOneofInner().getNested().getNum());
+ assertEquals(4, outer.getOneofInner().getNested().getNumWithDefault());
+ }
+
+ public void testSetRepeatedValues() {
+ LazyMessageLite outer = LazyMessageLite.newBuilder()
+ .setNum(1)
+ .addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(119))
+ .addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(122))
+ .build();
+
+ assertEquals(1, outer.getNum());
+ assertEquals(2, outer.getRepeatedInnerCount());
+ assertEquals(119, outer.getRepeatedInner(0).getNum());
+ assertEquals(122, outer.getRepeatedInner(1).getNum());
+ }
+
+ public void testAddAll() {
+ ArrayList<LazyInnerMessageLite> inners = new ArrayList<LazyInnerMessageLite>();
+ int count = 4;
+ for (int i = 0; i < count; i++) {
+ LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder()
+ .setNum(i)
+ .build();
+ inners.add(inner);
+ }
+
+ LazyMessageLite outer = LazyMessageLite.newBuilder()
+ .addAllRepeatedInner(inners)
+ .build();
+ assertEquals(count, outer.getRepeatedInnerCount());
+ for (int i = 0; i < count; i++) {
+ assertEquals(i, outer.getRepeatedInner(i).getNum());
+ }
+ }
+
+ public void testGetDefaultValues() {
+ LazyMessageLite outer = LazyMessageLite.newBuilder()
+ .build();
+
+ assertEquals(0, outer.getNum());
+ assertEquals(421, outer.getNumWithDefault());
+
+ assertEquals(0, outer.getInner().getNum());
+ assertEquals(42, outer.getInner().getNumWithDefault());
+
+ assertEquals(0, outer.getInner().getNested().getNum());
+ assertEquals(4, outer.getInner().getNested().getNumWithDefault());
+
+ assertEquals(0, outer.getOneofNum());
+
+ assertEquals(0, outer.getOneofInner().getNum());
+ assertEquals(42, outer.getOneofInner().getNumWithDefault());
+ assertEquals(0, outer.getOneofInner().getNested().getNum());
+ assertEquals(4, outer.getOneofInner().getNested().getNumWithDefault());
+ }
+
+ public void testClearValues() {
+ LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder()
+ .setNum(115)
+ .build();
+
+ LazyMessageLite.Builder outerBuilder = LazyMessageLite.newBuilder();
+
+ assertEquals(0, outerBuilder.build().getNum());
+
+
+ // Set/Clear num
+ outerBuilder.setNum(100);
+
+ assertEquals(100, outerBuilder.build().getNum());
+ assertEquals(421, outerBuilder.build().getNumWithDefault());
+ assertFalse(outerBuilder.build().hasInner());
+
+ outerBuilder.clearNum();
+
+ assertEquals(0, outerBuilder.build().getNum());
+ assertEquals(421, outerBuilder.build().getNumWithDefault());
+ assertFalse(outerBuilder.build().hasInner());
+
+
+ // Set/Clear all
+ outerBuilder.setNum(100)
+ .setInner(inner)
+ .addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(119))
+ .addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(122))
+ .setOneofInner(LazyInnerMessageLite.newBuilder().setNum(123));
+
+ LazyMessageLite outer = outerBuilder.build();
+ assertEquals(100, outer.getNum());
+ assertEquals(421, outer.getNumWithDefault());
+ assertTrue(outer.hasInner());
+ assertEquals(115, outer.getInner().getNum());
+ assertEquals(2, outer.getRepeatedInnerCount());
+ assertEquals(119, outer.getRepeatedInner(0).getNum());
+ assertEquals(122, outer.getRepeatedInner(1).getNum());
+ assertTrue(outer.hasOneofInner());
+ assertEquals(123, outer.getOneofInner().getNum());
+
+ outerBuilder.clear();
+
+ outer = outerBuilder.build();
+
+ assertEquals(0, outer.getNum());
+ assertEquals(421, outer.getNumWithDefault());
+ assertFalse(outer.hasInner());
+ assertEquals(0, outer.getRepeatedInnerCount());
+ assertFalse(outer.hasOneofInner());
+ assertEquals(0, outer.getOneofInner().getNum());
+ }
+
+ public void testMergeValues() {
+ LazyMessageLite outerBase = LazyMessageLite.newBuilder()
+ .setNumWithDefault(122)
+ .build();
+
+ LazyInnerMessageLite innerMerging = LazyInnerMessageLite.newBuilder()
+ .setNum(115)
+ .build();
+ LazyMessageLite outerMerging = LazyMessageLite.newBuilder()
+ .setNum(119)
+ .setInner(innerMerging)
+ .setOneofInner(innerMerging)
+ .build();
+
+ LazyMessageLite merged = LazyMessageLite
+ .newBuilder(outerBase)
+ .mergeFrom(outerMerging)
+ .build();
+ assertEquals(119, merged.getNum());
+ assertEquals(122, merged.getNumWithDefault());
+ assertEquals(115, merged.getInner().getNum());
+ assertEquals(42, merged.getInner().getNumWithDefault());
+ assertEquals(115, merged.getOneofInner().getNum());
+ assertEquals(42, merged.getOneofInner().getNumWithDefault());
+ }
+
+ public void testMergeDefaultValues() {
+ LazyInnerMessageLite innerBase = LazyInnerMessageLite.newBuilder()
+ .setNum(115)
+ .build();
+ LazyMessageLite outerBase = LazyMessageLite.newBuilder()
+ .setNum(119)
+ .setNumWithDefault(122)
+ .setInner(innerBase)
+ .setOneofInner(innerBase)
+ .build();
+
+ LazyMessageLite outerMerging = LazyMessageLite.newBuilder()
+ .build();
+
+ LazyMessageLite merged = LazyMessageLite
+ .newBuilder(outerBase)
+ .mergeFrom(outerMerging)
+ .build();
+ // Merging default-instance shouldn't overwrite values in the base message.
+ assertEquals(119, merged.getNum());
+ assertEquals(122, merged.getNumWithDefault());
+ assertEquals(115, merged.getInner().getNum());
+ assertEquals(42, merged.getInner().getNumWithDefault());
+ assertEquals(115, merged.getOneofInner().getNum());
+ assertEquals(42, merged.getOneofInner().getNumWithDefault());
+ }
+
+ public void testSerialize() throws InvalidProtocolBufferException {
+ LazyNestedInnerMessageLite nested = LazyNestedInnerMessageLite.newBuilder()
+ .setNum(3)
+ .build();
+ LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder()
+ .setNum(2)
+ .setNested(nested)
+ .build();
+ LazyMessageLite outer = LazyMessageLite.newBuilder()
+ .setNum(1)
+ .setInner(inner)
+ .setOneofInner(inner)
+ .build();
+
+ ByteString bytes = outer.toByteString();
+ assertEquals(bytes.size(), outer.getSerializedSize());
+
+ LazyMessageLite deserialized = LazyMessageLite.parseFrom(bytes);
+
+ assertEquals(1, deserialized.getNum());
+ assertEquals(421, deserialized.getNumWithDefault());
+
+ assertEquals(2, deserialized.getInner().getNum());
+ assertEquals(42, deserialized.getInner().getNumWithDefault());
+
+ assertEquals(3, deserialized.getInner().getNested().getNum());
+ assertEquals(4, deserialized.getInner().getNested().getNumWithDefault());
+
+ assertEquals(2, deserialized.getOneofInner().getNum());
+ assertEquals(42, deserialized.getOneofInner().getNumWithDefault());
+ assertEquals(3, deserialized.getOneofInner().getNested().getNum());
+ assertEquals(4, deserialized.getOneofInner().getNested().getNumWithDefault());
+
+ assertEquals(bytes, deserialized.toByteString());
+ }
+
+ public void testLaziness() throws InvalidProtocolBufferException {
+ LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder()
+ .setNum(2)
+ .build();
+ LazyMessageLite outer = LazyMessageLite.newBuilder()
+ .setNum(1)
+ .setInner(inner)
+ .setOneofInner(inner)
+ .build();
+ ByteString bytes = outer.toByteString();
+
+
+ // The parser for inner / oneofInner message shouldn't be used if
+ // getInner / getOneofInner is not called.
+ LazyInnerMessageLite.PARSER = EasyMock.createStrictMock(Parser.class);
+
+ EasyMock.replay(LazyInnerMessageLite.PARSER);
+
+ LazyMessageLite deserialized = LazyMessageLite.parseFrom(bytes);
+ assertEquals(1, deserialized.getNum());
+ assertEquals(421, deserialized.getNumWithDefault());
+
+ EasyMock.verify(LazyInnerMessageLite.PARSER);
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java b/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
new file mode 100644
index 0000000..f3012b9
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
@@ -0,0 +1,174 @@
+// 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.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));
+
+ List<ByteString> byteStringList = list.asByteStringList();
+ assertEquals(BYTE_STRING_A, byteStringList.get(0));
+ assertEquals(BYTE_STRING_C, byteStringList.get(1));
+
+ // Underlying list should be transformed.
+ assertSame(byteStringList.get(0), list.getByteString(0));
+ assertSame(byteStringList.get(1), list.getByteString(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));
+
+ List<ByteString> byteStringList = list.asByteStringList();
+ assertSame(BYTE_STRING_A, byteStringList.get(0));
+ assertSame(BYTE_STRING_C, byteStringList.get(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/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java b/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java
new file mode 100644
index 0000000..acd1800
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java
@@ -0,0 +1,143 @@
+// 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.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 testCaching() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ UnittestProto.TestAllTypes proto = UnittestProto.TestAllTypes.newBuilder()
+ .setOptionalString(a)
+ .addRepeatedString(b)
+ .addRepeatedString(c)
+ .build();
+
+ // String should be the one we passed it.
+ assertSame(a, proto.getOptionalString());
+ assertSame(b, proto.getRepeatedString(0));
+ assertSame(c, proto.getRepeatedString(1));
+
+
+ // There's no way to directly observe that the ByteString is cached
+ // correctly on serialization, but we can observe that it had to recompute
+ // the string after serialization.
+ proto.toByteString();
+ String aPrime = proto.getOptionalString();
+ assertNotSame(a, aPrime);
+ assertEquals(a, aPrime);
+ String bPrime = proto.getRepeatedString(0);
+ assertNotSame(b, bPrime);
+ assertEquals(b, bPrime);
+ String cPrime = proto.getRepeatedString(1);
+ assertNotSame(c, cPrime);
+ assertEquals(c, cPrime);
+
+ // And now the string should stay cached.
+ assertSame(aPrime, proto.getOptionalString());
+ assertSame(bPrime, proto.getRepeatedString(0));
+ assertSame(cPrime, proto.getRepeatedString(1));
+ }
+
+ 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/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java b/java/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java
new file mode 100644
index 0000000..94f4fcf
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java
@@ -0,0 +1,85 @@
+// 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.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 junit.framework.TestCase;
+
+/**
+ * Test generate equal and hash methods for the lite runtime.
+ *
+ * @author pbogle@google.com Phil Bogle
+ */
+public class LiteEqualsAndHashTest extends TestCase {
+
+ public void testEquals() throws Exception {
+ // Since the generated equals and hashCode methods for lite messages are a
+ // mostly complete subset of those for regular messages, we can mostly assume
+ // that the generated methods are already thoroughly tested by the regular tests.
+
+ // This test mostly just verifies is that a proto with
+ // optimize_for = LITE_RUNTIME and java_generates_equals_and_hash_compiles
+ // 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.
+
+ // 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));
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/LiteTest.java b/java/src/test/java/com/google/protobuf/LiteTest.java
index 728bad9..8bb30ad 100644
--- a/java/src/test/java/com/google/protobuf/LiteTest.java
+++ b/java/src/test/java/com/google/protobuf/LiteTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -37,6 +37,11 @@ import com.google.protobuf.UnittestLite.TestNestedExtensionLite;
import junit.framework.TestCase;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
/**
* Test lite runtime.
*
@@ -113,4 +118,31 @@ 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());
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java b/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java
new file mode 100644
index 0000000..475f7ff
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java
@@ -0,0 +1,396 @@
+// 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.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;
+ }
+
+ public void testExpectedType() {
+ String actualClassName = getActualClassName(stringUnderTest);
+ assertEquals(classUnderTest + " should match type exactly", classUnderTest, 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 < 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 testGetTreeDepth() {
+ assertEquals(classUnderTest + " must have depth 0", 0, stringUnderTest.getTreeDepth());
+ }
+
+ public void testIsBalanced() {
+ assertTrue(classUnderTest + " is technically balanced", stringUnderTest.isBalanced());
+ }
+
+ 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 testToString() throws UnsupportedEncodingException {
+ String testString = "I love unicode \u1234\u5678 characters";
+ LiteralByteString unicode = new LiteralByteString(testString.getBytes(UTF_8));
+ String roundTripString = unicode.toString(UTF_8);
+ assertEquals(classUnderTest + " unicode must match", testString, roundTripString);
+ }
+
+ public void testEquals() {
+ assertEquals(classUnderTest + " must not equal null", false, stringUnderTest.equals(null));
+ assertEquals(classUnderTest + " must equal self", stringUnderTest, stringUnderTest);
+ 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));
+ assertEquals(classUnderTest + " must equal another string with the same value",
+ stringUnderTest, new LiteralByteString(referenceBytes));
+
+ byte[] mungedBytes = new byte[referenceBytes.length];
+ System.arraycopy(referenceBytes, 0, mungedBytes, 0, referenceBytes.length);
+ mungedBytes[mungedBytes.length - 5] ^= 0xFF;
+ assertFalse(classUnderTest + " must not equal every string with the same length",
+ stringUnderTest.equals(new LiteralByteString(mungedBytes)));
+ }
+
+ public void testHashCode() {
+ int hash = stringUnderTest.hashCode();
+ assertEquals(classUnderTest + " must have expected hashCode", expectedHashCode, hash);
+ }
+
+ public void testPeekCachedHashCode() {
+ assertEquals(classUnderTest + ".peekCachedHashCode() should return zero at first", 0,
+ stringUnderTest.peekCachedHashCode());
+ stringUnderTest.hashCode();
+ assertEquals(classUnderTest + ".peekCachedHashCode should return zero at first",
+ expectedHashCode, stringUnderTest.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 = stringUnderTest.partialHash(stringUnderTest.size(), 0, stringUnderTest.size());
+ assertEquals(classUnderTest + ".partialHash() must yield 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/src/test/java/com/google/protobuf/MessageTest.java b/java/src/test/java/com/google/protobuf/MessageTest.java
index c2f47eb..abcd3a1 100644
--- a/java/src/test/java/com/google/protobuf/MessageTest.java
+++ b/java/src/test/java/com/google/protobuf/MessageTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -38,6 +38,8 @@ 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.
@@ -310,4 +312,42 @@ public class MessageTest extends TestCase {
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/src/test/java/com/google/protobuf/NanoTest.java b/java/src/test/java/com/google/protobuf/NanoTest.java
index 6b69aa7..4c3b416 100644
--- a/java/src/test/java/com/google/protobuf/NanoTest.java
+++ b/java/src/test/java/com/google/protobuf/NanoTest.java
@@ -49,6 +49,7 @@ import com.google.protobuf.nano.NanoHasOuterClass.TestAllTypesNanoHas;
import com.google.protobuf.nano.NanoOuterClass;
import com.google.protobuf.nano.NanoOuterClass.TestAllTypesNano;
import com.google.protobuf.nano.NanoReferenceTypes;
+import com.google.protobuf.nano.NanoReferenceTypesCompat;
import com.google.protobuf.nano.NanoRepeatedPackables;
import com.google.protobuf.nano.PackedExtensions;
import com.google.protobuf.nano.RepeatedExtensions;
@@ -2318,6 +2319,42 @@ public class NanoTest extends TestCase {
}
}
+ public void testDifferentStringLengthsNano() 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 InvalidProtocolBufferNanoException {
+ TestAllTypesNano testAllTypesNano = new TestAllTypesNano();
+ final String fullString = fullString(c, length);
+ testAllTypesNano.optionalString = fullString;
+ final TestAllTypesNano resultNano = new TestAllTypesNano();
+ MessageNano.mergeFrom(resultNano, MessageNano.toByteArray(testAllTypesNano));
+ assertEquals(fullString, resultNano.optionalString);
+ }
+
+ private String fullString(char c, int length) {
+ char[] result = new char[length];
+ Arrays.fill(result, c);
+ return new String(result);
+ }
+
public void testNanoWithHasParseFrom() throws Exception {
TestAllTypesNanoHas msg = null;
// Test false on creation, after clear and upon empty parse.
@@ -2963,6 +3000,10 @@ public class NanoTest extends TestCase {
assertTrue(Arrays.equals(floats, message.getExtension(RepeatedExtensions.repeatedFloat)));
assertTrue(Arrays.equals(doubles, message.getExtension(RepeatedExtensions.repeatedDouble)));
assertTrue(Arrays.equals(enums, message.getExtension(RepeatedExtensions.repeatedEnum)));
+
+ // Clone the message and ensure it's still equal.
+ Extensions.ExtendableMessage clone = message.clone();
+ assertEquals(clone, message);
}
public void testNullExtensions() throws Exception {
@@ -3753,6 +3794,11 @@ public class NanoTest extends TestCase {
assertTrue(Arrays.equals(new boolean[] {false, true, false, true}, nonPacked.bools));
}
+ public void testRepeatedFieldInitializedInReftypesCompatMode() {
+ NanoReferenceTypesCompat.TestAllTypesNano proto = new NanoReferenceTypesCompat.TestAllTypesNano();
+ assertNotNull(proto.repeatedString);
+ }
+
private void assertRepeatedPackablesEqual(
NanoRepeatedPackables.NonPacked nonPacked, NanoRepeatedPackables.Packed packed) {
// Not using MessageNano.equals() -- that belongs to a separate test.
@@ -3772,6 +3818,22 @@ public class NanoTest extends TestCase {
assertTrue(Arrays.equals(nonPacked.enums, packed.enums));
}
+ public void testClone() throws Exception {
+ // A simple message.
+ AnotherMessage anotherMessage = new AnotherMessage();
+ anotherMessage.string = "Hello";
+ anotherMessage.value = true;
+ anotherMessage.integers = new int[] { 1, 2, 3 };
+
+ AnotherMessage clone = anotherMessage.clone();
+ assertEquals(clone, anotherMessage);
+
+ // Verify it was a deep clone - changes to the clone shouldn't affect the
+ // original.
+ clone.integers[1] = 100;
+ assertFalse(clone.equals(anotherMessage));
+ }
+
private void assertHasWireData(MessageNano message, boolean expected) {
byte[] bytes = MessageNano.toByteArray(message);
int wireLength = bytes.length;
diff --git a/java/src/test/java/com/google/protobuf/NestedBuildersTest.java b/java/src/test/java/com/google/protobuf/NestedBuildersTest.java
new file mode 100644
index 0000000..2365312
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/NestedBuildersTest.java
@@ -0,0 +1,185 @@
+// 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.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/src/test/java/com/google/protobuf/ParserTest.java b/java/src/test/java/com/google/protobuf/ParserTest.java
new file mode 100644
index 0000000..b11d8cb
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/ParserTest.java
@@ -0,0 +1,381 @@
+// 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.TestAllTypesLite;
+import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
+import com.google.protobuf.UnittestLite.TestParsingMergeLite;
+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.TestParsingMerge;
+import protobuf_unittest.UnittestProto.TestRequired;
+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));
+ }
+
+ @SuppressWarnings("unchecked")
+ 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<MessageLite> parser =
+ (Parser<MessageLite>) 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 {
+ assertParsePartial(TestRequired.PARSER,
+ TestRequired.newBuilder().setA(1).buildPartial());
+ }
+
+ private <T extends MessageLite> void assertParsePartial(
+ Parser<T> parser, T partialMessage) throws Exception {
+ final String errorString =
+ "Should throw exceptions when the parsed message isn't initialized.";
+
+ // 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 testParseExtensions() throws Exception {
+ assertRoundTripEquals(TestUtil.getAllExtensionsSet(),
+ TestUtil.getExtensionRegistry());
+ assertRoundTripEquals(TestUtil.getAllLiteExtensionsSet(),
+ TestUtil.getExtensionRegistryLite());
+ }
+
+ public void testParsePacked() throws Exception {
+ assertRoundTripEquals(TestUtil.getPackedSet());
+ assertRoundTripEquals(TestUtil.getPackedExtensionsSet(),
+ TestUtil.getExtensionRegistry());
+ assertRoundTripEquals(TestUtil.getLitePackedExtensionsSet(),
+ TestUtil.getExtensionRegistryLite());
+ }
+
+ public void testParseDelimitedTo() throws Exception {
+ // Write normal Message.
+ TestAllTypes normalMessage = TestUtil.getAllSet();
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ normalMessage.writeDelimitedTo(output);
+
+ // Write MessageLite with packed extension fields.
+ TestPackedExtensionsLite packedMessage =
+ TestUtil.getLitePackedExtensionsSet();
+ packedMessage.writeDelimitedTo(output);
+
+ InputStream input = new ByteArrayInputStream(output.toByteArray());
+ assertMessageEquals(
+ normalMessage,
+ normalMessage.getParserForType().parseDelimitedFrom(input));
+ assertMessageEquals(
+ packedMessage,
+ packedMessage.getParserForType().parseDelimitedFrom(
+ input, TestUtil.getExtensionRegistryLite()));
+ }
+
+ 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());
+ }
+
+ /** Helper method for {@link #testParsingMergeLite()}.*/
+ private void assertMessageMerged(TestAllTypesLite 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));
+ }
+
+ public void testParsingMergeLite() throws Exception {
+ // Build messages.
+ TestAllTypesLite.Builder builder =
+ TestAllTypesLite.newBuilder();
+ TestAllTypesLite msg1 = builder.setOptionalInt32(1).build();
+ builder.clear();
+ TestAllTypesLite msg2 = builder.setOptionalInt64(2).build();
+ builder.clear();
+ TestAllTypesLite msg3 = builder.setOptionalInt32(3)
+ .setOptionalString("hello").build();
+
+ // Build groups.
+ TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG1 =
+ TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder()
+ .setField1(msg1).build();
+ TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG2 =
+ TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder()
+ .setField1(msg2).build();
+ TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG3 =
+ TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder()
+ .setField1(msg3).build();
+ TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG1 =
+ TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder()
+ .setField1(msg1).build();
+ TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG2 =
+ TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder()
+ .setField1(msg2).build();
+ TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG3 =
+ TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder()
+ .setField1(msg3).build();
+
+ // Assign and serialize RepeatedFieldsGenerator.
+ ByteString data = TestParsingMergeLite.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 TestParsingMergeLite.
+ ExtensionRegistry registry = ExtensionRegistry.newInstance();
+ UnittestLite.registerAllExtensions(registry);
+ TestParsingMergeLite parsingMerge =
+ TestParsingMergeLite.PARSER.parseFrom(data, registry);
+
+ // Required and optional fields should be merged.
+ assertMessageMerged(parsingMerge.getRequiredAllTypes());
+ assertMessageMerged(parsingMerge.getOptionalAllTypes());
+ assertMessageMerged(
+ parsingMerge.getOptionalGroup().getOptionalGroupAllTypes());
+ assertMessageMerged(parsingMerge.getExtension(
+ TestParsingMergeLite.optionalExt));
+
+ // Repeated fields should not be merged.
+ assertEquals(3, parsingMerge.getRepeatedAllTypesCount());
+ assertEquals(3, parsingMerge.getRepeatedGroupCount());
+ assertEquals(3, parsingMerge.getExtensionCount(
+ TestParsingMergeLite.repeatedExt));
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java b/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java
new file mode 100644
index 0000000..49d5232
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java
@@ -0,0 +1,190 @@
+// 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.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
+
+import junit.framework.TestCase;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Tests for {@link RepeatedFieldBuilder}. 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 void testBasicUse() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
+ assertEquals(0, builder.getMessage(0).getOptionalInt32());
+ assertEquals(1, builder.getMessage(1).getOptionalInt32());
+
+ List<TestAllTypes> list = builder.build();
+ assertEquals(2, list.size());
+ assertEquals(0, list.get(0).getOptionalInt32());
+ assertEquals(1, list.get(1).getOptionalInt32());
+ assertIsUnmodifiable(list);
+
+ // Make sure it doesn't change.
+ List<TestAllTypes> list2 = builder.build();
+ assertSame(list, list2);
+ assertEquals(0, mockParent.getInvalidationCount());
+ }
+
+ public void testGoingBackAndForth() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
+ assertEquals(0, builder.getMessage(0).getOptionalInt32());
+ assertEquals(1, builder.getMessage(1).getOptionalInt32());
+
+ // Convert to list
+ List<TestAllTypes> list = builder.build();
+ assertEquals(2, list.size());
+ assertEquals(0, list.get(0).getOptionalInt32());
+ assertEquals(1, list.get(1).getOptionalInt32());
+ assertIsUnmodifiable(list);
+
+ // Update 0th item
+ assertEquals(0, mockParent.getInvalidationCount());
+ builder.getBuilder(0).setOptionalString("foo");
+ assertEquals(1, mockParent.getInvalidationCount());
+ list = builder.build();
+ assertEquals(2, list.size());
+ assertEquals(0, list.get(0).getOptionalInt32());
+ assertEquals("foo", list.get(0).getOptionalString());
+ assertEquals(1, list.get(1).getOptionalInt32());
+ assertIsUnmodifiable(list);
+ assertEquals(1, mockParent.getInvalidationCount());
+ }
+
+ public void testVariousMethods() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(2).build());
+ builder.addBuilder(0, TestAllTypes.getDefaultInstance())
+ .setOptionalInt32(0);
+ builder.addBuilder(TestAllTypes.getDefaultInstance()).setOptionalInt32(3);
+
+ assertEquals(0, builder.getMessage(0).getOptionalInt32());
+ assertEquals(1, builder.getMessage(1).getOptionalInt32());
+ assertEquals(2, builder.getMessage(2).getOptionalInt32());
+ assertEquals(3, builder.getMessage(3).getOptionalInt32());
+
+ assertEquals(0, mockParent.getInvalidationCount());
+ List<TestAllTypes> messages = builder.build();
+ assertEquals(4, messages.size());
+ assertSame(messages, builder.build()); // expect same list
+
+ // Remove a message.
+ builder.remove(2);
+ assertEquals(1, mockParent.getInvalidationCount());
+ assertEquals(3, builder.getCount());
+ assertEquals(0, builder.getMessage(0).getOptionalInt32());
+ assertEquals(1, builder.getMessage(1).getOptionalInt32());
+ assertEquals(3, builder.getMessage(2).getOptionalInt32());
+
+ // Remove a builder.
+ builder.remove(0);
+ assertEquals(1, mockParent.getInvalidationCount());
+ assertEquals(2, builder.getCount());
+ assertEquals(1, builder.getMessage(0).getOptionalInt32());
+ assertEquals(3, builder.getMessage(1).getOptionalInt32());
+
+ // Test clear.
+ builder.clear();
+ assertEquals(1, mockParent.getInvalidationCount());
+ assertEquals(0, builder.getCount());
+ assertTrue(builder.isEmpty());
+ }
+
+ public void testLists() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
+ builder.addMessage(0,
+ TestAllTypes.newBuilder().setOptionalInt32(0).build());
+ assertEquals(0, builder.getMessage(0).getOptionalInt32());
+ assertEquals(1, builder.getMessage(1).getOptionalInt32());
+
+ // Use list of builders.
+ List<TestAllTypes.Builder> builders = builder.getBuilderList();
+ assertEquals(0, builders.get(0).getOptionalInt32());
+ assertEquals(1, builders.get(1).getOptionalInt32());
+ builders.get(0).setOptionalInt32(10);
+ builders.get(1).setOptionalInt32(11);
+
+ // Use list of protos
+ List<TestAllTypes> protos = builder.getMessageList();
+ assertEquals(10, protos.get(0).getOptionalInt32());
+ assertEquals(11, protos.get(1).getOptionalInt32());
+
+ // Add an item to the builders and verify it's updated in both
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(12).build());
+ assertEquals(3, builders.size());
+ assertEquals(3, protos.size());
+ }
+
+ 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
+ }
+ }
+ }
+
+ private RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder>
+ newRepeatedFieldBuilder(GeneratedMessage.BuilderParent parent) {
+ return new RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder>(Collections.<TestAllTypes>emptyList(), false,
+ parent, false);
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java b/java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java
new file mode 100644
index 0000000..212f8d6
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java
@@ -0,0 +1,97 @@
+// 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.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;
+ }
+
+ @Override
+ public void testGetTreeDepth() {
+ assertEquals(classUnderTest + " must have the expected tree depth",
+ 3, stringUnderTest.getTreeDepth());
+ }
+
+ @Override
+ public void testToString() throws UnsupportedEncodingException {
+ String sourceString = "I love unicode \u1234\u5678 characters";
+ ByteString sourceByteString = ByteString.copyFromUtf8(sourceString);
+ int copies = 250;
+
+ // By building the RopeByteString by concatenating, this is actually a fairly strenuous test.
+ StringBuilder builder = new StringBuilder(copies * sourceString.length());
+ ByteString unicode = ByteString.EMPTY;
+ for (int i = 0; i < copies; ++i) {
+ builder.append(sourceString);
+ unicode = RopeByteString.concatenate(unicode, sourceByteString);
+ }
+ String testString = builder.toString();
+
+ // Do the substring part
+ testString = testString.substring(2, testString.length() - 6);
+ unicode = unicode.substring(2, unicode.size() - 6);
+
+ assertEquals(classUnderTest + " from string must have the expected type",
+ classUnderTest, getActualClassName(unicode));
+ String roundTripString = unicode.toString(UTF_8);
+ assertEquals(classUnderTest + " unicode bytes must match",
+ testString, roundTripString);
+ ByteString flatString = ByteString.copyFromUtf8(testString);
+ assertEquals(classUnderTest + " string must equal the flat string", flatString, unicode);
+ assertEquals(classUnderTest + " string must must have same hashCode as the flat string",
+ flatString.hashCode(), unicode.hashCode());
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/RopeByteStringTest.java b/java/src/test/java/com/google/protobuf/RopeByteStringTest.java
new file mode 100644
index 0000000..9676f52
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/RopeByteStringTest.java
@@ -0,0 +1,115 @@
+// 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.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;
+ }
+
+ @Override
+ public void testGetTreeDepth() {
+ assertEquals(classUnderTest + " must have the expected tree depth",
+ 4, stringUnderTest.getTreeDepth());
+ }
+
+ 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());
+ }
+
+ @Override
+ public void testToString() throws UnsupportedEncodingException {
+ String sourceString = "I love unicode \u1234\u5678 characters";
+ ByteString sourceByteString = ByteString.copyFromUtf8(sourceString);
+ int copies = 250;
+
+ // By building the RopeByteString by concatenating, this is actually a fairly strenuous test.
+ StringBuilder builder = new StringBuilder(copies * sourceString.length());
+ ByteString unicode = ByteString.EMPTY;
+ for (int i = 0; i < copies; ++i) {
+ builder.append(sourceString);
+ unicode = RopeByteString.concatenate(unicode, sourceByteString);
+ }
+ String testString = builder.toString();
+
+ assertEquals(classUnderTest + " from string must have the expected type",
+ classUnderTest, getActualClassName(unicode));
+ String roundTripString = unicode.toString(UTF_8);
+ assertEquals(classUnderTest + " unicode bytes must match",
+ testString, roundTripString);
+ ByteString flatString = ByteString.copyFromUtf8(testString);
+ assertEquals(classUnderTest + " string must equal the flat string", flatString, unicode);
+ assertEquals(classUnderTest + " string must must have same hashCode as the flat string",
+ flatString.hashCode(), unicode.hashCode());
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/ServiceTest.java b/java/src/test/java/com/google/protobuf/ServiceTest.java
index e10322d..ff980d6 100644
--- a/java/src/test/java/com/google/protobuf/ServiceTest.java
+++ b/java/src/test/java/com/google/protobuf/ServiceTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -205,12 +205,6 @@ public class ServiceTest extends TestCase {
MethodDescriptor fooMethod =
ServiceWithNoOuter.getDescriptor().findMethodByName("Foo");
MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance();
- RpcCallback<Message> callback = new RpcCallback<Message>() {
- public void run(Message parameter) {
- // No reason this should be run.
- fail();
- }
- };
TestAllTypes expectedResponse = TestAllTypes.getDefaultInstance();
EasyMock.expect(impl.foo(EasyMock.same(controller), EasyMock.same(request)))
@@ -250,6 +244,14 @@ public class ServiceTest extends TestCase {
// 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));
}
diff --git a/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java b/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java
new file mode 100644
index 0000000..58b8000
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java
@@ -0,0 +1,155 @@
+// 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.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link SingleFieldBuilder}. 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 void testBasicUseAndInvalidations() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder =
+ new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder>(
+ TestAllTypes.getDefaultInstance(),
+ mockParent,
+ false);
+ assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+ assertEquals(TestAllTypes.getDefaultInstance(),
+ builder.getBuilder().buildPartial());
+ assertEquals(0, mockParent.getInvalidationCount());
+
+ builder.getBuilder().setOptionalInt32(10);
+ assertEquals(0, mockParent.getInvalidationCount());
+ TestAllTypes message = builder.build();
+ assertEquals(10, message.getOptionalInt32());
+
+ // Test that we receive invalidations now that build has been called.
+ assertEquals(0, mockParent.getInvalidationCount());
+ builder.getBuilder().setOptionalInt32(20);
+ assertEquals(1, mockParent.getInvalidationCount());
+
+ // Test that we don't keep getting invalidations on every change
+ builder.getBuilder().setOptionalInt32(30);
+ assertEquals(1, mockParent.getInvalidationCount());
+
+ }
+
+ public void testSetMessage() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder =
+ new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder>(
+ TestAllTypes.getDefaultInstance(),
+ mockParent,
+ false);
+ builder.setMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
+ assertEquals(0, builder.getMessage().getOptionalInt32());
+
+ // Update message using the builder
+ builder.getBuilder().setOptionalInt32(1);
+ assertEquals(0, mockParent.getInvalidationCount());
+ assertEquals(1, builder.getBuilder().getOptionalInt32());
+ assertEquals(1, builder.getMessage().getOptionalInt32());
+ builder.build();
+ builder.getBuilder().setOptionalInt32(2);
+ assertEquals(2, builder.getBuilder().getOptionalInt32());
+ assertEquals(2, builder.getMessage().getOptionalInt32());
+
+ // Make sure message stays cached
+ assertSame(builder.getMessage(), builder.getMessage());
+ }
+
+ public void testClear() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder =
+ new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder>(
+ TestAllTypes.getDefaultInstance(),
+ mockParent,
+ false);
+ builder.setMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
+ assertNotSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+ builder.clear();
+ assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+
+ builder.getBuilder().setOptionalInt32(1);
+ assertNotSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+ builder.clear();
+ assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+ }
+
+ public void testMerge() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder =
+ new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder>(
+ TestAllTypes.getDefaultInstance(),
+ mockParent,
+ false);
+
+ // Merge into default field.
+ builder.mergeFrom(TestAllTypes.getDefaultInstance());
+ assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+
+ // Merge into non-default field on existing builder.
+ builder.getBuilder().setOptionalInt32(2);
+ builder.mergeFrom(TestAllTypes.newBuilder()
+ .setOptionalDouble(4.0)
+ .buildPartial());
+ assertEquals(2, builder.getMessage().getOptionalInt32());
+ assertEquals(4.0, builder.getMessage().getOptionalDouble());
+
+ // Merge into non-default field on existing message
+ builder.setMessage(TestAllTypes.newBuilder()
+ .setOptionalInt32(10)
+ .buildPartial());
+ builder.mergeFrom(TestAllTypes.newBuilder()
+ .setOptionalDouble(5.0)
+ .buildPartial());
+ assertEquals(10, builder.getMessage().getOptionalInt32());
+ assertEquals(5.0, builder.getMessage().getOptionalDouble());
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java b/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java
new file mode 100644
index 0000000..366086d
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java
@@ -0,0 +1,420 @@
+// 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.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * @author darick@google.com Darick Tong
+ */
+public class SmallSortedMapTest extends TestCase {
+ // java.util.AbstractMap.SimpleEntry is private in JDK 1.5. We re-implement it
+ // here for JDK 1.5 users.
+ private static class SimpleEntry<K, V> implements Map.Entry<K, V> {
+ private final K key;
+ private V value;
+
+ SimpleEntry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public K getKey() {
+ return key;
+ }
+
+ public V getValue() {
+ return value;
+ }
+
+ public V setValue(V value) {
+ V oldValue = this.value;
+ this.value = value;
+ return oldValue;
+ }
+
+ private static boolean eq(Object o1, Object o2) {
+ return o1 == null ? o2 == null : o1.equals(o2);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof Map.Entry))
+ return false;
+ Map.Entry e = (Map.Entry) o;
+ return eq(key, e.getKey()) && eq(value, e.getValue());
+ }
+
+ @Override
+ public int hashCode() {
+ return ((key == null) ? 0 : key.hashCode()) ^
+ ((value == null) ? 0 : value.hashCode());
+ }
+ }
+
+ public void testPutAndGetArrayEntriesOnly() {
+ runPutAndGetTest(3);
+ }
+
+ public void testPutAndGetOverflowEntries() {
+ runPutAndGetTest(6);
+ }
+
+ private void runPutAndGetTest(int numElements) {
+ // Test with even and odd arraySize
+ SmallSortedMap<Integer, Integer> map1 =
+ SmallSortedMap.newInstanceForTest(3);
+ SmallSortedMap<Integer, Integer> map2 =
+ SmallSortedMap.newInstanceForTest(4);
+ SmallSortedMap<Integer, Integer> map3 =
+ SmallSortedMap.newInstanceForTest(3);
+ SmallSortedMap<Integer, Integer> map4 =
+ SmallSortedMap.newInstanceForTest(4);
+
+ // Test with puts in ascending order.
+ for (int i = 0; i < numElements; i++) {
+ assertNull(map1.put(i, i + 1));
+ assertNull(map2.put(i, i + 1));
+ }
+ // Test with puts in descending order.
+ for (int i = numElements - 1; i >= 0; i--) {
+ assertNull(map3.put(i, i + 1));
+ assertNull(map4.put(i, i + 1));
+ }
+
+ assertEquals(Math.min(3, numElements), map1.getNumArrayEntries());
+ assertEquals(Math.min(4, numElements), map2.getNumArrayEntries());
+ assertEquals(Math.min(3, numElements), map3.getNumArrayEntries());
+ assertEquals(Math.min(4, numElements), map4.getNumArrayEntries());
+
+ List<SmallSortedMap<Integer, Integer>> allMaps =
+ new ArrayList<SmallSortedMap<Integer, Integer>>();
+ allMaps.add(map1);
+ allMaps.add(map2);
+ allMaps.add(map3);
+ allMaps.add(map4);
+
+ for (SmallSortedMap<Integer, Integer> map : allMaps) {
+ assertEquals(numElements, map.size());
+ for (int i = 0; i < numElements; i++) {
+ assertEquals(new Integer(i + 1), map.get(i));
+ }
+ }
+
+ assertEquals(map1, map2);
+ assertEquals(map2, map3);
+ assertEquals(map3, map4);
+ }
+
+ public void testReplacingPut() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ assertNull(map.remove(i + 1));
+ }
+ for (int i = 0; i < 6; i++) {
+ assertEquals(new Integer(i + 1), map.put(i, i + 2));
+ }
+ }
+
+ public void testRemove() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ assertNull(map.remove(i + 1));
+ }
+
+ assertEquals(3, map.getNumArrayEntries());
+ assertEquals(3, map.getNumOverflowEntries());
+ assertEquals(6, map.size());
+ assertEquals(makeSortedKeySet(0, 1, 2, 3, 4, 5), map.keySet());
+
+ assertEquals(new Integer(2), map.remove(1));
+ assertEquals(3, map.getNumArrayEntries());
+ assertEquals(2, map.getNumOverflowEntries());
+ assertEquals(5, map.size());
+ assertEquals(makeSortedKeySet(0, 2, 3, 4, 5), map.keySet());
+
+ assertEquals(new Integer(5), map.remove(4));
+ assertEquals(3, map.getNumArrayEntries());
+ assertEquals(1, map.getNumOverflowEntries());
+ assertEquals(4, map.size());
+ assertEquals(makeSortedKeySet(0, 2, 3, 5), map.keySet());
+
+ assertEquals(new Integer(4), map.remove(3));
+ assertEquals(3, map.getNumArrayEntries());
+ assertEquals(0, map.getNumOverflowEntries());
+ assertEquals(3, map.size());
+ assertEquals(makeSortedKeySet(0, 2, 5), map.keySet());
+
+ assertNull(map.remove(3));
+ assertEquals(3, map.getNumArrayEntries());
+ assertEquals(0, map.getNumOverflowEntries());
+ assertEquals(3, map.size());
+
+ assertEquals(new Integer(1), map.remove(0));
+ assertEquals(2, map.getNumArrayEntries());
+ assertEquals(0, map.getNumOverflowEntries());
+ assertEquals(2, map.size());
+ }
+
+ public void testClear() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ map.clear();
+ assertEquals(0, map.getNumArrayEntries());
+ assertEquals(0, map.getNumOverflowEntries());
+ assertEquals(0, map.size());
+ }
+
+ public void testGetArrayEntryAndOverflowEntries() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ assertEquals(3, map.getNumArrayEntries());
+ for (int i = 0; i < 3; i++) {
+ Map.Entry<Integer, Integer> entry = map.getArrayEntryAt(i);
+ assertEquals(new Integer(i), entry.getKey());
+ assertEquals(new Integer(i + 1), entry.getValue());
+ }
+ Iterator<Map.Entry<Integer, Integer>> it =
+ map.getOverflowEntries().iterator();
+ for (int i = 3; i < 6; i++) {
+ assertTrue(it.hasNext());
+ Map.Entry<Integer, Integer> entry = it.next();
+ assertEquals(new Integer(i), entry.getKey());
+ assertEquals(new Integer(i + 1), entry.getValue());
+ }
+ assertFalse(it.hasNext());
+ }
+
+ public void testEntrySetContains() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
+ for (int i = 0; i < 6; i++) {
+ assertTrue(
+ entrySet.contains(new SimpleEntry<Integer, Integer>(i, i + 1)));
+ assertFalse(
+ entrySet.contains(new SimpleEntry<Integer, Integer>(i, i)));
+ }
+ }
+
+ public void testEntrySetAdd() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
+ for (int i = 0; i < 6; i++) {
+ Map.Entry<Integer, Integer> entry =
+ new SimpleEntry<Integer, Integer>(i, i + 1);
+ assertTrue(entrySet.add(entry));
+ assertFalse(entrySet.add(entry));
+ }
+ for (int i = 0; i < 6; i++) {
+ assertEquals(new Integer(i + 1), map.get(i));
+ }
+ assertEquals(3, map.getNumArrayEntries());
+ assertEquals(3, map.getNumOverflowEntries());
+ assertEquals(6, map.size());
+ }
+
+ public void testEntrySetRemove() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ for (int i = 0; i < 6; i++) {
+ Map.Entry<Integer, Integer> entry =
+ new SimpleEntry<Integer, Integer>(i, i + 1);
+ assertTrue(entrySet.remove(entry));
+ assertFalse(entrySet.remove(entry));
+ }
+ assertTrue(map.isEmpty());
+ assertEquals(0, map.getNumArrayEntries());
+ assertEquals(0, map.getNumOverflowEntries());
+ assertEquals(0, map.size());
+ }
+
+ public void testEntrySetClear() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ map.entrySet().clear();
+ assertTrue(map.isEmpty());
+ assertEquals(0, map.getNumArrayEntries());
+ assertEquals(0, map.getNumOverflowEntries());
+ assertEquals(0, map.size());
+ }
+
+ public void testEntrySetIteratorNext() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
+ for (int i = 0; i < 6; i++) {
+ assertTrue(it.hasNext());
+ Map.Entry<Integer, Integer> entry = it.next();
+ assertEquals(new Integer(i), entry.getKey());
+ assertEquals(new Integer(i + 1), entry.getValue());
+ }
+ assertFalse(it.hasNext());
+ }
+
+ public void testEntrySetIteratorRemove() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
+ for (int i = 0; i < 6; i++) {
+ assertTrue(map.containsKey(i));
+ it.next();
+ it.remove();
+ assertFalse(map.containsKey(i));
+ assertEquals(6 - i - 1, map.size());
+ }
+ }
+
+ public void testMapEntryModification() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
+ for (int i = 0; i < 6; i++) {
+ Map.Entry<Integer, Integer> entry = it.next();
+ entry.setValue(i + 23);
+ }
+ for (int i = 0; i < 6; i++) {
+ assertEquals(new Integer(i + 23), map.get(i));
+ }
+ }
+
+ public void testMakeImmutable() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ map.makeImmutable();
+ assertEquals(new Integer(1), map.get(0));
+ assertEquals(6, map.size());
+
+ try {
+ map.put(23, 23);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ Map<Integer, Integer> other = new HashMap<Integer, Integer>();
+ other.put(23, 23);
+ try {
+ map.putAll(other);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ try {
+ map.remove(0);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ try {
+ map.clear();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
+ try {
+ entrySet.clear();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ Iterator<Map.Entry<Integer, Integer>> it = entrySet.iterator();
+ while (it.hasNext()) {
+ Map.Entry<Integer, Integer> entry = it.next();
+ try {
+ entry.setValue(0);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ it.remove();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ Set<Integer> keySet = map.keySet();
+ try {
+ keySet.clear();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ Iterator<Integer> keys = keySet.iterator();
+ while (keys.hasNext()) {
+ Integer key = keys.next();
+ try {
+ keySet.remove(key);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ keys.remove();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+ }
+
+ private Set<Integer> makeSortedKeySet(Integer... keys) {
+ return new TreeSet<Integer>(Arrays.<Integer>asList(keys));
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java b/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java
new file mode 100644
index 0000000..614ac7f
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java
@@ -0,0 +1,96 @@
+// 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;
+
+/**
+ * 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();
+ }
+
+ public void testConflictingFieldNames() throws Exception {
+ TestBadIdentifiersProto.TestConflictingFieldNames message =
+ TestBadIdentifiersProto.TestConflictingFieldNames.getDefaultInstance();
+ // Make sure generated accessors are properly named.
+ assertEquals(0, message.getInt32Field1Count());
+ assertEquals(0, message.getEnumField2Count());
+ assertEquals(0, message.getStringField3Count());
+ assertEquals(0, message.getBytesField4Count());
+ assertEquals(0, message.getMessageField5Count());
+
+ assertEquals(0, message.getInt32FieldCount11());
+ assertEquals(1, message.getEnumFieldCount12().getNumber());
+ assertEquals("", message.getStringFieldCount13());
+ assertEquals(ByteString.EMPTY, message.getBytesFieldCount14());
+ assertEquals(0, message.getMessageFieldCount15().getSerializedSize());
+
+ assertEquals(0, message.getInt32Field21Count());
+ assertEquals(0, message.getEnumField22Count());
+ assertEquals(0, message.getStringField23Count());
+ assertEquals(0, message.getBytesField24Count());
+ assertEquals(0, message.getMessageField25Count());
+
+ assertEquals(0, message.getInt32Field1List().size());
+ assertEquals(0, message.getInt32FieldList31());
+
+ assertEquals(0, message.getInt64FieldCount());
+ assertEquals(0L, message.getExtension(
+ TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldCount).longValue());
+ assertEquals(0L, message.getExtension(
+ TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldList).longValue());
+
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/TestUtil.java b/java/src/test/java/com/google/protobuf/TestUtil.java
index 2b8b2af..135a117 100644
--- a/java/src/test/java/com/google/protobuf/TestUtil.java
+++ b/java/src/test/java/com/google/protobuf/TestUtil.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -56,6 +56,11 @@ 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.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;
@@ -72,14 +77,16 @@ 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.optionalNestedMessageExtension;
+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.optionalForeignEnumExtension;
-import static protobuf_unittest.UnittestProto.optionalImportEnumExtension;
+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.optionalCordExtension;
import static protobuf_unittest.UnittestProto.repeatedInt32Extension;
import static protobuf_unittest.UnittestProto.repeatedInt64Extension;
@@ -100,6 +107,7 @@ 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;
@@ -145,6 +153,11 @@ 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;
@@ -162,11 +175,13 @@ 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.optionalForeignEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalImportEnumExtensionLite;
+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;
@@ -189,6 +204,7 @@ 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;
@@ -214,22 +230,28 @@ import static com.google.protobuf.UnittestLite.packedBoolExtensionLite;
import static com.google.protobuf.UnittestLite.packedEnumExtensionLite;
import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllExtensionsOrBuilder;
import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
+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.ImportMessage;
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.ImportMessageLite;
import com.google.protobuf.UnittestImportLite.ImportEnumLite;
+import com.google.protobuf.UnittestImportLite.ImportMessageLite;
+import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
import junit.framework.Assert;
@@ -239,14 +261,17 @@ import java.io.RandomAccessFile;
/**
* Contains methods for setting all fields of {@code TestAllTypes} to
- * some vaules as well as checking that all the fields are set to those values.
+ * 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
*/
-class TestUtil {
+public final class TestUtil {
private TestUtil() {}
/** Helper to convert a String to ByteString. */
@@ -269,6 +294,16 @@ class TestUtil {
}
/**
+ * 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)}.
*/
@@ -338,6 +373,10 @@ class TestUtil {
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);
@@ -372,6 +411,8 @@ class TestUtil {
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);
@@ -405,6 +446,8 @@ class TestUtil {
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);
@@ -437,6 +480,12 @@ class TestUtil {
message.setDefaultStringPiece("424");
message.setDefaultCord("425");
+
+ message.setOneofUint32(601);
+ message.setOneofNestedMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(602).build());
+ message.setOneofString("603");
+ message.setOneofBytes(toBytes("604"));
}
// -------------------------------------------------------------------
@@ -470,6 +519,8 @@ class TestUtil {
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);
@@ -485,7 +536,7 @@ class TestUtil {
* 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(TestAllTypes message) {
+ public static void assertAllFieldsSet(TestAllTypesOrBuilder message) {
Assert.assertTrue(message.hasOptionalInt32 ());
Assert.assertTrue(message.hasOptionalInt64 ());
Assert.assertTrue(message.hasOptionalUint32 ());
@@ -535,10 +586,12 @@ class TestUtil {
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(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());
@@ -569,6 +622,7 @@ class TestUtil {
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 ());
@@ -596,6 +650,7 @@ class TestUtil {
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));
@@ -624,6 +679,7 @@ class TestUtil {
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));
@@ -679,16 +735,22 @@ class TestUtil {
Assert.assertEquals("424", message.getDefaultStringPiece());
Assert.assertEquals("425", message.getDefaultCord());
+
+ Assert.assertFalse(message.hasOneofUint32());
+ Assert.assertFalse(message.hasOneofNestedMessage());
+ Assert.assertFalse(message.hasOneofString());
+ Assert.assertTrue(message.hasOneofBytes());
+
+ Assert.assertEquals(toBytes("604"), message.getOneofBytes());
}
// -------------------------------------------------------------------
-
/**
* 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(TestAllTypes message) {
+ public static void assertClear(TestAllTypesOrBuilder message) {
// hasBlah() should initially be false for all optional fields.
Assert.assertFalse(message.hasOptionalInt32 ());
Assert.assertFalse(message.hasOptionalInt64 ());
@@ -736,15 +798,19 @@ class TestUtil {
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.assertEquals(0, message.getOptionalGroup ().getA());
- Assert.assertEquals(0, message.getOptionalNestedMessage ().getBb());
- Assert.assertEquals(0, message.getOptionalForeignMessage().getC());
- Assert.assertEquals(0, message.getOptionalImportMessage ().getD());
+ 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 ());
@@ -775,6 +841,7 @@ class TestUtil {
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 ());
@@ -829,6 +896,11 @@ class TestUtil {
Assert.assertEquals("abc", message.getDefaultStringPiece());
Assert.assertEquals("123", message.getDefaultCord());
+
+ Assert.assertFalse(message.hasOneofUint32());
+ Assert.assertFalse(message.hasOneofNestedMessage());
+ Assert.assertFalse(message.hasOneofString());
+ Assert.assertFalse(message.hasOneofBytes());
}
// -------------------------------------------------------------------
@@ -838,7 +910,8 @@ class TestUtil {
* {@code message} are set to the values assigned by {@code setAllFields}
* followed by {@code modifyRepeatedFields}.
*/
- public static void assertRepeatedFieldsModified(TestAllTypes message) {
+ 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.
@@ -862,6 +935,7 @@ class TestUtil {
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 ());
@@ -889,6 +963,7 @@ class TestUtil {
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));
@@ -918,6 +993,7 @@ class TestUtil {
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));
@@ -1204,6 +1280,10 @@ class TestUtil {
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);
@@ -1238,6 +1318,8 @@ class TestUtil {
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);
@@ -1271,6 +1353,8 @@ class TestUtil {
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);
@@ -1303,6 +1387,12 @@ class TestUtil {
message.setExtension(defaultStringPieceExtension, "424");
message.setExtension(defaultCordExtension, "425");
+
+ message.setExtension(oneofUint32Extension, 601);
+ message.setExtension(oneofNestedMessageExtension,
+ TestAllTypes.NestedMessage.newBuilder().setBb(602).build());
+ message.setExtension(oneofStringExtension, "603");
+ message.setExtension(oneofBytesExtension, toBytes("604"));
}
// -------------------------------------------------------------------
@@ -1337,6 +1427,8 @@ class TestUtil {
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);
@@ -1352,7 +1444,8 @@ class TestUtil {
* 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(TestAllExtensions message) {
+ public static void assertAllExtensionsSet(
+ TestAllExtensionsOrBuilder message) {
Assert.assertTrue(message.hasExtension(optionalInt32Extension ));
Assert.assertTrue(message.hasExtension(optionalInt64Extension ));
Assert.assertTrue(message.hasExtension(optionalUint32Extension ));
@@ -1402,10 +1495,12 @@ class TestUtil {
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(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));
@@ -1439,6 +1534,7 @@ class TestUtil {
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 ));
@@ -1466,6 +1562,7 @@ class TestUtil {
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));
@@ -1497,6 +1594,7 @@ class TestUtil {
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));
@@ -1558,6 +1656,10 @@ class TestUtil {
assertEqualsExactType("424", message.getExtension(defaultStringPieceExtension));
assertEqualsExactType("425", message.getExtension(defaultCordExtension));
+
+ Assert.assertTrue(message.hasExtension(oneofBytesExtension));
+
+ assertEqualsExactType(toBytes("604"), message.getExtension(oneofBytesExtension));
}
// -------------------------------------------------------------------
@@ -1567,7 +1669,7 @@ class TestUtil {
* {@code message} are cleared, and that getting the extensions returns their
* default values.
*/
- public static void assertExtensionsClear(TestAllExtensions message) {
+ 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 ));
@@ -1657,6 +1759,7 @@ class TestUtil {
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 ));
@@ -1685,6 +1788,7 @@ class TestUtil {
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());
@@ -1742,6 +1846,11 @@ class TestUtil {
assertEqualsExactType("abc", message.getExtension(defaultStringPieceExtension));
assertEqualsExactType("123", message.getExtension(defaultCordExtension));
+
+ Assert.assertFalse(message.hasExtension(oneofUint32Extension));
+ Assert.assertFalse(message.hasExtension(oneofNestedMessageExtension));
+ Assert.assertFalse(message.hasExtension(oneofStringExtension));
+ Assert.assertFalse(message.hasExtension(oneofBytesExtension));
}
// -------------------------------------------------------------------
@@ -1752,7 +1861,7 @@ class TestUtil {
* followed by {@code modifyRepeatedExtensions}.
*/
public static void assertRepeatedExtensionsModified(
- TestAllExtensions message) {
+ 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.
@@ -1776,6 +1885,7 @@ class TestUtil {
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 ));
@@ -1803,6 +1913,7 @@ class TestUtil {
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));
@@ -1835,6 +1946,7 @@ class TestUtil {
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));
@@ -1958,6 +2070,10 @@ class TestUtil {
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);
@@ -1992,6 +2108,8 @@ class TestUtil {
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);
@@ -2025,6 +2143,8 @@ class TestUtil {
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);
@@ -2057,6 +2177,12 @@ class TestUtil {
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"));
}
// -------------------------------------------------------------------
@@ -2091,6 +2217,8 @@ class TestUtil {
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);
@@ -2106,7 +2234,8 @@ class TestUtil {
* 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(TestAllExtensionsLite message) {
+ public static void assertAllExtensionsSet(
+ TestAllExtensionsLiteOrBuilder message) {
Assert.assertTrue(message.hasExtension(optionalInt32ExtensionLite ));
Assert.assertTrue(message.hasExtension(optionalInt64ExtensionLite ));
Assert.assertTrue(message.hasExtension(optionalUint32ExtensionLite ));
@@ -2160,6 +2289,9 @@ class TestUtil {
assertEqualsExactType(118, message.getExtension(optionalNestedMessageExtensionLite ).getBb());
assertEqualsExactType(119, message.getExtension(optionalForeignMessageExtensionLite).getC());
assertEqualsExactType(120, message.getExtension(optionalImportMessageExtensionLite ).getD());
+ assertEqualsExactType(126, message.getExtension(
+ optionalPublicImportMessageExtensionLite).getE());
+ assertEqualsExactType(127, message.getExtension(optionalLazyMessageExtensionLite).getBb());
assertEqualsExactType(TestAllTypesLite.NestedEnum.BAZ,
message.getExtension(optionalNestedEnumExtensionLite));
@@ -2193,6 +2325,7 @@ class TestUtil {
Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtensionLite ));
Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtensionLite));
Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtensionLite ));
Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtensionLite ));
Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtensionLite ));
Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtensionLite ));
@@ -2220,6 +2353,7 @@ class TestUtil {
assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtensionLite ,0).getBb());
assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtensionLite,0).getC());
assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtensionLite ,0).getD());
+ assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtensionLite ,0).getBb());
assertEqualsExactType(TestAllTypesLite.NestedEnum.BAR,
message.getExtension(repeatedNestedEnumExtensionLite, 0));
@@ -2251,6 +2385,7 @@ class TestUtil {
assertEqualsExactType(318, message.getExtension(repeatedNestedMessageExtensionLite ,1).getBb());
assertEqualsExactType(319, message.getExtension(repeatedForeignMessageExtensionLite,1).getC());
assertEqualsExactType(320, message.getExtension(repeatedImportMessageExtensionLite ,1).getD());
+ assertEqualsExactType(327, message.getExtension(repeatedLazyMessageExtensionLite ,1).getBb());
assertEqualsExactType(TestAllTypesLite.NestedEnum.BAZ,
message.getExtension(repeatedNestedEnumExtensionLite, 1));
@@ -2312,6 +2447,10 @@ class TestUtil {
assertEqualsExactType("424", message.getExtension(defaultStringPieceExtensionLite));
assertEqualsExactType("425", message.getExtension(defaultCordExtensionLite));
+
+ Assert.assertTrue(message.hasExtension(oneofBytesExtensionLite));
+
+ assertEqualsExactType(toBytes("604"), message.getExtension(oneofBytesExtensionLite));
}
// -------------------------------------------------------------------
@@ -2321,7 +2460,8 @@ class TestUtil {
* {@code message} are cleared, and that getting the extensions returns their
* default values.
*/
- public static void assertExtensionsClear(TestAllExtensionsLite message) {
+ public static void assertExtensionsClear(
+ TestAllExtensionsLiteOrBuilder message) {
// hasBlah() should initially be false for all optional fields.
Assert.assertFalse(message.hasExtension(optionalInt32ExtensionLite ));
Assert.assertFalse(message.hasExtension(optionalInt64ExtensionLite ));
@@ -2339,10 +2479,12 @@ class TestUtil {
Assert.assertFalse(message.hasExtension(optionalStringExtensionLite ));
Assert.assertFalse(message.hasExtension(optionalBytesExtensionLite ));
- Assert.assertFalse(message.hasExtension(optionalGroupExtensionLite ));
- Assert.assertFalse(message.hasExtension(optionalNestedMessageExtensionLite ));
- Assert.assertFalse(message.hasExtension(optionalForeignMessageExtensionLite));
- Assert.assertFalse(message.hasExtension(optionalImportMessageExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalGroupExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalNestedMessageExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalForeignMessageExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalImportMessageExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalPublicImportMessageExtensionLite));
+ Assert.assertFalse(message.hasExtension(optionalLazyMessageExtensionLite ));
Assert.assertFalse(message.hasExtension(optionalNestedEnumExtensionLite ));
Assert.assertFalse(message.hasExtension(optionalForeignEnumExtensionLite));
@@ -2369,15 +2511,20 @@ class TestUtil {
assertEqualsExactType(ByteString.EMPTY, message.getExtension(optionalBytesExtensionLite));
// Embedded messages should also be clear.
- Assert.assertFalse(message.getExtension(optionalGroupExtensionLite ).hasA());
- Assert.assertFalse(message.getExtension(optionalNestedMessageExtensionLite ).hasBb());
- Assert.assertFalse(message.getExtension(optionalForeignMessageExtensionLite).hasC());
- Assert.assertFalse(message.getExtension(optionalImportMessageExtensionLite ).hasD());
+ Assert.assertFalse(message.getExtension(optionalGroupExtensionLite ).hasA());
+ Assert.assertFalse(message.getExtension(optionalNestedMessageExtensionLite ).hasBb());
+ Assert.assertFalse(message.getExtension(optionalForeignMessageExtensionLite ).hasC());
+ Assert.assertFalse(message.getExtension(optionalImportMessageExtensionLite ).hasD());
+ Assert.assertFalse(message.getExtension(optionalPublicImportMessageExtensionLite).hasE());
+ Assert.assertFalse(message.getExtension(optionalLazyMessageExtensionLite ).hasBb());
assertEqualsExactType(0, message.getExtension(optionalGroupExtensionLite ).getA());
assertEqualsExactType(0, message.getExtension(optionalNestedMessageExtensionLite ).getBb());
assertEqualsExactType(0, message.getExtension(optionalForeignMessageExtensionLite).getC());
assertEqualsExactType(0, message.getExtension(optionalImportMessageExtensionLite ).getD());
+ assertEqualsExactType(0, message.getExtension(
+ optionalPublicImportMessageExtensionLite).getE());
+ assertEqualsExactType(0, message.getExtension(optionalLazyMessageExtensionLite ).getBb());
// Enums without defaults are set to the first value in the enum.
assertEqualsExactType(TestAllTypesLite.NestedEnum.FOO,
@@ -2411,6 +2558,7 @@ class TestUtil {
Assert.assertEquals(0, message.getExtensionCount(repeatedNestedMessageExtensionLite ));
Assert.assertEquals(0, message.getExtensionCount(repeatedForeignMessageExtensionLite));
Assert.assertEquals(0, message.getExtensionCount(repeatedImportMessageExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedLazyMessageExtensionLite ));
Assert.assertEquals(0, message.getExtensionCount(repeatedNestedEnumExtensionLite ));
Assert.assertEquals(0, message.getExtensionCount(repeatedForeignEnumExtensionLite ));
Assert.assertEquals(0, message.getExtensionCount(repeatedImportEnumExtensionLite ));
@@ -2468,6 +2616,11 @@ class TestUtil {
assertEqualsExactType("abc", message.getExtension(defaultStringPieceExtensionLite));
assertEqualsExactType("123", message.getExtension(defaultCordExtensionLite));
+
+ Assert.assertFalse(message.hasExtension(oneofUint32ExtensionLite));
+ Assert.assertFalse(message.hasExtension(oneofNestedMessageExtensionLite));
+ Assert.assertFalse(message.hasExtension(oneofStringExtensionLite));
+ Assert.assertFalse(message.hasExtension(oneofBytesExtensionLite));
}
// -------------------------------------------------------------------
@@ -2478,7 +2631,7 @@ class TestUtil {
* followed by {@code modifyRepeatedExtensions}.
*/
public static void assertRepeatedExtensionsModified(
- TestAllExtensionsLite message) {
+ TestAllExtensionsLiteOrBuilder 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.
@@ -2502,6 +2655,7 @@ class TestUtil {
Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtensionLite ));
Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtensionLite));
Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtensionLite ));
Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtensionLite ));
Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtensionLite ));
Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtensionLite ));
@@ -2529,6 +2683,7 @@ class TestUtil {
assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtensionLite ,0).getBb());
assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtensionLite,0).getC());
assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtensionLite ,0).getD());
+ assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtensionLite ,0).getBb());
assertEqualsExactType(TestAllTypesLite.NestedEnum.BAR,
message.getExtension(repeatedNestedEnumExtensionLite, 0));
@@ -2561,6 +2716,7 @@ class TestUtil {
assertEqualsExactType(518, message.getExtension(repeatedNestedMessageExtensionLite ,1).getBb());
assertEqualsExactType(519, message.getExtension(repeatedForeignMessageExtensionLite,1).getC());
assertEqualsExactType(520, message.getExtension(repeatedImportMessageExtensionLite ,1).getD());
+ assertEqualsExactType(527, message.getExtension(repeatedLazyMessageExtensionLite ,1).getBb());
assertEqualsExactType(TestAllTypesLite.NestedEnum.FOO,
message.getExtension(repeatedNestedEnumExtensionLite, 1));
@@ -2652,6 +2808,82 @@ class TestUtil {
message.getExtension(packedEnumExtensionLite, 1));
}
+ // ===================================================================
+ // oneof
+ public static void setOneof(TestOneof2.Builder message) {
+ message.setFooLazyMessage(
+ TestOneof2.NestedMessage.newBuilder().setQuxInt(100).build());
+ message.setBarString("101");
+ message.setBazInt(102);
+ message.setBazString("103");
+ }
+
+ public static void assertOneofSet(TestOneof2 message) {
+ Assert.assertTrue(message.hasFooLazyMessage ());
+ Assert.assertTrue(message.getFooLazyMessage().hasQuxInt());
+
+ Assert.assertTrue(message.hasBarString());
+ Assert.assertTrue(message.hasBazInt ());
+ Assert.assertTrue(message.hasBazString());
+
+ Assert.assertEquals(100 , message.getFooLazyMessage().getQuxInt());
+ Assert.assertEquals("101", message.getBarString ());
+ Assert.assertEquals(102 , message.getBazInt ());
+ Assert.assertEquals("103", message.getBazString ());
+ }
+
+ public static void assertAtMostOneFieldSetOneof(TestOneof2 message) {
+ int count = 0;
+ if (message.hasFooInt()) { ++count; }
+ if (message.hasFooString()) { ++count; }
+ if (message.hasFooCord()) { ++count; }
+ if (message.hasFooStringPiece()) { ++count; }
+ if (message.hasFooBytes()) { ++count; }
+ if (message.hasFooEnum()) { ++count; }
+ if (message.hasFooMessage()) { ++count; }
+ if (message.hasFooGroup()) { ++count; }
+ if (message.hasFooLazyMessage()) { ++count; }
+ Assert.assertTrue(count <= 1);
+
+ count = 0;
+ if (message.hasBarInt()) { ++count; }
+ if (message.hasBarString()) { ++count; }
+ if (message.hasBarCord()) { ++count; }
+ if (message.hasBarStringPiece()) { ++count; }
+ if (message.hasBarBytes()) { ++count; }
+ if (message.hasBarEnum()) { ++count; }
+ Assert.assertTrue(count <= 1);
+
+ switch (message.getFooCase()) {
+ case FOO_INT:
+ Assert.assertTrue(message.hasFooInt());
+ break;
+ case FOO_STRING:
+ Assert.assertTrue(message.hasFooString());
+ break;
+ case FOO_CORD:
+ Assert.assertTrue(message.hasFooCord());
+ break;
+ case FOO_BYTES:
+ Assert.assertTrue(message.hasFooBytes());
+ break;
+ case FOO_ENUM:
+ Assert.assertTrue(message.hasFooEnum());
+ break;
+ case FOO_MESSAGE:
+ Assert.assertTrue(message.hasFooMessage());
+ break;
+ case FOOGROUP:
+ Assert.assertTrue(message.hasFooGroup());
+ break;
+ case FOO_LAZY_MESSAGE:
+ Assert.assertTrue(message.hasFooLazyMessage());
+ break;
+ case FOO_NOT_SET:
+ break;
+ }
+ }
+
// =================================================================
/**
@@ -2665,18 +2897,21 @@ class TestUtil {
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;
@@ -2713,6 +2948,7 @@ class TestUtil {
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") {
@@ -2739,6 +2975,8 @@ class TestUtil {
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");
@@ -2756,6 +2994,7 @@ class TestUtil {
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");
@@ -2774,6 +3013,7 @@ class TestUtil {
Assert.assertNotNull(nestedB );
Assert.assertNotNull(foreignC );
Assert.assertNotNull(importD );
+ Assert.assertNotNull(importE );
Assert.assertNotNull(nestedFoo );
Assert.assertNotNull(nestedBar );
Assert.assertNotNull(nestedBaz );
@@ -2810,8 +3050,8 @@ class TestUtil {
return parent.newBuilderForField(field);
} else {
ExtensionRegistry.ExtensionInfo extension =
- extensionRegistry.findExtensionByNumber(field.getContainingType(),
- field.getNumber());
+ extensionRegistry.findImmutableExtensionByNumber(
+ field.getContainingType(), field.getNumber());
Assert.assertNotNull(extension);
Assert.assertNotNull(extension.defaultInstance);
return extension.defaultInstance.newBuilderForType();
@@ -2854,6 +3094,12 @@ class TestUtil {
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);
@@ -2892,6 +3138,9 @@ class TestUtil {
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);
@@ -2929,6 +3178,9 @@ class TestUtil {
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);
@@ -2961,6 +3213,13 @@ class TestUtil {
message.setField(f("default_string_piece" ), "424");
message.setField(f("default_cord" ), "425");
+
+ message.setField(f("oneof_uint32" ), 601);
+ message.setField(f("oneof_nested_message"),
+ newBuilderForField(message, f("oneof_nested_message"))
+ .setField(nestedB, 602).build());
+ message.setField(f("oneof_string" ), "603");
+ message.setField(f("oneof_bytes" ), toBytes("604"));
}
// -------------------------------------------------------------------
@@ -2999,6 +3258,9 @@ class TestUtil {
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);
@@ -3015,7 +3277,7 @@ class TestUtil {
* {@code message} are set to the values assigned by {@code setAllFields},
* using the {@link Message} reflection interface.
*/
- public void assertAllFieldsSetViaReflection(Message message) {
+ 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" )));
@@ -3083,6 +3345,12 @@ class TestUtil {
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")));
@@ -3113,6 +3381,7 @@ class TestUtil {
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" )));
@@ -3148,6 +3417,9 @@ class TestUtil {
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));
@@ -3184,6 +3456,9 @@ class TestUtil {
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));
@@ -3239,6 +3514,24 @@ class TestUtil {
Assert.assertEquals("424", message.getField(f("default_string_piece")));
Assert.assertEquals("425", message.getField(f("default_cord")));
+
+ Assert.assertTrue(message.hasField(f("oneof_bytes")));
+ Assert.assertEquals(toBytes("604"), message.getField(f("oneof_bytes")));
+
+ if (extensionRegistry == null) {
+ Assert.assertFalse(message.hasField(f("oneof_uint32")));
+ Assert.assertFalse(message.hasField(f("oneof_nested_message")));
+ Assert.assertFalse(message.hasField(f("oneof_string")));
+ } else {
+ Assert.assertTrue(message.hasField(f("oneof_uint32")));
+ Assert.assertTrue(message.hasField(f("oneof_nested_message")));
+ Assert.assertTrue(message.hasField(f("oneof_string")));
+ Assert.assertEquals(601, message.getField(f("oneof_uint32")));
+ Assert.assertEquals(602,
+ ((MessageOrBuilder) message.getField(f("oneof_nested_message")))
+ .getField(nestedB));
+ Assert.assertEquals("603", message.getField(f("oneof_string")));
+ }
}
// -------------------------------------------------------------------
@@ -3248,7 +3541,7 @@ class TestUtil {
* {@code message} are cleared, and that getting the fields returns their
* default values, using the {@link Message} reflection interface.
*/
- public void assertClearViaReflection(Message message) {
+ 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" )));
@@ -3307,6 +3600,12 @@ class TestUtil {
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));
@@ -3319,6 +3618,12 @@ class TestUtil {
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" )));
@@ -3349,6 +3654,7 @@ class TestUtil {
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" )));
@@ -3403,11 +3709,22 @@ class TestUtil {
Assert.assertEquals("abc", message.getField(f("default_string_piece")));
Assert.assertEquals("123", message.getField(f("default_cord")));
+
+ Assert.assertFalse(message.hasField(f("oneof_uint32")));
+ Assert.assertFalse(message.hasField(f("oneof_nested_message")));
+ Assert.assertFalse(message.hasField(f("oneof_string")));
+ Assert.assertFalse(message.hasField(f("oneof_bytes")));
+
+ Assert.assertEquals(0, message.getField(f("oneof_uint32")));
+ Assert.assertEquals("", message.getField(f("oneof_string")));
+ Assert.assertEquals(toBytes(""), message.getField(f("oneof_bytes")));
}
+
// ---------------------------------------------------------------
- public void assertRepeatedFieldsModifiedViaReflection(Message message) {
+ 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.
@@ -3431,6 +3748,7 @@ class TestUtil {
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" )));
@@ -3466,6 +3784,9 @@ class TestUtil {
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));
@@ -3502,6 +3823,9 @@ class TestUtil {
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));
@@ -3543,7 +3867,7 @@ class TestUtil {
message.addRepeatedField(f("packed_enum" ), foreignBaz);
}
- public void assertPackedFieldsSetViaReflection(Message message) {
+ 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" )));
@@ -3699,7 +4023,7 @@ class TestUtil {
/**
* @param filePath The path relative to
- * {@link com.google.testing.util.TestUtil#getDefaultSrcDir}.
+ * {@link #getTestDataDir}.
*/
public static String readTextFromFile(String filePath) {
return readBytesFromFile(filePath).toStringUtf8();
@@ -3728,8 +4052,8 @@ class TestUtil {
}
/**
- * @param filePath The path relative to
- * {@link com.google.testing.util.TestUtil#getDefaultSrcDir}.
+ * @param filename The path relative to
+ * {@link #getTestDataDir}.
*/
public static ByteString readBytesFromFile(String filename) {
File fullPath = new File(getTestDataDir(), filename);
@@ -3749,13 +4073,13 @@ class TestUtil {
/**
* 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
+ * {@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");
+ goldenMessage = readBytesFromFile("golden_message_oneof_implemented");
}
return goldenMessage;
}
@@ -3764,7 +4088,7 @@ class TestUtil {
/**
* 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
+ * {@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++.
@@ -3777,4 +4101,24 @@ class TestUtil {
return goldenPackedFieldsMessage;
}
private static ByteString goldenPackedFieldsMessage = null;
+
+ /**
+ * Mock implementation of {@link GeneratedMessage.BuilderParent} for testing.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+ public static class MockBuilderParent
+ implements GeneratedMessage.BuilderParent {
+
+ 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/src/test/java/com/google/protobuf/TextFormatTest.java b/java/src/test/java/com/google/protobuf/TextFormatTest.java
index 60bd800..152bdad 100644
--- a/java/src/test/java/com/google/protobuf/TextFormatTest.java
+++ b/java/src/test/java/com/google/protobuf/TextFormatTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -31,14 +31,16 @@
package com.google.protobuf;
import com.google.protobuf.Descriptors.FieldDescriptor;
-import protobuf_unittest.UnittestProto.OneString;
-import protobuf_unittest.UnittestProto.TestAllTypes;
-import protobuf_unittest.UnittestProto.TestAllExtensions;
-import protobuf_unittest.UnittestProto.TestEmptyMessage;
-import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
+import com.google.protobuf.TextFormat.Parser.SingularOverwritePolicy;
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 protobuf_unittest.UnittestProto.TestOneof2;
import junit.framework.TestCase;
@@ -60,11 +62,11 @@ public class TextFormatTest extends TestCase {
// 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 \\\\\"";
+ "\\\"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");
+ "text_format_unittest_data_oneof_implemented.txt");
private static String allExtensionsSetText = TestUtil.readTextFromFile(
"text_format_unittest_extensions_data.txt");
@@ -109,6 +111,23 @@ public class TextFormatTest extends TestCase {
" str: \"foo\"\n" +
"}\n";
+ private String messageSetTextWithRepeatedExtension =
+ "[protobuf_unittest.TestMessageSetExtension1] {\n" +
+ " i: 123\n" +
+ "}\n" +
+ "[protobuf_unittest.TestMessageSetExtension1] {\n" +
+ " i: 456\n" +
+ "}\n";
+
+ private final TextFormat.Parser parserWithOverwriteForbidden =
+ TextFormat.Parser.newBuilder()
+ .setSingularOverwritePolicy(
+ SingularOverwritePolicy.FORBID_SINGULAR_OVERWRITES)
+ .build();
+
+ private final TextFormat.Parser defaultParser =
+ TextFormat.Parser.newBuilder().build();
+
/** Print TestAllTypes and compare with golden file. */
public void testPrintMessage() throws Exception {
String javaText = TextFormat.printToString(TestUtil.getAllSet());
@@ -121,6 +140,18 @@ public class TextFormatTest extends TestCase {
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());
@@ -133,40 +164,44 @@ public class TextFormatTest extends TestCase {
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(
- 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())
+ .setUnknownFields(makeUnknownFieldSet())
.build();
assertEquals(
@@ -234,8 +269,8 @@ public class TextFormatTest extends TestCase {
.addRepeatedInt32 (1 << 31)
.addRepeatedUint32(1 << 31)
- .addRepeatedInt64 (1l << 63)
- .addRepeatedUint64(1l << 63)
+ .addRepeatedInt64 (1L << 63)
+ .addRepeatedUint64(1L << 63)
// Floats of various precisions and exponents.
.addRepeatedDouble(123)
@@ -355,6 +390,40 @@ public class TextFormatTest extends TestCase {
TestMessageSetExtension2.messageSetExtension));
assertEquals("foo", messageSet.getExtension(
TestMessageSetExtension2.messageSetExtension).getStr());
+
+ builder = TestMessageSet.newBuilder();
+ TextFormat.merge(messageSetTextWithRepeatedExtension, extensionRegistry,
+ builder);
+ messageSet = builder.build();
+ assertEquals(456, messageSet.getExtension(
+ TestMessageSetExtension1.messageSetExtension).getI());
+ }
+
+ public void testParseMessageSetWithOverwriteForbidden() throws Exception {
+ ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
+ extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
+ extensionRegistry.add(TestMessageSetExtension2.messageSetExtension);
+
+ TestMessageSet.Builder builder = TestMessageSet.newBuilder();
+ parserWithOverwriteForbidden.merge(
+ messageSetText, extensionRegistry, builder);
+ TestMessageSet messageSet = builder.build();
+ assertEquals(123, messageSet.getExtension(
+ TestMessageSetExtension1.messageSetExtension).getI());
+ assertEquals("foo", messageSet.getExtension(
+ TestMessageSetExtension2.messageSetExtension).getStr());
+
+ builder = TestMessageSet.newBuilder();
+ try {
+ parserWithOverwriteForbidden.merge(
+ messageSetTextWithRepeatedExtension, extensionRegistry, builder);
+ fail("expected parse exception");
+ } catch (TextFormat.ParseException e) {
+ assertEquals("6:1: Non-repeated field "
+ + "\"protobuf_unittest.TestMessageSetExtension1.message_set_extension\""
+ + " cannot be overwritten.",
+ e.getMessage());
+ }
}
public void testParseNumericEnum() throws Exception {
@@ -391,12 +460,32 @@ public class TextFormatTest extends TestCase {
}
}
+ private void assertParseErrorWithOverwriteForbidden(String error,
+ String text) {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ try {
+ parserWithOverwriteForbidden.merge(
+ text, TestUtil.getExtensionRegistry(), builder);
+ fail("Expected parse exception.");
+ } catch (TextFormat.ParseException e) {
+ assertEquals(error, e.getMessage());
+ }
+ }
+
+ private TestAllTypes assertParseSuccessWithOverwriteForbidden(
+ String text) throws TextFormat.ParseException {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ parserWithOverwriteForbidden.merge(
+ text, TestUtil.getExtensionRegistry(), builder);
+ return builder.build();
+ }
+
public void testParseErrors() throws Exception {
assertParseError(
"1:16: Expected \":\".",
"optional_int32 123");
assertParseError(
- "1:23: Expected identifier.",
+ "1:23: Expected identifier. Found '?'",
"optional_nested_enum: ?");
assertParseError(
"1:18: Couldn't parse integer: Number must be positive: -1",
@@ -409,6 +498,9 @@ public class TextFormatTest extends TestCase {
"1:16: Expected \"true\" or \"false\".",
"optional_bool: maybe");
assertParseError(
+ "1:16: Expected \"true\" or \"false\".",
+ "optional_bool: 2");
+ assertParseError(
"1:18: Expected string.",
"optional_string: 123");
assertParseError(
@@ -450,10 +542,10 @@ public class TextFormatTest extends TestCase {
// Delimiters must match.
assertParseError(
- "1:22: Expected identifier.",
+ "1:22: Expected identifier. Found '}'",
"OptionalGroup < a: 1 }");
assertParseError(
- "1:22: Expected identifier.",
+ "1:22: Expected identifier. Found '>'",
"OptionalGroup { a: 1 >");
}
@@ -469,6 +561,10 @@ public class TextFormatTest extends TestCase {
TextFormat.unescapeBytes("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
assertEquals("\0\001\007\b\f\n\r\t\013\\\'\"",
TextFormat.unescapeText("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
+ assertEquals(kEscapeTestStringEscaped,
+ TextFormat.escapeText(kEscapeTestString));
+ assertEquals(kEscapeTestString,
+ TextFormat.unescapeText(kEscapeTestStringEscaped));
// Unicode handling.
assertEquals("\\341\\210\\264", TextFormat.escapeText("\u1234"));
@@ -481,6 +577,11 @@ public class TextFormatTest extends TestCase {
assertEquals(bytes(0xe1, 0x88, 0xb4),
TextFormat.unescapeBytes("\\xe1\\x88\\xb4"));
+ // Handling of strings with unescaped Unicode characters > 255.
+ final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c";
+ ByteString zhByteString = ByteString.copyFromUtf8(zh);
+ assertEquals(zhByteString, TextFormat.unescapeBytes(zh));
+
// Errors.
try {
TextFormat.unescapeText("\\x");
@@ -622,6 +723,13 @@ public class TextFormatTest extends TestCase {
}
}
+ 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" +
@@ -650,9 +758,237 @@ public class TextFormatTest extends TestCase {
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() throws Exception {
+ 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()));
+
+ // Double quotes and backslashes should be escaped
+ assertEquals(
+ "optional_string: \"a\\\\bc\\\"ef\\\"g\"\n",
+ TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+ .setOptionalString("a\\bc\"ef\"g")
+ .build()));
+
+ // Test escaping roundtrip
+ TestAllTypes message = TestAllTypes.newBuilder()
+ .setOptionalString("a\\bc\\\"ef\"g")
+ .build();
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge(TextFormat.printToUnicodeString(message), builder);
+ assertEquals(message.getOptionalString(), builder.getOptionalString());
+ }
+
+ public void testPrintToUnicodeStringWithNewlines() {
+ // No newlines at start and end
+ assertEquals("optional_string: \"test newlines\n\nin\nstring\"\n",
+ TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+ .setOptionalString("test newlines\n\nin\nstring")
+ .build()));
+
+ // Newlines at start and end
+ assertEquals("optional_string: \"\ntest\nnewlines\n\nin\nstring\n\"\n",
+ TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+ .setOptionalString("\ntest\nnewlines\n\nin\nstring\n")
+ .build()));
+
+ // Strings with 0, 1 and 2 newlines.
+ assertEquals("optional_string: \"\"\n",
+ TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+ .setOptionalString("")
+ .build()));
+ assertEquals("optional_string: \"\n\"\n",
+ TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+ .setOptionalString("\n")
+ .build()));
+ assertEquals("optional_string: \"\n\n\"\n",
+ TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+ .setOptionalString("\n\n")
+ .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()));
+ }
+
+ public void testParseNonRepeatedFields() throws Exception {
+ assertParseSuccessWithOverwriteForbidden(
+ "repeated_int32: 1\n" +
+ "repeated_int32: 2\n");
+ assertParseSuccessWithOverwriteForbidden(
+ "RepeatedGroup { a: 1 }\n" +
+ "RepeatedGroup { a: 2 }\n");
+ assertParseSuccessWithOverwriteForbidden(
+ "repeated_nested_message { bb: 1 }\n" +
+ "repeated_nested_message { bb: 2 }\n");
+ assertParseErrorWithOverwriteForbidden(
+ "3:17: Non-repeated field " +
+ "\"protobuf_unittest.TestAllTypes.optional_int32\" " +
+ "cannot be overwritten.",
+ "optional_int32: 1\n" +
+ "optional_bool: true\n" +
+ "optional_int32: 1\n");
+ assertParseErrorWithOverwriteForbidden(
+ "2:17: Non-repeated field " +
+ "\"protobuf_unittest.TestAllTypes.optionalgroup\" " +
+ "cannot be overwritten.",
+ "OptionalGroup { a: 1 }\n" +
+ "OptionalGroup { }\n");
+ assertParseErrorWithOverwriteForbidden(
+ "2:33: Non-repeated field " +
+ "\"protobuf_unittest.TestAllTypes.optional_nested_message\" " +
+ "cannot be overwritten.",
+ "optional_nested_message { }\n" +
+ "optional_nested_message { bb: 3 }\n");
+ assertParseErrorWithOverwriteForbidden(
+ "2:16: Non-repeated field " +
+ "\"protobuf_unittest.TestAllTypes.default_int32\" " +
+ "cannot be overwritten.",
+ "default_int32: 41\n" + // the default value
+ "default_int32: 41\n");
+ assertParseErrorWithOverwriteForbidden(
+ "2:17: Non-repeated field " +
+ "\"protobuf_unittest.TestAllTypes.default_string\" " +
+ "cannot be overwritten.",
+ "default_string: \"zxcv\"\n" +
+ "default_string: \"asdf\"\n");
+ }
+
+ public void testParseShortRepeatedFormOfRepeatedFields() throws Exception {
+ assertParseSuccessWithOverwriteForbidden("repeated_foreign_enum: [FOREIGN_FOO, FOREIGN_BAR]");
+ assertParseSuccessWithOverwriteForbidden("repeated_int32: [ 1, 2 ]\n");
+ assertParseSuccessWithOverwriteForbidden("RepeatedGroup [{ a: 1 },{ a: 2 }]\n");
+ assertParseSuccessWithOverwriteForbidden("repeated_nested_message [{ bb: 1 }, { bb: 2 }]\n");
+ }
+
+ public void testParseShortRepeatedFormOfNonRepeatedFields() throws Exception {
+ assertParseErrorWithOverwriteForbidden(
+ "1:17: Couldn't parse integer: For input string: \"[\"",
+ "optional_int32: [1]\n");
+ }
+
+ // =======================================================================
+ // test oneof
+
+ public void testOneofTextFormat() throws Exception {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ TestUtil.setOneof(builder);
+ TestOneof2 message = builder.build();
+ TestOneof2.Builder dest = TestOneof2.newBuilder();
+ TextFormat.merge(TextFormat.printToUnicodeString(message), dest);
+ TestUtil.assertOneofSet(dest.build());
+ }
+
+ public void testOneofOverwriteForbidden() throws Exception {
+ String input = "foo_string: \"stringvalue\" foo_int: 123";
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ try {
+ parserWithOverwriteForbidden.merge(
+ input, TestUtil.getExtensionRegistry(), builder);
+ fail("Expected parse exception.");
+ } catch (TextFormat.ParseException e) {
+ assertEquals("1:36: Field \"protobuf_unittest.TestOneof2.foo_int\""
+ + " is specified along with field \"protobuf_unittest.TestOneof2.foo_string\","
+ + " another member of oneof \"foo\".", e.getMessage());
+ }
+ }
+
+ public void testOneofOverwriteAllowed() throws Exception {
+ String input = "foo_string: \"stringvalue\" foo_int: 123";
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ defaultParser.merge(input, TestUtil.getExtensionRegistry(), builder);
+ // Only the last value sticks.
+ TestOneof2 oneof = builder.build();
+ assertFalse(oneof.hasFooString());
+ assertTrue(oneof.hasFooInt());
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java b/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
index ea088b3..93a5ee2 100644
--- a/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
+++ b/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -31,10 +31,13 @@
package com.google.protobuf;
import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.ForeignEnum;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestEmptyMessage;
import protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions;
+import protobuf_unittest.UnittestProto.TestPackedExtensions;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
import junit.framework.TestCase;
@@ -204,6 +207,13 @@ public class UnknownFieldSetTest extends TestCase {
TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).clear().build();
assertEquals(0, message.getSerializedSize());
}
+
+ public void testClearField() throws Exception {
+ int fieldNumber = unknownFields.asMap().keySet().iterator().next();
+ UnknownFieldSet fields =
+ UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clearField(fieldNumber).build();
+ assertFalse(fields.hasField(fieldNumber));
+ }
public void testParseKnownAndUnknown() throws Exception {
// Test mixing known and unknown fields when parsing.
@@ -434,4 +444,210 @@ public class UnknownFieldSetTest extends TestCase {
assertEquals(copy, set);
assertEquals(set.hashCode(), copy.hashCode());
}
+
+ // =================================================================
+
+ public void testSerializeLite() throws Exception {
+ UnittestLite.TestEmptyMessageLite emptyMessageLite =
+ UnittestLite.TestEmptyMessageLite.parseFrom(allFieldsData);
+ assertEquals(allFieldsData.size(), emptyMessageLite.getSerializedSize());
+ ByteString data = emptyMessageLite.toByteString();
+ TestAllTypes message = TestAllTypes.parseFrom(data);
+ TestUtil.assertAllFieldsSet(message);
+ assertEquals(allFieldsData, data);
+ }
+
+ public void testAllExtensionsLite() throws Exception {
+ TestAllExtensions allExtensions = TestUtil.getAllExtensionsSet();
+ ByteString allExtensionsData = allExtensions.toByteString();
+ UnittestLite.TestEmptyMessageLite emptyMessageLite =
+ UnittestLite.TestEmptyMessageLite.PARSER.parseFrom(allExtensionsData);
+ ByteString data = emptyMessageLite.toByteString();
+ TestAllExtensions message =
+ TestAllExtensions.parseFrom(data, TestUtil.getExtensionRegistry());
+ TestUtil.assertAllExtensionsSet(message);
+ assertEquals(allExtensionsData, data);
+ }
+
+ public void testAllPackedFieldsLite() throws Exception {
+ TestPackedTypes allPackedFields = TestUtil.getPackedSet();
+ ByteString allPackedData = allPackedFields.toByteString();
+ UnittestLite.TestEmptyMessageLite emptyMessageLite =
+ UnittestLite.TestEmptyMessageLite.parseFrom(allPackedData);
+ ByteString data = emptyMessageLite.toByteString();
+ TestPackedTypes message =
+ TestPackedTypes.parseFrom(data, TestUtil.getExtensionRegistry());
+ TestUtil.assertPackedFieldsSet(message);
+ assertEquals(allPackedData, data);
+ }
+
+ public void testAllPackedExtensionsLite() throws Exception {
+ TestPackedExtensions allPackedExtensions = TestUtil.getPackedExtensionsSet();
+ ByteString allPackedExtensionsData = allPackedExtensions.toByteString();
+ UnittestLite.TestEmptyMessageLite emptyMessageLite =
+ UnittestLite.TestEmptyMessageLite.parseFrom(allPackedExtensionsData);
+ ByteString data = emptyMessageLite.toByteString();
+ TestPackedExtensions message =
+ TestPackedExtensions.parseFrom(data, TestUtil.getExtensionRegistry());
+ TestUtil.assertPackedExtensionsSet(message);
+ assertEquals(allPackedExtensionsData, data);
+ }
+
+ public void testCopyFromLite() throws Exception {
+ UnittestLite.TestEmptyMessageLite emptyMessageLite =
+ UnittestLite.TestEmptyMessageLite.parseFrom(allFieldsData);
+ UnittestLite.TestEmptyMessageLite emptyMessageLite2 =
+ UnittestLite.TestEmptyMessageLite.newBuilder()
+ .mergeFrom(emptyMessageLite).build();
+ assertEquals(emptyMessageLite.toByteString(), emptyMessageLite2.toByteString());
+ }
+
+ public void testMergeFromLite() throws Exception {
+ TestAllTypes message1 = TestAllTypes.newBuilder()
+ .setOptionalInt32(1)
+ .setOptionalString("foo")
+ .addRepeatedString("bar")
+ .setOptionalNestedEnum(TestAllTypes.NestedEnum.BAZ)
+ .build();
+
+ TestAllTypes message2 = TestAllTypes.newBuilder()
+ .setOptionalInt64(2)
+ .setOptionalString("baz")
+ .addRepeatedString("qux")
+ .setOptionalForeignEnum(ForeignEnum.FOREIGN_BAZ)
+ .build();
+
+ ByteString data1 = message1.toByteString();
+ UnittestLite.TestEmptyMessageLite emptyMessageLite1 =
+ UnittestLite.TestEmptyMessageLite.parseFrom(data1);
+ ByteString data2 = message2.toByteString();
+ UnittestLite.TestEmptyMessageLite emptyMessageLite2 =
+ UnittestLite.TestEmptyMessageLite.parseFrom(data2);
+
+ message1 = TestAllTypes.newBuilder(message1).mergeFrom(message2).build();
+ emptyMessageLite1 = UnittestLite.TestEmptyMessageLite.newBuilder(emptyMessageLite1)
+ .mergeFrom(emptyMessageLite2).build();
+
+ data1 = emptyMessageLite1.toByteString();
+ message2 = TestAllTypes.parseFrom(data1);
+
+ assertEquals(message1, message2);
+ }
+
+ public void testWrongTypeTreatedAsUnknownLite() 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);
+ UnittestLite.TestEmptyMessageLite emptyMessageLite =
+ UnittestLite.TestEmptyMessageLite.parseFrom(bizarroData);
+ ByteString data = emptyMessageLite.toByteString();
+ TestAllTypes allTypesMessage2 = TestAllTypes.parseFrom(data);
+
+ assertEquals(allTypesMessage.toString(), allTypesMessage2.toString());
+ }
+
+ public void testUnknownExtensionsLite() throws Exception {
+ // Make sure fields are properly parsed to the UnknownFieldSet even when
+ // they are declared as extension numbers.
+
+ UnittestLite.TestEmptyMessageWithExtensionsLite message =
+ UnittestLite.TestEmptyMessageWithExtensionsLite.parseFrom(allFieldsData);
+
+ assertEquals(allFieldsData, message.toByteString());
+ }
+
+ public void testWrongExtensionTypeTreatedAsUnknownLite() 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);
+ UnittestLite.TestEmptyMessageLite emptyMessageLite =
+ UnittestLite.TestEmptyMessageLite.parseFrom(bizarroData);
+
+ // All fields should have been interpreted as unknown, so the byte strings
+ // should be the same.
+ assertEquals(emptyMessageLite.toByteString(),
+ allExtensionsMessage.toByteString());
+ }
+
+ public void testParseUnknownEnumValueLite() 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();
+
+ UnittestLite.TestEmptyMessageLite emptyMessageLite =
+ UnittestLite.TestEmptyMessageLite.parseFrom(data);
+ data = emptyMessageLite.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 testClearLite() throws Exception {
+ UnittestLite.TestEmptyMessageLite emptyMessageLite1 =
+ UnittestLite.TestEmptyMessageLite.parseFrom(allFieldsData);
+ UnittestLite.TestEmptyMessageLite emptyMessageLite2 =
+ UnittestLite.TestEmptyMessageLite.newBuilder()
+ .mergeFrom(emptyMessageLite1).clear().build();
+ assertEquals(0, emptyMessageLite2.getSerializedSize());
+ ByteString data = emptyMessageLite2.toByteString();
+ assertEquals(0, data.size());
+ }
+
}
diff --git a/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java b/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java
new file mode 100644
index 0000000..b1c75fc
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java
@@ -0,0 +1,227 @@
+// 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.util.Iterator;
+import java.util.List;
+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));
+
+ List<ByteString> byteStringList = list.asByteStringList();
+ assertSame(list.getByteString(0), byteStringList.get(0));
+ assertSame(list.getByteString(1), byteStringList.get(1));
+ assertSame(list.getByteString(2), byteStringList.get(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
+ }
+ assertEquals(3, list.size());
+
+ List<ByteString> byteStringList = list.asByteStringList();
+ try {
+ byteStringList.remove(0);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ assertEquals(3, list.size());
+ assertEquals(3, byteStringList.size());
+
+ try {
+ byteStringList.add(BYTE_STRING_B);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ assertEquals(3, list.size());
+ assertEquals(3, byteStringList.size());
+
+ try {
+ byteStringList.set(1, BYTE_STRING_B);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ assertEquals(3, list.size());
+ assertEquals(3, byteStringList.size());
+ }
+
+ 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);
+
+ List<ByteString> byteStringList = list.asByteStringList();
+ Iterator<ByteString> byteIter = byteStringList.iterator();
+ count = 0;
+ while (byteIter.hasNext()) {
+ byteIter.next();
+ count++;
+ try {
+ byteIter.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);
+
+ List<ByteString> byteStringList = list.asByteStringList();
+ ListIterator<ByteString> byteIter = byteStringList.listIterator();
+ count = 0;
+ while (byteIter.hasNext()) {
+ byteIter.next();
+ count++;
+ try {
+ byteIter.remove();
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ try {
+ byteIter.set(BYTE_STRING_A);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ try {
+ byteIter.add(BYTE_STRING_A);
+ 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/src/test/java/com/google/protobuf/WireFormatTest.java b/java/src/test/java/com/google/protobuf/WireFormatTest.java
index 5ea1dd6..6858524 100644
--- a/java/src/test/java/com/google/protobuf/WireFormatTest.java
+++ b/java/src/test/java/com/google/protobuf/WireFormatTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -34,11 +34,14 @@ 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.TestOneof2;
+import protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible;
import protobuf_unittest.UnittestProto.TestPackedExtensions;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestMset.TestMessageSet;
@@ -217,8 +220,8 @@ public class WireFormatTest extends TestCase {
}
public void testExtensionsSerializedSize() throws Exception {
- assertEquals(TestUtil.getAllSet().getSerializedSize(),
- TestUtil.getAllExtensionsSet().getSerializedSize());
+ assertNotSame(TestUtil.getAllSet().getSerializedSize(),
+ TestUtil.getAllExtensionsSet().getSerializedSize());
}
public void testSerializeDelimited() throws Exception {
@@ -328,7 +331,17 @@ public class WireFormatTest extends TestCase {
private static final int TYPE_ID_2 =
TestMessageSetExtension2.getDescriptor().getExtensions().get(0).getNumber();
- public void testSerializeMessageSet() throws Exception {
+ 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()
@@ -372,7 +385,17 @@ public class WireFormatTest extends TestCase {
assertEquals("bar", raw.getItem(2).getMessage().toStringUtf8());
}
- public void testParseMessageSet() throws Exception {
+ 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);
@@ -424,4 +447,160 @@ public class WireFormatTest extends TestCase {
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());
+ }
+
+ public void testMergeMessageSetExtensionEagerly() throws Exception {
+ testMergeMessageSetExtensionWithFlag(true);
+ }
+
+ public void testMergeMessageSetExtensionNotEagerly() throws Exception {
+ testMergeMessageSetExtensionWithFlag(false);
+ }
+
+ private void testMergeMessageSetExtensionWithFlag(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();
+
+ // Serialize RawMessageSet unnormally (message value before type id)
+ ByteString.CodedBuilder out = ByteString.newCodedBuilder(
+ raw.getSerializedSize());
+ CodedOutputStream output = out.getCodedOutput();
+ List<RawMessageSet.Item> items = raw.getItemList();
+ for (int i = 0; i < items.size(); i++) {
+ RawMessageSet.Item item = items.get(i);
+ output.writeTag(1, WireFormat.WIRETYPE_START_GROUP);
+ output.writeBytes(3, item.getMessage());
+ output.writeInt32(2, item.getTypeId());
+ output.writeTag(1, WireFormat.WIRETYPE_END_GROUP);
+ }
+ ByteString data = out.build();
+
+ // Merge bytes into TestMessageSet and check the contents.
+ TestMessageSet messageSet =
+ TestMessageSet.newBuilder().mergeFrom(data, extensionRegistry).build();
+ assertEquals(123, messageSet.getExtension(
+ TestMessageSetExtension1.messageSetExtension).getI());
+ }
+
+ // ================================================================
+ // oneof
+ public void testOneofWireFormat() throws Exception {
+ TestOneof2.Builder builder = TestOneof2.newBuilder();
+ TestUtil.setOneof(builder);
+ TestOneof2 message = builder.build();
+ ByteString rawBytes = message.toByteString();
+
+ assertEquals(rawBytes.size(), message.getSerializedSize());
+
+ TestOneof2 message2 = TestOneof2.parseFrom(rawBytes);
+ TestUtil.assertOneofSet(message2);
+ }
+
+ public void testOneofOnlyLastSet() throws Exception {
+ TestOneofBackwardsCompatible source = TestOneofBackwardsCompatible
+ .newBuilder().setFooInt(100).setFooString("101").build();
+
+ ByteString rawBytes = source.toByteString();
+ TestOneof2 message = TestOneof2.parseFrom(rawBytes);
+ assertFalse(message.hasFooInt());
+ assertTrue(message.hasFooString());
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/lazy_fields_lite.proto b/java/src/test/java/com/google/protobuf/lazy_fields_lite.proto
new file mode 100644
index 0000000..baed4e1
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/lazy_fields_lite.proto
@@ -0,0 +1,61 @@
+// 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: Naoki Iwasaki (niwasaki@google.com)
+//
+// A proto file with lazy fields
+
+
+package protobuf_unittest;
+
+option optimize_for = LITE_RUNTIME;
+
+message LazyMessageLite {
+ optional int32 num = 1;
+ optional int32 num_with_default = 2 [default = 421];
+ optional LazyInnerMessageLite inner = 3 [lazy = true];
+ repeated LazyInnerMessageLite repeated_inner = 4 [lazy = true];
+
+ oneof oneof_field {
+ int32 oneof_num = 5;
+ LazyInnerMessageLite oneof_inner = 6 [lazy = true];
+ }
+}
+
+message LazyInnerMessageLite {
+ optional int32 num = 1;
+ optional int32 num_with_default = 2 [default = 42];
+ optional LazyNestedInnerMessageLite nested = 3 [lazy = true];
+}
+
+message LazyNestedInnerMessageLite {
+ optional int32 num = 1;
+ optional int32 num_with_default = 2 [default = 4];
+}
diff --git a/java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto b/java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto
new file mode 100644
index 0000000..6861567
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto
@@ -0,0 +1,55 @@
+// 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: pbogle@google.com (Phil Bogle)
+
+
+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 Foo {
+ optional int32 value = 1;
+ repeated Bar bar = 2;
+}
+
+message Bar {
+ optional string name = 1;
+}
+
+message BarPrime {
+ optional string name = 1;
+}
+
+message Empty {
+}
diff --git a/java/src/test/java/com/google/protobuf/multiple_files_test.proto b/java/src/test/java/com/google/protobuf/multiple_files_test.proto
index 060f159..7ec89a0 100644
--- a/java/src/test/java/com/google/protobuf/multiple_files_test.proto
+++ b/java/src/test/java/com/google/protobuf/multiple_files_test.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,13 +33,19 @@
// 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";
+import "google/protobuf/descriptor.proto";
package protobuf_unittest;
option java_multiple_files = true;
option java_outer_classname = "MultipleFilesTestProto";
+
message MessageWithNoOuter {
message NestedMessage {
optional int32 i = 1;
@@ -53,8 +59,12 @@ message MessageWithNoOuter {
optional EnumWithNoOuter foreign_enum = 4;
}
+extend google.protobuf.EnumValueOptions {
+ optional int32 enum_value_option = 7654321;
+}
+
enum EnumWithNoOuter {
- FOO = 1;
+ FOO = 1 [(enum_value_option) = 12345];
BAR = 2;
}
diff --git a/java/src/test/java/com/google/protobuf/nested_builders_test.proto b/java/src/test/java/com/google/protobuf/nested_builders_test.proto
new file mode 100644
index 0000000..8ab4a43
--- /dev/null
+++ b/java/src/test/java/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.
+// 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: 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/src/test/java/com/google/protobuf/nested_extension.proto b/java/src/test/java/com/google/protobuf/nested_extension.proto
new file mode 100644
index 0000000..8649286
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/nested_extension.proto
@@ -0,0 +1,46 @@
+// 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: 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/src/test/java/com/google/protobuf/nested_extension_lite.proto b/java/src/test/java/com/google/protobuf/nested_extension_lite.proto
new file mode 100644
index 0000000..9c68682
--- /dev/null
+++ b/java/src/test/java/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.
+// 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: 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/src/test/java/com/google/protobuf/non_nested_extension.proto b/java/src/test/java/com/google/protobuf/non_nested_extension.proto
new file mode 100644
index 0000000..cb2f8b0
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/non_nested_extension.proto
@@ -0,0 +1,49 @@
+// 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: 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/src/test/java/com/google/protobuf/non_nested_extension_lite.proto b/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto
new file mode 100644
index 0000000..c1f744b
--- /dev/null
+++ b/java/src/test/java/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.
+// 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: 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/src/test/java/com/google/protobuf/outer_class_name_test.proto b/java/src/test/java/com/google/protobuf/outer_class_name_test.proto
new file mode 100644
index 0000000..c5114f8
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/outer_class_name_test.proto
@@ -0,0 +1,38 @@
+// 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 protobuf_unittest;
+
+
+// This message's name is the same with the default outer class name of this
+// proto file. It's used to test if the compiler can avoid this conflict
+// correctly.
+message OuterClassNameTest {
+}
diff --git a/java/src/test/java/com/google/protobuf/outer_class_name_test2.proto b/java/src/test/java/com/google/protobuf/outer_class_name_test2.proto
new file mode 100644
index 0000000..741cd28
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/outer_class_name_test2.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.
+
+package protobuf_unittest;
+
+
+message TestMessage2 {
+ message NestedMessage {
+ // This message's name is the same with the default outer class name of this
+ // proto file. It's used to test if the compiler can avoid this conflict
+ // correctly.
+ message OuterClassNameTest2 {
+ }
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/outer_class_name_test3.proto b/java/src/test/java/com/google/protobuf/outer_class_name_test3.proto
new file mode 100644
index 0000000..5d5d4ac
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/outer_class_name_test3.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.
+
+package protobuf_unittest;
+
+
+message TestMessage3 {
+ message NestedMessage {
+ // This enum's name is the same with the default outer class name of this
+ // proto file. It's used to test if the compiler can avoid this conflict
+ // correctly.
+ enum OuterClassNameTest3 {
+ DUMMY_VALUE = 1;
+ }
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto b/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto
new file mode 100644
index 0000000..202e8c9
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto
@@ -0,0 +1,157 @@
+// 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: 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";
+option java_generate_equals_and_hash = true;
+
+message TestMessage {
+ optional string cached_size = 1;
+ optional string serialized_size = 2;
+ optional string class = 3;
+}
+
+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;
+ enum NestedEnum {
+ FOO = 1;
+ }
+}
+
+message Parser {
+ enum ParserEnum {
+ PARSER = 1;
+ }
+ optional ParserEnum parser = 1;
+}
+
+message Deprecated {
+ enum TestEnum {
+ FOO = 1;
+
+ // Test if @Deprecated annotation conflicts with Deprecated message name.
+ BAR = 2 [ deprecated = true ];
+ }
+
+ 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);
+}
+
+message TestConflictingFieldNames {
+ enum TestEnum {
+ FOO = 1;
+ }
+ message TestMessage {
+ }
+ repeated int32 int32_field = 1;
+ repeated TestEnum enum_field = 2;
+ repeated string string_field = 3;
+ repeated bytes bytes_field = 4;
+ repeated TestMessage message_field = 5;
+
+ optional int32 int32_field_count = 11;
+ optional TestEnum enum_field_count = 12;
+ optional string string_field_count = 13;
+ optional bytes bytes_field_count = 14;
+ optional TestMessage message_field_count = 15;
+
+ repeated int32 Int32Field = 21;
+ repeated TestEnum EnumField = 22;
+ repeated string StringField = 23;
+ repeated bytes BytesField = 24;
+ repeated TestMessage MessageField = 25;
+
+ // This field conflicts with "int32_field" as they both generate
+ // the method getInt32FieldList().
+ required int32 int32_field_list = 31;
+
+ extensions 1000 to max;
+
+ repeated int64 int64_field = 41;
+ extend TestConflictingFieldNames {
+ // We don't generate accessors for extensions so the following extension
+ // fields don't conflict with the repeated field "int64_field".
+ optional int64 int64_field_count = 1001;
+ optional int64 int64_field_list = 1002;
+ }
+}
+
diff --git a/java/src/test/java/com/google/protobuf/test_check_utf8.proto b/java/src/test/java/com/google/protobuf/test_check_utf8.proto
new file mode 100644
index 0000000..206946d
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/test_check_utf8.proto
@@ -0,0 +1,50 @@
+// 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: Jacob Butcher (jbaum@google.com)
+//
+// Test file option java_string_check_utf8.
+
+package proto2_test_check_utf8;
+
+option java_outer_classname = "TestCheckUtf8";
+option java_string_check_utf8 = true;
+
+message StringWrapper {
+ required string req = 1;
+ optional string opt = 2;
+ repeated string rep = 3;
+}
+
+message BytesWrapper {
+ required bytes req = 1;
+ optional bytes opt = 2;
+ repeated bytes rep = 3;
+}
diff --git a/java/src/test/java/com/google/protobuf/test_check_utf8_size.proto b/java/src/test/java/com/google/protobuf/test_check_utf8_size.proto
new file mode 100644
index 0000000..fa057a8
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/test_check_utf8_size.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: Jacob Butcher (jbaum@google.com)
+//
+// Test file option java_string_check_utf8.
+
+package proto2_test_check_utf8_size;
+
+option java_outer_classname = "TestCheckUtf8Size";
+option java_string_check_utf8 = true;
+option optimize_for = CODE_SIZE;
+
+message StringWrapperSize {
+ required string req = 1;
+ optional string opt = 2;
+ repeated string rep = 3;
+}
+
+message BytesWrapperSize {
+ required bytes req = 1;
+ optional bytes opt = 2;
+ repeated bytes rep = 3;
+}
diff --git a/java/src/test/java/com/google/protobuf/test_custom_options.proto b/java/src/test/java/com/google/protobuf/test_custom_options.proto
new file mode 100644
index 0000000..f6a5ecd
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/test_custom_options.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.
+
+// Author: Feng Xiao (xiaofeng@google.com)
+//
+// Test that custom options defined in a proto file's dependencies are properly
+// initialized.
+
+package protobuf_unittest;
+
+
+import "google/protobuf/unittest_custom_options.proto";
+
+message TestMessageWithCustomOptionsContainer {
+ optional TestMessageWithCustomOptions field = 1;
+}
diff --git a/java/src/test/java/com/google/protobuf/test_extra_interfaces.proto b/java/src/test/java/com/google/protobuf/test_extra_interfaces.proto
new file mode 100644
index 0000000..72e05a3
--- /dev/null
+++ b/java/src/test/java/com/google/protobuf/test_extra_interfaces.proto
@@ -0,0 +1,60 @@
+// 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: Darick Tong (darick@google.com)
+
+package protobuf_unittest;
+
+message Proto1 {
+ option experimental_java_message_interface =
+ "com.google.protobuf.ExtraInterfaces.HasBoolValue";
+
+ option experimental_java_interface_extends =
+ "com.google.protobuf.ExtraInterfaces.HasByteValue";
+
+ option experimental_java_message_interface =
+ "com.google.protobuf.ExtraInterfaces.HasStringValue<Proto1>";
+
+ option experimental_java_builder_interface =
+ "com.google.protobuf.ExtraInterfaces.HasStringValueBuilder"
+ "<Proto1, Builder>";
+
+ optional string string_value = 1;
+ optional bool bool_value = 2;
+ optional bytes byte_value = 3;
+ optional int32 int_value = 4;
+}
+
+message Proto2 {
+ option experimental_java_message_interface =
+ "com.google.protobuf.ExtraInterfaces.HasBoolValue";
+
+ optional bool bool_value = 1;
+}
diff --git a/ltmain.sh b/ltmain.sh
index 174e492..a356aca 100755..100644
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -1,9 +1,9 @@
-# Generated from ltmain.m4sh.
-# ltmain.sh (GNU libtool) 2.2.4
+# libtool (GNU libtool) 2.4.2
# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
# This is free software; see the source for copying conditions. There is NO
# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -32,50 +32,57 @@
#
# Provide generalized library-building support services.
#
-# --config show all configuration variables
-# --debug enable verbose shell tracing
-# -n, --dry-run display commands without modifying any files
-# --features display basic configuration information and exit
-# --mode=MODE use operation mode MODE
-# --preserve-dup-deps don't remove duplicate dependency libraries
-# --quiet, --silent don't print informational messages
-# --tag=TAG use configuration variables from tag TAG
-# -v, --verbose print informational messages (default)
-# --version print version information
-# -h, --help print short or long help message
+# --config show all configuration variables
+# --debug enable verbose shell tracing
+# -n, --dry-run display commands without modifying any files
+# --features display basic configuration information and exit
+# --mode=MODE use operation mode MODE
+# --preserve-dup-deps don't remove duplicate dependency libraries
+# --quiet, --silent don't print informational messages
+# --no-quiet, --no-silent
+# print informational messages (default)
+# --no-warn don't display warning messages
+# --tag=TAG use configuration variables from tag TAG
+# -v, --verbose print more informational messages than default
+# --no-verbose don't print the extra informational messages
+# --version print version information
+# -h, --help, --help-all print short, long, or detailed help message
#
# MODE must be one of the following:
#
-# clean remove files from the build directory
-# compile compile a source file into a libtool object
-# execute automatically set library path, then run a program
-# finish complete the installation of libtool libraries
-# install install libraries or executables
-# link create a library or an executable
-# uninstall remove libraries from an installed directory
+# clean remove files from the build directory
+# compile compile a source file into a libtool object
+# execute automatically set library path, then run a program
+# finish complete the installation of libtool libraries
+# install install libraries or executables
+# link create a library or an executable
+# uninstall remove libraries from an installed directory
#
-# MODE-ARGS vary depending on the MODE.
+# MODE-ARGS vary depending on the MODE. When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
#
# When reporting a bug, please describe a test case to reproduce it and
# include the following information:
#
-# host-triplet: $host
-# shell: $SHELL
-# compiler: $LTCC
-# compiler flags: $LTCFLAGS
-# linker: $LD (gnu? $with_gnu_ld)
-# $progname: (GNU libtool) 2.2.4
-# automake: $automake_version
-# autoconf: $autoconf_version
+# host-triplet: $host
+# shell: $SHELL
+# compiler: $LTCC
+# compiler flags: $LTCFLAGS
+# linker: $LD (gnu? $with_gnu_ld)
+# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.7ubuntu1
+# automake: $automake_version
+# autoconf: $autoconf_version
#
# Report bugs to <bug-libtool@gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
-PROGRAM=ltmain.sh
+PROGRAM=libtool
PACKAGE=libtool
-VERSION=2.2.4
+VERSION="2.4.2 Debian-2.4.2-1.7ubuntu1"
TIMESTAMP=""
-package_revision=1.2976
+package_revision=1.3337
# Be Bourne compatible
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
@@ -91,10 +98,15 @@ fi
BIN_SH=xpg4; export BIN_SH # for Tru64
DUALCASE=1; export DUALCASE # for MKS sh
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
# NLS nuisances: We save the old values to restore during execute mode.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
lt_user_locale=
lt_safe_locale=
for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
@@ -107,24 +119,28 @@ do
lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
fi"
done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
$lt_unset CDPATH
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
: ${CP="cp -f"}
-: ${ECHO="echo"}
-: ${EGREP="/usr/bin/grep -E"}
-: ${FGREP="/usr/bin/grep -F"}
-: ${GREP="/usr/bin/grep"}
-: ${LN_S="ln -s"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
: ${MAKE="make"}
: ${MKDIR="mkdir"}
: ${MV="mv -f"}
: ${RM="rm -f"}
-: ${SED="/opt/local/bin/gsed"}
: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
: ${Xsed="$SED -e 1s/^X//"}
@@ -144,6 +160,27 @@ IFS=" $lt_nl"
dirname="s,/[^/]*$,,"
basename="s,^.*/,,"
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
# func_dirname_and_basename file append nondir_replacement
# perform func_basename and func_dirname in a single function
# call:
@@ -158,33 +195,183 @@ basename="s,^.*/,,"
# those functions but instead duplicate the functionality here.
func_dirname_and_basename ()
{
- # Extract subdirectory from the argument.
- func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
- if test "X$func_dirname_result" = "X${1}"; then
- func_dirname_result="${3}"
- else
- func_dirname_result="$func_dirname_result${2}"
- fi
- func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+ func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+ s@/\./@/@g
+ t dotsl
+ s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+# value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test "$func_normal_abspath_tpath" = / ; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result" ; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
}
-# Generated shell functions inserted here.
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+# value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=${func_dirname_result}
+ if test "x$func_relative_path_tlibdir" = x ; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
-# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
-# is ksh but when the shell is invoked as "sh" and the current value of
-# the _XPG environment variable is not equal to 1 (one), the special
-# positional parameter $0, within a function call, is the name of the
-# function.
-progpath="$0"
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test "x$func_stripname_result" != x ; then
+ func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+ fi
+
+ # Normalisation. If bindir is libdir, return empty string,
+ # else relative path ending with a slash; either way, target
+ # file name can be directly appended.
+ if test ! -z "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result/"
+ func_relative_path_result=$func_stripname_result
+ fi
+}
# The name of this program:
-# In the unlikely event $progname began with a '-', it would play havoc with
-# func_echo (imagine progname=-n), so we prepend ./ in that case:
func_dirname_and_basename "$progpath"
progname=$func_basename_result
-case $progname in
- -*) progname=./$progname ;;
-esac
# Make sure we have an absolute path for reexecution:
case $progpath in
@@ -196,7 +383,7 @@ case $progpath in
;;
*)
save_IFS="$IFS"
- IFS=:
+ IFS=${PATH_SEPARATOR-:}
for progdir in $PATH; do
IFS="$save_IFS"
test -x "$progdir/$progname" && break
@@ -215,6 +402,15 @@ sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
# Same as above, but do not quote variable references.
double_quote_subst='s/\(["`\\]\)/\\\1/g'
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
# Re-`\' parameter expansions in output of double_quote_subst that were
# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
# in input to double_quote_subst, that '$' was protected from expansion.
@@ -243,7 +439,7 @@ opt_warning=:
# name if it has been set yet.
func_echo ()
{
- $ECHO "$progname${mode+: }$mode: $*"
+ $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
}
# func_verbose arg...
@@ -258,18 +454,25 @@ func_verbose ()
:
}
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
# func_error arg...
# Echo program name prefixed message to standard error.
func_error ()
{
- $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2
+ $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
}
# func_warning arg...
# Echo program name prefixed warning message to standard error.
func_warning ()
{
- $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
+ $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
# bash bug again:
:
@@ -326,9 +529,9 @@ func_mkdir_p ()
case $my_directory_path in */*) ;; *) break ;; esac
# ...otherwise throw away the child directory and loop
- my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"`
+ my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
done
- my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'`
+ my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
save_mkdir_p_IFS="$IFS"; IFS=':'
for my_dir in $my_dir_list; do
@@ -378,7 +581,7 @@ func_mktempdir ()
func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
fi
- $ECHO "X$my_tmpdir" | $Xsed
+ $ECHO "$my_tmpdir"
}
@@ -392,7 +595,7 @@ func_quote_for_eval ()
{
case $1 in
*[\\\`\"\$]*)
- func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;;
+ func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
*)
func_quote_for_eval_unquoted_result="$1" ;;
esac
@@ -419,7 +622,7 @@ func_quote_for_expand ()
{
case $1 in
*[\\\`\"]*)
- my_arg=`$ECHO "X$1" | $Xsed \
+ my_arg=`$ECHO "$1" | $SED \
-e "$double_quote_subst" -e "$sed_double_backslash"` ;;
*)
my_arg="$1" ;;
@@ -488,15 +691,39 @@ func_show_eval_locale ()
fi
}
-
-
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
# func_version
# Echo version message to standard output and exit.
func_version ()
{
- $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / {
+ $opt_debug
+
+ $SED -n '/(C)/!b go
+ :more
+ /\./!{
+ N
+ s/\n# / /
+ b more
+ }
+ :go
+ /^# '$PROGRAM' (GNU /,/# warranty; / {
s/^# //
s/^# *$//
s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
@@ -509,22 +736,28 @@ func_version ()
# Echo short help message to standard output and exit.
func_usage ()
{
- $SED -n '/^# Usage:/,/# -h/ {
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/^# *.*--help/ {
s/^# //
s/^# *$//
s/\$progname/'$progname'/
p
}' < "$progpath"
- $ECHO
+ echo
$ECHO "run \`$progname --help | more' for full usage"
exit $?
}
-# func_help
-# Echo long help message to standard output and exit.
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
func_help ()
{
+ $opt_debug
+
$SED -n '/^# Usage:/,/# Report bugs to/ {
+ :print
s/^# //
s/^# *$//
s*\$progname*'$progname'*
@@ -534,11 +767,18 @@ func_help ()
s*\$LTCFLAGS*'"$LTCFLAGS"'*
s*\$LD*'"$LD"'*
s/\$with_gnu_ld/'"$with_gnu_ld"'/
- s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
- s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
+ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
p
- }' < "$progpath"
- exit $?
+ d
+ }
+ /^# .* home page:/b print
+ /^# General help using/b print
+ ' < "$progpath"
+ ret=$?
+ if test -z "$1"; then
+ exit $ret
+ fi
}
# func_missing_arg argname
@@ -546,63 +786,106 @@ func_help ()
# exit_cmd.
func_missing_arg ()
{
- func_error "missing argument for $1"
+ $opt_debug
+
+ func_error "missing argument for $1."
exit_cmd=exit
}
-exit_cmd=:
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+ my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+ my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+ func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+ func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+ my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+ my_sed_long_arg='1s/^--[^=]*=//'
+
+ func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+ func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
-# Check that we have a working $ECHO.
-if test "X$1" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
-elif test "X$1" = X--fallback-echo; then
- # Avoid inline document here, it may be left over
- :
-elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then
- # Yippee, $ECHO works!
- :
-else
- # Restart under the correct shell, and then maybe $ECHO will work.
- exec $SHELL "$progpath" --no-reexec ${1+"$@"}
-fi
-if test "X$1" = X--fallback-echo; then
- # used as fallback echo
- shift
- cat <<EOF
-$*
-EOF
- exit $EXIT_SUCCESS
-fi
magic="%%%MAGIC variable%%%"
magic_exe="%%%MAGIC EXE variable%%%"
# Global variables.
-# $mode is unset
nonopt=
-execute_dlfiles=
preserve_args=
lo2o="s/\\.lo\$/.${objext}/"
o2lo="s/\\.${objext}\$/.lo/"
extracted_archives=
extracted_serial=0
-opt_dry_run=false
-opt_duplicate_deps=false
-opt_silent=false
-opt_debug=:
-
# If this variable is set in any of the actions, the command in it
# will be execed at the end. This prevents here-documents from being
# left over by shells.
exec_cmd=
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+ func_quote_for_eval "${2}"
+ eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
# func_fatal_configuration arg...
# Echo program name prefixed message to standard error, followed by
# a configuration failure hint, and exit.
@@ -636,16 +919,16 @@ func_config ()
# Display the features supported by this script.
func_features ()
{
- $ECHO "host: $host"
+ echo "host: $host"
if test "$build_libtool_libs" = yes; then
- $ECHO "enable shared libraries"
+ echo "enable shared libraries"
else
- $ECHO "disable shared libraries"
+ echo "disable shared libraries"
fi
if test "$build_old_libs" = yes; then
- $ECHO "enable static libraries"
+ echo "enable static libraries"
else
- $ECHO "disable static libraries"
+ echo "disable static libraries"
fi
exit $?
@@ -692,133 +975,6 @@ func_enable_tag ()
esac
}
-# Parse options once, thoroughly. This comes as soon as possible in
-# the script to make things like `libtool --version' happen quickly.
-{
-
- # Shorthand for --mode=foo, only valid as the first argument
- case $1 in
- clean|clea|cle|cl)
- shift; set dummy --mode clean ${1+"$@"}; shift
- ;;
- compile|compil|compi|comp|com|co|c)
- shift; set dummy --mode compile ${1+"$@"}; shift
- ;;
- execute|execut|execu|exec|exe|ex|e)
- shift; set dummy --mode execute ${1+"$@"}; shift
- ;;
- finish|finis|fini|fin|fi|f)
- shift; set dummy --mode finish ${1+"$@"}; shift
- ;;
- install|instal|insta|inst|ins|in|i)
- shift; set dummy --mode install ${1+"$@"}; shift
- ;;
- link|lin|li|l)
- shift; set dummy --mode link ${1+"$@"}; shift
- ;;
- uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
- shift; set dummy --mode uninstall ${1+"$@"}; shift
- ;;
- esac
-
- # Parse non-mode specific arguments:
- while test "$#" -gt 0; do
- opt="$1"
- shift
-
- case $opt in
- --config) func_config ;;
-
- --debug) preserve_args="$preserve_args $opt"
- func_echo "enabling shell trace mode"
- opt_debug='set -x'
- $opt_debug
- ;;
-
- -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break
- execute_dlfiles="$execute_dlfiles $1"
- shift
- ;;
-
- --dry-run | -n) opt_dry_run=: ;;
- --features) func_features ;;
- --finish) mode="finish" ;;
-
- --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break
- case $1 in
- # Valid mode arguments:
- clean) ;;
- compile) ;;
- execute) ;;
- finish) ;;
- install) ;;
- link) ;;
- relink) ;;
- uninstall) ;;
-
- # Catch anything else as an error
- *) func_error "invalid argument for $opt"
- exit_cmd=exit
- break
- ;;
- esac
-
- mode="$1"
- shift
- ;;
-
- --preserve-dup-deps)
- opt_duplicate_deps=: ;;
-
- --quiet|--silent) preserve_args="$preserve_args $opt"
- opt_silent=:
- ;;
-
- --verbose| -v) preserve_args="$preserve_args $opt"
- opt_silent=false
- ;;
-
- --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break
- preserve_args="$preserve_args $opt $1"
- func_enable_tag "$1" # tagname is set here
- shift
- ;;
-
- # Separate optargs to long options:
- -dlopen=*|--mode=*|--tag=*)
- func_opt_split "$opt"
- set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"}
- shift
- ;;
-
- -\?|-h) func_usage ;;
- --help) opt_help=: ;;
- --version) func_version ;;
-
- -*) func_fatal_help "unrecognized option \`$opt'" ;;
-
- *) nonopt="$opt"
- break
- ;;
- esac
- done
-
-
- case $host in
- *cygwin* | *mingw* | *pw32*)
- # don't eliminate duplications in $postdeps and $predeps
- opt_duplicate_compiler_generated_deps=:
- ;;
- *)
- opt_duplicate_compiler_generated_deps=$opt_duplicate_deps
- ;;
- esac
-
- # Having warned about all mis-specified options, bail out if
- # anything was wrong.
- $exit_cmd $EXIT_FAILURE
-}
-
# func_check_version_match
# Ensure that we are using m4 macros, and libtool script from the same
# release of libtool.
@@ -855,46 +1011,228 @@ _LT_EOF
}
-## ----------- ##
-## Main. ##
-## ----------- ##
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+esac
-$opt_help || {
- # Sanity checks first:
- func_check_version_match
- if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
- func_fatal_configuration "not configured to build any kind of library"
- fi
- test -z "$mode" && func_fatal_error "error: you must specify a MODE."
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
- # Darwin sucks
- eval std_shrext=\"$shrext_cmds\"
+# Parse options once, thoroughly. This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+ # this just eases exit handling
+ while test $# -gt 0; do
+ opt="$1"
+ shift
+ case $opt in
+ --debug|-x) opt_debug='set -x'
+ func_echo "enabling shell trace mode"
+ $opt_debug
+ ;;
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+ --config)
+ opt_config=:
+func_config
+ ;;
+ --dlopen|-dlopen)
+ optarg="$1"
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+ shift
+ ;;
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=:
+ ;;
+ --features)
+ opt_features=:
+func_features
+ ;;
+ --finish)
+ opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ --help)
+ opt_help=:
+ ;;
+ --help-all)
+ opt_help_all=:
+opt_help=': help-all'
+ ;;
+ --mode)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_mode="$optarg"
+case $optarg in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $opt"
+ exit_cmd=exit
+ break
+ ;;
+esac
+ shift
+ ;;
+ --no-silent|--no-quiet)
+ opt_silent=false
+func_append preserve_args " $opt"
+ ;;
+ --no-warning|--no-warn)
+ opt_warning=false
+func_append preserve_args " $opt"
+ ;;
+ --no-verbose)
+ opt_verbose=false
+func_append preserve_args " $opt"
+ ;;
+ --silent|--quiet)
+ opt_silent=:
+func_append preserve_args " $opt"
+ opt_verbose=false
+ ;;
+ --verbose|-v)
+ opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+ ;;
+ --tag)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+ shift
+ ;;
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+ --version) func_version ;;
- # Only execute mode is allowed to have -dlopen flags.
- if test -n "$execute_dlfiles" && test "$mode" != execute; then
- func_error "unrecognized option \`-dlopen'"
- $ECHO "$help" 1>&2
- exit $EXIT_FAILURE
+ # Separate optargs to long options:
+ --*=*)
+ func_split_long_opt "$opt"
+ set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-n*|-v*)
+ func_split_short_opt "$opt"
+ set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognized option \`$opt'" ;;
+ *) set dummy "$opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+ # Validate options:
+
+ # save first non-option argument
+ if test "$#" -gt 0; then
+ nonopt="$opt"
+ shift
fi
- # Change the help message to a mode-specific one.
- generic_help="$help"
- help="Try \`$progname --help --mode=$mode' for more information."
+ # preserve --debug
+ test "$opt_debug" = : || func_append preserve_args " --debug"
+
+ case $host in
+ *cygwin* | *mingw* | *pw32* | *cegcc*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ func_fatal_configuration "not configured to build any kind of library"
+ fi
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+ func_error "unrecognized option \`-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$progname --help --mode=$opt_mode' for more information."
+ }
+
+
+ # Bail if the options were screwed
+ $exit_cmd $EXIT_FAILURE
}
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
# func_lalib_p file
# True iff FILE is a libtool `.la' library or `.lo' object file.
# This function is only a basic sanity check; it will hardly flush out
# determined imposters.
func_lalib_p ()
{
- $SED -e 4q "$1" 2>/dev/null \
- | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null \
+ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
}
# func_lalib_unsafe_p file
@@ -907,7 +1245,7 @@ func_lalib_p ()
func_lalib_unsafe_p ()
{
lalib_p=no
- if test -r "$1" && exec 5<&0 <"$1"; then
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
for lalib_p_l in 1 2 3 4
do
read lalib_p_line
@@ -949,12 +1287,9 @@ func_ltwrapper_executable_p ()
# temporary ltwrapper_script.
func_ltwrapper_scriptname ()
{
- func_ltwrapper_scriptname_result=""
- if func_ltwrapper_executable_p "$1"; then
- func_dirname_and_basename "$1" "" "."
- func_stripname '' '.exe' "$func_basename_result"
- func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
- fi
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
}
# func_ltwrapper_p file
@@ -1000,6 +1335,37 @@ func_source ()
}
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case "$lt_sysroot:$1" in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result="=$func_stripname_result"
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
# func_infer_tag arg
# Infer tagged configuration to use if any are available and
# if one wasn't chosen via the "--tag" command line option.
@@ -1012,13 +1378,15 @@ func_infer_tag ()
if test -n "$available_tags" && test -z "$tagname"; then
CC_quoted=
for arg in $CC; do
- func_quote_for_eval "$arg"
- CC_quoted="$CC_quoted $func_quote_for_eval_result"
+ func_append_quoted CC_quoted "$arg"
done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
case $@ in
# Blanks in the command may have been stripped by the calling shell,
# but not from the CC environment variable when configure was run.
- " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;;
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
# Blanks at the start of $base_compile will cause this to fail
# if we don't check for them as well.
*)
@@ -1029,11 +1397,13 @@ func_infer_tag ()
CC_quoted=
for arg in $CC; do
# Double-quote args containing other shell metacharacters.
- func_quote_for_eval "$arg"
- CC_quoted="$CC_quoted $func_quote_for_eval_result"
+ func_append_quoted CC_quoted "$arg"
done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
case "$@ " in
- " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*)
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
# The compiler in the base compile command matches
# the one in the tagged configuration.
# Assume this is the tagged configuration we want.
@@ -1096,6 +1466,486 @@ EOF
}
}
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+ $opt_debug
+ func_convert_core_file_wine_to_w32_result="$1"
+ if test -n "$1"; then
+ # Unfortunately, winepath does not exit with a non-zero error code, so we
+ # are forced to check the contents of stdout. On the other hand, if the
+ # command is not found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both error code of
+ # zero AND non-empty stdout, which explains the odd construction:
+ func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$lt_sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $opt_debug
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=""
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $opt_debug
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $opt_debug
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $opt_debug
+ if test -z "$2" && test -n "$1" ; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " \`$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result="$1"
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $opt_debug
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " \`$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result="$3"
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $opt_debug
+ case $4 in
+ $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $opt_debug
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $opt_debug
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $opt_debug
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd="func_convert_path_${func_stripname_result}"
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $opt_debug
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+ func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from ARG. MSYS
+ # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+ # and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format. Requires a wine environment and
+# a working winepath. Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set. Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
# func_mode_compile arg...
func_mode_compile ()
{
@@ -1136,12 +1986,12 @@ func_mode_compile ()
;;
-pie | -fpie | -fPIE)
- pie_flag="$pie_flag $arg"
+ func_append pie_flag " $arg"
continue
;;
-shared | -static | -prefer-pic | -prefer-non-pic)
- later="$later $arg"
+ func_append later " $arg"
continue
;;
@@ -1162,15 +2012,14 @@ func_mode_compile ()
save_ifs="$IFS"; IFS=','
for arg in $args; do
IFS="$save_ifs"
- func_quote_for_eval "$arg"
- lastarg="$lastarg $func_quote_for_eval_result"
+ func_append_quoted lastarg "$arg"
done
IFS="$save_ifs"
func_stripname ' ' '' "$lastarg"
lastarg=$func_stripname_result
# Add the arguments to base_compile.
- base_compile="$base_compile $lastarg"
+ func_append base_compile " $lastarg"
continue
;;
@@ -1186,8 +2035,7 @@ func_mode_compile ()
esac # case $arg_mode
# Aesthetically quote the previous argument.
- func_quote_for_eval "$lastarg"
- base_compile="$base_compile $func_quote_for_eval_result"
+ func_append_quoted base_compile "$lastarg"
done # for arg
case $arg_mode in
@@ -1212,7 +2060,7 @@ func_mode_compile ()
*.[cCFSifmso] | \
*.ada | *.adb | *.ads | *.asm | \
*.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
- *.[fF][09]? | *.for | *.java | *.obj | *.sx)
+ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
func_xform "$libobj"
libobj=$func_xform_result
;;
@@ -1275,7 +2123,7 @@ func_mode_compile ()
# On Cygwin there's no "real" PIC flag so we must build both object types
case $host_os in
- cygwin* | mingw* | pw32* | os2*)
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
pic_mode=default
;;
esac
@@ -1287,7 +2135,7 @@ func_mode_compile ()
# Calculate the filename of the output object if compiler does
# not support -o with -c
if test "$compiler_c_o" = no; then
- output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
lockfile="$output_obj.lock"
else
output_obj=
@@ -1318,17 +2166,16 @@ compiler."
$opt_dry_run || $RM $removelist
exit $EXIT_FAILURE
fi
- removelist="$removelist $output_obj"
+ func_append removelist " $output_obj"
$ECHO "$srcfile" > "$lockfile"
fi
$opt_dry_run || $RM $removelist
- removelist="$removelist $lockfile"
+ func_append removelist " $lockfile"
trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
- if test -n "$fix_srcfile_path"; then
- eval srcfile=\"$fix_srcfile_path\"
- fi
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
func_quote_for_eval "$srcfile"
qsrcfile=$func_quote_for_eval_result
@@ -1348,7 +2195,7 @@ compiler."
if test -z "$output_obj"; then
# Place PIC objects in $objdir
- command="$command -o $lobj"
+ func_append command " -o $lobj"
fi
func_show_eval_locale "$command" \
@@ -1395,11 +2242,11 @@ compiler."
command="$base_compile $qsrcfile $pic_flag"
fi
if test "$compiler_c_o" = yes; then
- command="$command -o $obj"
+ func_append command " -o $obj"
fi
# Suppress compiler output if we already did a PIC compilation.
- command="$command$suppress_output"
+ func_append command "$suppress_output"
func_show_eval_locale "$command" \
'$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
@@ -1444,13 +2291,13 @@ compiler."
}
$opt_help || {
-test "$mode" = compile && func_mode_compile ${1+"$@"}
+ test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
}
func_mode_help ()
{
# We need to display help for each of the modes.
- case $mode in
+ case $opt_mode in
"")
# Generic help is extracted from the usage comments
# at the start of this file.
@@ -1481,10 +2328,11 @@ This mode accepts the following additional options:
-o OUTPUT-FILE set the output file name to OUTPUT-FILE
-no-suppress do not suppress compiler output for multiple passes
- -prefer-pic try to building PIC objects only
- -prefer-non-pic try to building non-PIC objects only
+ -prefer-pic try to build PIC objects only
+ -prefer-non-pic try to build non-PIC objects only
-shared do not build a \`.o' file suitable for static linking
-static only build a \`.o' file suitable for static linking
+ -Wc,FLAG pass FLAG directly to the compiler
COMPILE-COMMAND is a command to be used in creating a \`standard' object file
from the given SOURCEFILE.
@@ -1537,7 +2385,7 @@ either the \`install' or \`cp' program.
The following components of INSTALL-COMMAND are treated specially:
- -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+ -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation
The rest of the components are interpreted as arguments to that command (only
BSD-compatible install options are recognized)."
@@ -1557,6 +2405,8 @@ The following components of LINK-COMMAND are treated specially:
-all-static do not do any dynamic linking at all
-avoid-version do not add a version suffix if possible
+ -bindir BINDIR specify path to binaries directory (for systems where
+ libraries must be found in the PATH setting at runtime)
-dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
-dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
-export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
@@ -1585,6 +2435,11 @@ The following components of LINK-COMMAND are treated specially:
-version-info CURRENT[:REVISION[:AGE]]
specify library version info [each variable defaults to 0]
-weak LIBNAME declare that the target provides the LIBNAME interface
+ -Wc,FLAG
+ -Xcompiler FLAG pass linker-specific FLAG directly to the compiler
+ -Wl,FLAG
+ -Xlinker FLAG pass linker-specific FLAG directly to the linker
+ -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
All other options (arguments beginning with \`-') are ignored.
@@ -1618,18 +2473,44 @@ Otherwise, only FILE itself is deleted using RM."
;;
*)
- func_fatal_help "invalid operation mode \`$mode'"
+ func_fatal_help "invalid operation mode \`$opt_mode'"
;;
esac
- $ECHO
+ echo
$ECHO "Try \`$progname --help' for more information about other modes."
-
- exit $?
}
- # Now that we've collected a possible --mode arg, show help if necessary
- $opt_help && func_mode_help
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+ if test "$opt_help" = :; then
+ func_mode_help
+ else
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ func_mode_help
+ done
+ } | sed -n '1p; 2,$s/^Usage:/ or: /p'
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ echo
+ func_mode_help
+ done
+ } |
+ sed '1d
+ /^When reporting/,/^Report/{
+ H
+ d
+ }
+ $x
+ /information about other modes/d
+ /more detailed .*MODE/d
+ s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+ fi
+ exit $?
+fi
# func_mode_execute arg...
@@ -1642,13 +2523,16 @@ func_mode_execute ()
func_fatal_help "you must specify a COMMAND"
# Handle -dlopen flags immediately.
- for file in $execute_dlfiles; do
+ for file in $opt_dlopen; do
test -f "$file" \
|| func_fatal_help "\`$file' is not a file"
dir=
case $file in
*.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
# Check to see that this really is a libtool archive.
func_lalib_unsafe_p "$file" \
|| func_fatal_help "\`$lib' is not a valid libtool archive"
@@ -1670,7 +2554,7 @@ func_mode_execute ()
dir="$func_dirname_result"
if test -f "$dir/$objdir/$dlname"; then
- dir="$dir/$objdir"
+ func_append dir "/$objdir"
else
if test ! -f "$dir/$dlname"; then
func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
@@ -1711,7 +2595,7 @@ func_mode_execute ()
for file
do
case $file in
- -*) ;;
+ -* | *.la | *.lo ) ;;
*)
# Do a test to see if this is really a libtool program.
if func_ltwrapper_script_p "$file"; then
@@ -1727,8 +2611,7 @@ func_mode_execute ()
;;
esac
# Quote arguments (to preserve shell metacharacters).
- func_quote_for_eval "$file"
- args="$args $func_quote_for_eval_result"
+ func_append_quoted args "$file"
done
if test "X$opt_dry_run" = Xfalse; then
@@ -1753,29 +2636,66 @@ func_mode_execute ()
# Display what would be done.
if test -n "$shlibpath_var"; then
eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
- $ECHO "export $shlibpath_var"
+ echo "export $shlibpath_var"
fi
$ECHO "$cmd$args"
exit $EXIT_SUCCESS
fi
}
-test "$mode" = execute && func_mode_execute ${1+"$@"}
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
# func_mode_finish arg...
func_mode_finish ()
{
$opt_debug
- libdirs="$nonopt"
+ libs=
+ libdirs=
admincmds=
- if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
- for dir
- do
- libdirs="$libdirs $dir"
- done
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "\`$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument \`$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
for libdir in $libdirs; do
if test -n "$finish_cmds"; then
# Do each command in the finish commands.
@@ -1785,7 +2705,7 @@ func_mode_finish ()
if test -n "$finish_eval"; then
# Do the single finish_eval.
eval cmds=\"$finish_eval\"
- $opt_dry_run || eval "$cmds" || admincmds="$admincmds
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
$cmds"
fi
done
@@ -1794,53 +2714,55 @@ func_mode_finish ()
# Exit here if they wanted silent mode.
$opt_silent && exit $EXIT_SUCCESS
- $ECHO "X----------------------------------------------------------------------" | $Xsed
- $ECHO "Libraries have been installed in:"
- for libdir in $libdirs; do
- $ECHO " $libdir"
- done
- $ECHO
- $ECHO "If you ever happen to want to link against installed libraries"
- $ECHO "in a given directory, LIBDIR, you must either use libtool, and"
- $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'"
- $ECHO "flag during linking and do at least one of the following:"
- if test -n "$shlibpath_var"; then
- $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable"
- $ECHO " during execution"
- fi
- if test -n "$runpath_var"; then
- $ECHO " - add LIBDIR to the \`$runpath_var' environment variable"
- $ECHO " during linking"
- fi
- if test -n "$hardcode_libdir_flag_spec"; then
- libdir=LIBDIR
- eval flag=\"$hardcode_libdir_flag_spec\"
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
- $ECHO " - use the \`$flag' linker flag"
- fi
- if test -n "$admincmds"; then
- $ECHO " - have your system administrator run these commands:$admincmds"
- fi
- if test -f /etc/ld.so.conf; then
- $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
- fi
- $ECHO
+ $ECHO " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
- $ECHO "See any operating system documentation about shared libraries for"
- case $host in
- solaris2.[6789]|solaris2.1[0-9])
- $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual"
- $ECHO "pages."
- ;;
- *)
- $ECHO "more information, such as the ld(1) and ld.so(8) manual pages."
- ;;
- esac
- $ECHO "X----------------------------------------------------------------------" | $Xsed
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
exit $EXIT_SUCCESS
}
-test "$mode" = finish && func_mode_finish ${1+"$@"}
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
# func_mode_install arg...
@@ -1851,7 +2773,7 @@ func_mode_install ()
# install_prog (especially on Windows NT).
if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
# Allow the use of GNU shtool's install command.
- $ECHO "X$nonopt" | $GREP shtool >/dev/null; then
+ case $nonopt in *shtool*) :;; *) false;; esac; then
# Aesthetically quote it.
func_quote_for_eval "$nonopt"
install_prog="$func_quote_for_eval_result "
@@ -1865,7 +2787,12 @@ func_mode_install ()
# The real first argument should be the name of the installation program.
# Aesthetically quote it.
func_quote_for_eval "$arg"
- install_prog="$install_prog$func_quote_for_eval_result"
+ func_append install_prog "$func_quote_for_eval_result"
+ install_shared_prog=$install_prog
+ case " $install_prog " in
+ *[\\\ /]cp\ *) install_cp=: ;;
+ *) install_cp=false ;;
+ esac
# We need to accept at least all the BSD install flags.
dest=
@@ -1875,10 +2802,12 @@ func_mode_install ()
install_type=
isdir=no
stripme=
+ no_mode=:
for arg
do
+ arg2=
if test -n "$dest"; then
- files="$files $dest"
+ func_append files " $dest"
dest=$arg
continue
fi
@@ -1886,10 +2815,9 @@ func_mode_install ()
case $arg in
-d) isdir=yes ;;
-f)
- case " $install_prog " in
- *[\\\ /]cp\ *) ;;
- *) prev=$arg ;;
- esac
+ if $install_cp; then :; else
+ prev=$arg
+ fi
;;
-g | -m | -o)
prev=$arg
@@ -1903,6 +2831,10 @@ func_mode_install ()
*)
# If the previous option needed an argument, then skip it.
if test -n "$prev"; then
+ if test "x$prev" = x-m && test -n "$install_override_mode"; then
+ arg2=$install_override_mode
+ no_mode=false
+ fi
prev=
else
dest=$arg
@@ -1913,7 +2845,11 @@ func_mode_install ()
# Aesthetically quote the argument.
func_quote_for_eval "$arg"
- install_prog="$install_prog $func_quote_for_eval_result"
+ func_append install_prog " $func_quote_for_eval_result"
+ if test -n "$arg2"; then
+ func_quote_for_eval "$arg2"
+ fi
+ func_append install_shared_prog " $func_quote_for_eval_result"
done
test -z "$install_prog" && \
@@ -1922,6 +2858,13 @@ func_mode_install ()
test -n "$prev" && \
func_fatal_help "the \`$prev' option requires an argument"
+ if test -n "$install_override_mode" && $no_mode; then
+ if $install_cp; then :; else
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
+ fi
+ fi
+
if test -z "$files"; then
if test -z "$dest"; then
func_fatal_help "no file or destination specified"
@@ -1976,10 +2919,13 @@ func_mode_install ()
case $file in
*.$libext)
# Do the static libraries later.
- staticlibs="$staticlibs $file"
+ func_append staticlibs " $file"
;;
*.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
# Check to see that this really is a libtool archive.
func_lalib_unsafe_p "$file" \
|| func_fatal_help "\`$file' is not a valid libtool archive"
@@ -1993,23 +2939,23 @@ func_mode_install ()
if test "X$destdir" = "X$libdir"; then
case "$current_libdirs " in
*" $libdir "*) ;;
- *) current_libdirs="$current_libdirs $libdir" ;;
+ *) func_append current_libdirs " $libdir" ;;
esac
else
# Note the libdir as a future libdir.
case "$future_libdirs " in
*" $libdir "*) ;;
- *) future_libdirs="$future_libdirs $libdir" ;;
+ *) func_append future_libdirs " $libdir" ;;
esac
fi
func_dirname "$file" "/" ""
dir="$func_dirname_result"
- dir="$dir$objdir"
+ func_append dir "$objdir"
if test -n "$relink_command"; then
# Determine the prefix the user has applied to our future dir.
- inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"`
+ inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
# Don't allow the user to place us outside of our expected
# location b/c this prevents finding dependent libraries that
@@ -2022,9 +2968,9 @@ func_mode_install ()
if test -n "$inst_prefix_dir"; then
# Stick the inst_prefix_dir data into the link command.
- relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
else
- relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"`
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
fi
func_warning "relinking \`$file'"
@@ -2042,11 +2988,11 @@ func_mode_install ()
test -n "$relink_command" && srcname="$realname"T
# Install the shared library and build the symlinks.
- func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \
+ func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
'exit $?'
tstripme="$stripme"
case $host_os in
- cygwin* | mingw* | pw32*)
+ cygwin* | mingw* | pw32* | cegcc*)
case $realname in
*.dll.a)
tstripme=""
@@ -2082,7 +3028,7 @@ func_mode_install ()
func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
# Maybe install the static library, too.
- test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
;;
*.lo)
@@ -2152,7 +3098,7 @@ func_mode_install ()
# Do a test to see if this is really a libtool program.
case $host in
- *cygwin*|*mingw*)
+ *cygwin* | *mingw*)
if func_ltwrapper_executable_p "$file"; then
func_ltwrapper_scriptname "$file"
wrapper=$func_ltwrapper_scriptname_result
@@ -2182,7 +3128,7 @@ func_mode_install ()
if test -f "$lib"; then
func_source "$lib"
fi
- libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
if test -n "$libdir" && test ! -f "$libfile"; then
func_warning "\`$lib' has not been installed in \`$libdir'"
finalize=no
@@ -2201,7 +3147,7 @@ func_mode_install ()
file="$func_basename_result"
outputname="$tmpdir/$file"
# Replace the output file specification.
- relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+ relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
$opt_silent || {
func_quote_for_expand "$relink_command"
@@ -2220,7 +3166,7 @@ func_mode_install ()
}
else
# Install the binary that we compiled earlier.
- file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
fi
fi
@@ -2256,11 +3202,13 @@ func_mode_install ()
# Set up the ranlib parameters.
oldlib="$destdir/$name"
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
if test -n "$stripme" && test -n "$old_striplib"; then
- func_show_eval "$old_striplib $oldlib" 'exit $?'
+ func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
fi
# Do each command in the postinstall commands.
@@ -2279,7 +3227,7 @@ func_mode_install ()
fi
}
-test "$mode" = install && func_mode_install ${1+"$@"}
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
# func_generate_dlsyms outputname originator pic_p
@@ -2322,6 +3270,22 @@ func_generate_dlsyms ()
extern \"C\" {
#endif
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
/* External symbol declarations for the compiler. */\
"
@@ -2331,10 +3295,11 @@ extern \"C\" {
$opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
# Add our own program objects to the symbol list.
- progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
for progfile in $progfiles; do
- func_verbose "extracting global C symbols from \`$progfile'"
- $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'"
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
done
if test -n "$exclude_expsyms"; then
@@ -2358,7 +3323,7 @@ extern \"C\" {
$RM $export_symbols
eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
case $host in
- *cygwin* | *mingw* )
+ *cygwin* | *mingw* | *cegcc* )
eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
;;
@@ -2370,7 +3335,7 @@ extern \"C\" {
eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
eval '$MV "$nlist"T "$nlist"'
case $host in
- *cygwin | *mingw* )
+ *cygwin* | *mingw* | *cegcc* )
eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
;;
@@ -2383,10 +3348,52 @@ extern \"C\" {
func_verbose "extracting global C symbols from \`$dlprefile'"
func_basename "$dlprefile"
name="$func_basename_result"
- $opt_dry_run || {
- eval '$ECHO ": $name " >> "$nlist"'
- eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
- }
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=""
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname" ; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename="$func_basename_result"
+ else
+ # no lafile. user explicitly requested -dlpreopen <import library>.
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename" ; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
done
$opt_dry_run || {
@@ -2414,36 +3421,19 @@ extern \"C\" {
if test -f "$nlist"S; then
eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
else
- $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
fi
- $ECHO >> "$output_objdir/$my_dlsyms" "\
+ echo >> "$output_objdir/$my_dlsyms" "\
/* The mapping between symbol names and symbols. */
typedef struct {
const char *name;
void *address;
} lt_dlsymlist;
-"
- case $host in
- *cygwin* | *mingw* )
- $ECHO >> "$output_objdir/$my_dlsyms" "\
-/* DATA imports from DLLs on WIN32 con't be const, because
- runtime relocations are performed -- see ld's documentation
- on pseudo-relocs. */"
- lt_dlsym_const= ;;
- *osf5*)
- echo >> "$output_objdir/$my_dlsyms" "\
-/* This system does not cope well with relocations in const data */"
- lt_dlsym_const= ;;
- *)
- lt_dlsym_const=const ;;
- esac
-
- $ECHO >> "$output_objdir/$my_dlsyms" "\
-extern $lt_dlsym_const lt_dlsymlist
+extern LT_DLSYM_CONST lt_dlsymlist
lt_${my_prefix}_LTX_preloaded_symbols[];
-$lt_dlsym_const lt_dlsymlist
+LT_DLSYM_CONST lt_dlsymlist
lt_${my_prefix}_LTX_preloaded_symbols[] =
{\
{ \"$my_originator\", (void *) 0 },"
@@ -2456,7 +3446,7 @@ lt_${my_prefix}_LTX_preloaded_symbols[] =
eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
;;
esac
- $ECHO >> "$output_objdir/$my_dlsyms" "\
+ echo >> "$output_objdir/$my_dlsyms" "\
{0, (void *) 0}
};
@@ -2483,7 +3473,7 @@ static const void *lt_preloaded_setup() {
# linked before any other PIC object. But we must not use
# pic_flag when linking with -static. The problem exists in
# FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
- *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
*-*-hpux*)
pic_flag_for_symtable=" $pic_flag" ;;
@@ -2499,7 +3489,7 @@ static const void *lt_preloaded_setup() {
for arg in $LTCFLAGS; do
case $arg in
-pie | -fpie | -fPIE) ;;
- *) symtab_cflags="$symtab_cflags $arg" ;;
+ *) func_append symtab_cflags " $arg" ;;
esac
done
@@ -2512,18 +3502,18 @@ static const void *lt_preloaded_setup() {
# Transform the symbol file into the correct name.
symfileobj="$output_objdir/${my_outputname}S.$objext"
case $host in
- *cygwin* | *mingw* )
+ *cygwin* | *mingw* | *cegcc* )
if test -f "$output_objdir/$my_outputname.def"; then
- compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
- finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
else
- compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
- finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
fi
;;
*)
- compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
- finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
;;
esac
;;
@@ -2537,8 +3527,8 @@ static const void *lt_preloaded_setup() {
# really was required.
# Nullify the symbol file.
- compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
- finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
fi
}
@@ -2548,6 +3538,7 @@ static const void *lt_preloaded_setup() {
# Need a lot of goo to handle *both* DLLs and import libs
# Has to be a shell function in order to 'eat' the argument
# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
func_win32_libid ()
{
$opt_debug
@@ -2558,9 +3549,11 @@ func_win32_libid ()
win32_libid_type="x86 archive import"
;;
*ar\ archive*) # could be an import, or static
+ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
- $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
- win32_nmres=`eval $NM -f posix -A $1 |
+ $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
$SED -n -e '
1,100{
/ I /{
@@ -2589,6 +3582,131 @@ func_win32_libid ()
$ECHO "$win32_libid_type"
}
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $opt_debug
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $opt_debug
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive which possess that section. Heuristic: eliminate
+ # all those which have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $opt_debug
+ if func_cygming_gnu_implib_p "$1" ; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1" ; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=""
+ fi
+}
# func_extract_an_archive dir oldlib
@@ -2597,7 +3715,18 @@ func_extract_an_archive ()
$opt_debug
f_ex_an_ar_dir="$1"; shift
f_ex_an_ar_oldlib="$1"
- func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?'
+ if test "$lock_old_archive_extraction" = yes; then
+ lockfile=$f_ex_an_ar_oldlib.lock
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ fi
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test "$lock_old_archive_extraction" = yes; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
:
else
@@ -2668,7 +3797,7 @@ func_extract_archives ()
darwin_file=
darwin_files=
for darwin_file in $darwin_filelist; do
- darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+ darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
$LIPO -create -output "$darwin_file" $darwin_files
done # $darwin_filelist
$RM -rf unfat-$$
@@ -2683,34 +3812,30 @@ func_extract_archives ()
func_extract_an_archive "$my_xdir" "$my_xabs"
;;
esac
- my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
done
func_extract_archives_result="$my_oldobjs"
}
-
-# func_emit_wrapper arg
+# func_emit_wrapper [arg=no]
#
-# emit a libtool wrapper script on stdout
-# don't directly open a file because we may want to
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
# incorporate the script contents within a cygwin/mingw
# wrapper executable. Must ONLY be called from within
-# func_mode_link because it depends on a number of variable
+# func_mode_link because it depends on a number of variables
# set therein.
#
-# arg is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
# variable will take. If 'yes', then the emitted script
# will assume that the directory in which it is stored is
-# the '.lib' directory. This is a cygwin/mingw-specific
+# the $objdir directory. This is a cygwin/mingw-specific
# behavior.
func_emit_wrapper ()
{
- func_emit_wrapper_arg1=no
- if test -n "$1" ; then
- func_emit_wrapper_arg1=$1
- fi
+ func_emit_wrapper_arg1=${1-no}
$ECHO "\
#! $SHELL
@@ -2726,7 +3851,6 @@ func_emit_wrapper ()
# Sed substitution that helps us do robust quoting. It backslashifies
# metacharacters that are still active within double-quoted strings.
-Xsed='${SED} -e 1s/^X//'
sed_quote_subst='$sed_quote_subst'
# Be Bourne compatible
@@ -2757,31 +3881,135 @@ if test \"\$libtool_install_magic\" = \"$magic\"; then
else
# When we are sourced in execute mode, \$file and \$ECHO are already set.
if test \"\$libtool_execute_magic\" != \"$magic\"; then
- ECHO=\"$qecho\"
- file=\"\$0\"
- # Make sure echo works.
- if test \"X\$1\" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
- elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then
- # Yippee, \$ECHO works!
- :
- else
- # Restart under the correct shell, and then maybe \$ECHO will work.
- exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
- fi
- fi\
+ file=\"\$0\""
+
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+ $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+ ECHO=\"$qECHO\"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=\$0
+ shift
+ for lt_opt
+ do
+ case \"\$lt_opt\" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+ test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+ lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+ cat \"\$lt_dump_D/\$lt_dump_F\"
+ exit 0
+ ;;
+ --lt-*)
+ \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n \"\$lt_option_debug\"; then
+ echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
"
- $ECHO "\
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case \" \$* \" in
+ *\\ --lt-*)
+ for lt_wr_arg
+ do
+ case \$lt_wr_arg in
+ --lt-*) ;;
+ *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core \${1+\"\$@\"}
+}
+
+ # Parse options
+ func_parse_lt_options \"\$0\" \${1+\"\$@\"}
# Find the directory that this script lives in.
- thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
test \"x\$thisdir\" = \"x\$file\" && thisdir=.
# Follow symbolic links until we get to the real thisdir.
- file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+ file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
while test -n \"\$file\"; do
- destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+ destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
# If there was a directory component, then change thisdir.
if test \"x\$destdir\" != \"x\$file\"; then
@@ -2791,8 +4019,8 @@ else
esac
fi
- file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
- file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+ file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
done
# Usually 'no', except on cygwin/mingw when embedded into
@@ -2805,7 +4033,7 @@ else
fi
# remove .libs from thisdir
case \"\$thisdir\" in
- *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
$objdir ) thisdir=. ;;
esac
fi
@@ -2860,6 +4088,18 @@ else
if test -f \"\$progdir/\$program\"; then"
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
# Export our shlibpath_var if we have one.
if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
$ECHO "\
@@ -2868,53 +4108,28 @@ else
# Some systems cannot cope with colon-terminated $shlibpath_var
# The second colon is a workaround for a bug in BeOS R4 sed
- $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+ $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
export $shlibpath_var
"
fi
- # fixup the dll searchpath if we need to.
- if test -n "$dllsearchpath"; then
- $ECHO "\
- # Add the dll search path components to the executable PATH
- PATH=$dllsearchpath:\$PATH
-"
- fi
-
$ECHO "\
if test \"\$libtool_execute_magic\" != \"$magic\"; then
# Run the actual program with our arguments.
-"
- case $host in
- # Backslashes separate directories on plain windows
- *-*-mingw | *-*-os2*)
- $ECHO "\
- exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
-"
- ;;
-
- *)
- $ECHO "\
- exec \"\$progdir/\$program\" \${1+\"\$@\"}
-"
- ;;
- esac
- $ECHO "\
- \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
- exit 1
+ func_exec_program \${1+\"\$@\"}
fi
else
# The program doesn't exist.
\$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
\$ECHO \"This script is just a wrapper for \$program.\" 1>&2
- $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
exit 1
fi
fi\
"
}
-# end: func_emit_wrapper
+
# func_emit_cwrapperexe_src
# emit the source code for a wrapper executable on stdout
@@ -2932,20 +4147,18 @@ func_emit_cwrapperexe_src ()
This wrapper executable should never be moved out of the build directory.
If it is, it will not operate correctly.
-
- Currently, it simply execs the wrapper *script* "$SHELL $output",
- but could eventually absorb all of the scripts functionality and
- exec $objdir/$outputname directly.
*/
EOF
cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER
# include <direct.h>
# include <process.h>
# include <io.h>
-# define setmode _setmode
#else
# include <unistd.h>
# include <stdint.h>
@@ -2962,6 +4175,44 @@ EOF
#include <fcntl.h>
#include <sys/stat.h>
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+# define _INTPTR_T_DEFINED
+# define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
#if defined(PATH_MAX)
# define LT_PATHMAX PATH_MAX
#elif defined(MAXPATHLEN)
@@ -2977,14 +4228,7 @@ EOF
# define S_IXGRP 0
#endif
-#ifdef _MSC_VER
-# define S_IXUSR _S_IEXEC
-# define stat _stat
-# ifndef _INTPTR_T_DEFINED
-# define intptr_t int
-# endif
-#endif
-
+/* path handling portability macros */
#ifndef DIR_SEPARATOR
# define DIR_SEPARATOR '/'
# define PATH_SEPARATOR ':'
@@ -3015,10 +4259,6 @@ EOF
# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
#endif /* PATH_SEPARATOR_2 */
-#ifdef __CYGWIN__
-# define FOPEN_WB "wb"
-#endif
-
#ifndef FOPEN_WB
# define FOPEN_WB "w"
#endif
@@ -3031,22 +4271,13 @@ EOF
if (stale) { free ((void *) stale); stale = 0; } \
} while (0)
-#undef LTWRAPPER_DEBUGPRINTF
-#if defined DEBUGWRAPPER
-# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args
-static void
-ltwrapper_debugprintf (const char *fmt, ...)
-{
- va_list args;
- va_start (args, fmt);
- (void) vfprintf (stderr, fmt, args);
- va_end (args);
-}
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
#else
-# define LTWRAPPER_DEBUGPRINTF(args)
+static int lt_debug = 0;
#endif
-const char *program_name = NULL;
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
void *xmalloc (size_t num);
char *xstrdup (const char *string);
@@ -3056,37 +4287,88 @@ char *chase_symlinks (const char *pathspec);
int make_executable (const char *path);
int check_executable (const char *path);
char *strendzap (char *str, const char *pat);
-void lt_fatal (const char *message, ...);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
-static const char *script_text =
+ cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
EOF
- func_emit_wrapper yes |
- $SED -e 's/\([\\"]\)/\\\1/g' \
- -e 's/^/ "/' -e 's/$/\\n"/'
- echo ";"
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_path "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_path "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test "$fast_install" = yes; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
- cat <<EOF
-const char * MAGIC_EXE = "$magic_exe";
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
int
main (int argc, char *argv[])
{
char **newargz;
+ int newargc;
char *tmp_pathspec;
char *actual_cwrapper_path;
- char *shwrapper_name;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
intptr_t rval = 127;
- FILE *shwrapper;
- const char *dumpscript_opt = "--lt-dump-script";
int i;
program_name = (char *) xstrdup (base_name (argv[0]));
- LTWRAPPER_DEBUGPRINTF (("(main) argv[0] : %s\n", argv[0]));
- LTWRAPPER_DEBUGPRINTF (("(main) program_name : %s\n", program_name));
+ newargz = XMALLOC (char *, argc + 1);
- /* very simple arg parsing; don't want to rely on getopt */
+ /* very simple arg parsing; don't want to rely on getopt
+ * also, copy all non cwrapper options to newargz, except
+ * argz[0], which is handled differently
+ */
+ newargc=0;
for (i = 1; i < argc; i++)
{
if (strcmp (argv[i], dumpscript_opt) == 0)
@@ -3099,82 +4381,112 @@ EOF
;;
esac
- cat <<EOF
- printf ("%s", script_text);
+ cat <<"EOF"
+ lt_dump_script (stdout);
return 0;
}
+ if (strcmp (argv[i], debug_opt) == 0)
+ {
+ lt_debug = 1;
+ continue;
+ }
+ if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal (__FILE__, __LINE__,
+ "unrecognized %s option: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
}
+ newargz[++newargc] = NULL;
- newargz = XMALLOC (char *, argc + 2);
EOF
-
- if test -n "$TARGETSHELL" ; then
- # no path translation at all
- lt_newargv0=$TARGETSHELL
- else
- case "$host" in
- *mingw* )
- # awkward: cmd appends spaces to result
- lt_sed_strip_trailing_spaces="s/[ ]*\$//"
- lt_newargv0=`( cmd //c echo $SHELL | $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo $SHELL`
- case $lt_newargv0 in
- *.exe | *.EXE) ;;
- *) lt_newargv0=$lt_newargv0.exe ;;
- esac
- ;;
- * ) lt_newargv0=$SHELL ;;
- esac
- fi
-
- cat <<EOF
- newargz[0] = (char *) xstrdup ("$lt_newargv0");
+ cat <<EOF
+ /* The GNU banner must be the first non-error debug message */
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
EOF
-
cat <<"EOF"
+ lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
tmp_pathspec = find_executable (argv[0]);
if (tmp_pathspec == NULL)
- lt_fatal ("Couldn't find %s", argv[0]);
- LTWRAPPER_DEBUGPRINTF (("(main) found exe (before symlink chase) at : %s\n",
- tmp_pathspec));
+ lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (before symlink chase) at: %s\n",
+ tmp_pathspec);
actual_cwrapper_path = chase_symlinks (tmp_pathspec);
- LTWRAPPER_DEBUGPRINTF (("(main) found exe (after symlink chase) at : %s\n",
- actual_cwrapper_path));
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (after symlink chase) at: %s\n",
+ actual_cwrapper_path);
XFREE (tmp_pathspec);
- shwrapper_name = (char *) xstrdup (base_name (actual_cwrapper_path));
- strendzap (actual_cwrapper_path, shwrapper_name);
-
- /* shwrapper_name transforms */
- strendzap (shwrapper_name, ".exe");
- tmp_pathspec = XMALLOC (char, (strlen (shwrapper_name) +
- strlen ("_ltshwrapperTMP") + 1));
- strcpy (tmp_pathspec, shwrapper_name);
- strcat (tmp_pathspec, "_ltshwrapperTMP");
- XFREE (shwrapper_name);
- shwrapper_name = tmp_pathspec;
+ actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
tmp_pathspec = 0;
- LTWRAPPER_DEBUGPRINTF (("(main) libtool shell wrapper name: %s\n",
- shwrapper_name));
+
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) libtool target name: %s\n",
+ target_name);
EOF
cat <<EOF
- newargz[1] =
+ newargz[0] =
XMALLOC (char, (strlen (actual_cwrapper_path) +
- strlen ("$objdir") + 1 + strlen (shwrapper_name) + 1));
- strcpy (newargz[1], actual_cwrapper_path);
- strcat (newargz[1], "$objdir");
- strcat (newargz[1], "/");
- strcat (newargz[1], shwrapper_name);
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
EOF
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
case $host_os in
mingw*)
cat <<"EOF"
{
char* p;
- while ((p = strchr (newargz[1], '\\')) != NULL)
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
{
*p = '/';
}
@@ -3184,62 +4496,63 @@ EOF
esac
cat <<"EOF"
- XFREE (shwrapper_name);
+ XFREE (target_name);
XFREE (actual_cwrapper_path);
-
- /* always write in binary mode */
- if ((shwrapper = fopen (newargz[1], FOPEN_WB)) == 0)
- {
- lt_fatal ("Could not open %s for writing", newargz[1]);
- }
- fprintf (shwrapper, "%s", script_text);
- fclose (shwrapper);
-
- make_executable (newargz[1]);
-
- for (i = 1; i < argc; i++)
- newargz[i + 1] = xstrdup (argv[i]);
- newargz[argc + 1] = NULL;
-
- for (i = 0; i < argc + 1; i++)
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must
+ be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+ because on Windows, both *_VARNAMEs are PATH but uninstalled
+ libraries must come first. */
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+ lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+ nonnull (lt_argv_zero));
+ for (i = 0; i < newargc; i++)
{
- LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, newargz[i]));
+ lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+ i, nonnull (newargz[i]));
}
EOF
case $host_os in
mingw*)
- cat <<EOF
+ cat <<"EOF"
/* execv doesn't actually work on mingw as expected on unix */
- rval = _spawnv (_P_WAIT, "$lt_newargv0", (const char * const *) newargz);
+ newargz = prepare_spawn (newargz);
+ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
if (rval == -1)
{
/* failed to start process */
- LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"$lt_newargv0\": errno = %d\n", errno));
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) failed to launch target \"%s\": %s\n",
+ lt_argv_zero, nonnull (strerror (errno)));
return 127;
}
return rval;
-}
EOF
;;
*)
- cat <<EOF
- execv ("$lt_newargv0", newargz);
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
return rval; /* =127, but avoids unused variable warning */
-}
EOF
;;
esac
cat <<"EOF"
+}
void *
xmalloc (size_t num)
{
void *p = (void *) malloc (num);
if (!p)
- lt_fatal ("Memory exhausted");
+ lt_fatal (__FILE__, __LINE__, "memory exhausted");
return p;
}
@@ -3273,8 +4586,8 @@ check_executable (const char *path)
{
struct stat st;
- LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n",
- path ? (*path ? path : "EMPTY!") : "NULL!"));
+ lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+ nonempty (path));
if ((!path) || (!*path))
return 0;
@@ -3291,8 +4604,8 @@ make_executable (const char *path)
int rval = 0;
struct stat st;
- LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n",
- path ? (*path ? path : "EMPTY!") : "NULL!"));
+ lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+ nonempty (path));
if ((!path) || (!*path))
return 0;
@@ -3318,8 +4631,8 @@ find_executable (const char *wrapper)
int tmp_len;
char *concat_name;
- LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n",
- wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"));
+ lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+ nonempty (wrapper));
if ((wrapper == NULL) || (*wrapper == '\0'))
return NULL;
@@ -3372,7 +4685,8 @@ find_executable (const char *wrapper)
{
/* empty path: current directory */
if (getcwd (tmp, LT_PATHMAX) == NULL)
- lt_fatal ("getcwd failed");
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
tmp_len = strlen (tmp);
concat_name =
XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
@@ -3397,7 +4711,8 @@ find_executable (const char *wrapper)
}
/* Relative path | not found in path: prepend cwd */
if (getcwd (tmp, LT_PATHMAX) == NULL)
- lt_fatal ("getcwd failed");
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
tmp_len = strlen (tmp);
concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
memcpy (concat_name, tmp, tmp_len);
@@ -3423,8 +4738,9 @@ chase_symlinks (const char *pathspec)
int has_symlinks = 0;
while (strlen (tmp_pathspec) && !has_symlinks)
{
- LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n",
- tmp_pathspec));
+ lt_debugprintf (__FILE__, __LINE__,
+ "checking path component for symlinks: %s\n",
+ tmp_pathspec);
if (lstat (tmp_pathspec, &s) == 0)
{
if (S_ISLNK (s.st_mode) != 0)
@@ -3446,8 +4762,9 @@ chase_symlinks (const char *pathspec)
}
else
{
- char *errstr = strerror (errno);
- lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr);
+ lt_fatal (__FILE__, __LINE__,
+ "error accessing file \"%s\": %s",
+ tmp_pathspec, nonnull (strerror (errno)));
}
}
XFREE (tmp_pathspec);
@@ -3460,7 +4777,8 @@ chase_symlinks (const char *pathspec)
tmp_pathspec = realpath (pathspec, buf);
if (tmp_pathspec == 0)
{
- lt_fatal ("Could not follow symlinks for %s", pathspec);
+ lt_fatal (__FILE__, __LINE__,
+ "could not follow symlinks for %s", pathspec);
}
return xstrdup (tmp_pathspec);
#endif
@@ -3486,11 +4804,25 @@ strendzap (char *str, const char *pat)
return str;
}
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ if (lt_debug)
+ {
+ (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
static void
-lt_error_core (int exit_status, const char *mode,
+lt_error_core (int exit_status, const char *file,
+ int line, const char *mode,
const char *message, va_list ap)
{
- fprintf (stderr, "%s: %s: ", program_name, mode);
+ fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
vfprintf (stderr, message, ap);
fprintf (stderr, ".\n");
@@ -3499,23 +4831,270 @@ lt_error_core (int exit_status, const char *mode,
}
void
-lt_fatal (const char *message, ...)
+lt_fatal (const char *file, int line, const char *message, ...)
{
va_list ap;
va_start (ap, message);
- lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+ lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
va_end (ap);
}
+
+static const char *
+nonnull (const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+ return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_setenv) setting '%s' to '%s'\n",
+ nonnull (name), nonnull (value));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ int len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ int orig_value_len = strlen (orig_value);
+ int add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ int len = strlen (new_value);
+ while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[len-1] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+EOF
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+ Note that spawn() does not by itself call the command interpreter
+ (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+ ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&v);
+ v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+ }) ? "cmd.exe" : "command.com").
+ Instead it simply concatenates the arguments, separated by ' ', and calls
+ CreateProcess(). We must quote the arguments since Win32 CreateProcess()
+ interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+ special way:
+ - Space and tab are interpreted as delimiters. They are not treated as
+ delimiters if they are surrounded by double quotes: "...".
+ - Unescaped double quotes are removed from the input. Their only effect is
+ that within double quotes, space and tab are treated like normal
+ characters.
+ - Backslashes not followed by double quotes are not special.
+ - But 2*n+1 backslashes followed by a double quote become
+ n backslashes followed by a double quote (n >= 0):
+ \" -> "
+ \\\" -> \"
+ \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+ size_t argc;
+ char **new_argv;
+ size_t i;
+
+ /* Count number of arguments. */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ ;
+
+ /* Allocate new argument vector. */
+ new_argv = XMALLOC (char *, argc + 1);
+
+ /* Put quoted arguments into the new argument vector. */
+ for (i = 0; i < argc; i++)
+ {
+ const char *string = argv[i];
+
+ if (string[0] == '\0')
+ new_argv[i] = xstrdup ("\"\"");
+ else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+ {
+ int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+ size_t length;
+ unsigned int backslashes;
+ const char *s;
+ char *quoted_string;
+ char *p;
+
+ length = 0;
+ backslashes = 0;
+ if (quote_around)
+ length++;
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ length += backslashes + 1;
+ length++;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ length += backslashes + 1;
+
+ quoted_string = XMALLOC (char, length + 1);
+
+ p = quoted_string;
+ backslashes = 0;
+ if (quote_around)
+ *p++ = '"';
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ {
+ unsigned int j;
+ for (j = backslashes + 1; j > 0; j--)
+ *p++ = '\\';
+ }
+ *p++ = c;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ {
+ unsigned int j;
+ for (j = backslashes; j > 0; j--)
+ *p++ = '\\';
+ *p++ = '"';
+ }
+ *p = '\0';
+
+ new_argv[i] = quoted_string;
+ }
+ else
+ new_argv[i] = (char *) string;
+ }
+ new_argv[argc] = NULL;
+
+ return new_argv;
+}
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+ func_emit_wrapper yes |
+ $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/ fputs ("\1", f);/p
+g
+D'
+ cat <<"EOF"
+}
EOF
}
# end: func_emit_cwrapperexe_src
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+ $opt_debug
+ case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+ *import*) : ;;
+ *) false ;;
+ esac
+}
+
# func_mode_link arg...
func_mode_link ()
{
$opt_debug
case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
# It is impossible to link a dll without this setting, and
# we shouldn't force the makefile maintainer to figure out
# which system we are compiling for in order to pass an extra
@@ -3554,6 +5133,7 @@ func_mode_link ()
new_inherited_linker_flags=
avoid_version=no
+ bindir=
dlfiles=
dlprefiles=
dlself=no
@@ -3646,6 +5226,11 @@ func_mode_link ()
esac
case $prev in
+ bindir)
+ bindir="$arg"
+ prev=
+ continue
+ ;;
dlfiles|dlprefiles)
if test "$preload" = no; then
# Add the symbol object into the linking commands.
@@ -3677,9 +5262,9 @@ func_mode_link ()
;;
*)
if test "$prev" = dlfiles; then
- dlfiles="$dlfiles $arg"
+ func_append dlfiles " $arg"
else
- dlprefiles="$dlprefiles $arg"
+ func_append dlprefiles " $arg"
fi
prev=
continue
@@ -3703,7 +5288,7 @@ func_mode_link ()
*-*-darwin*)
case "$deplibs " in
*" $qarg.ltframework "*) ;;
- *) deplibs="$deplibs $qarg.ltframework" # this is fixed later
+ *) func_append deplibs " $qarg.ltframework" # this is fixed later
;;
esac
;;
@@ -3722,7 +5307,7 @@ func_mode_link ()
moreargs=
for fil in `cat "$save_arg"`
do
-# moreargs="$moreargs $fil"
+# func_append moreargs " $fil"
arg=$fil
# A libtool-controlled object.
@@ -3751,7 +5336,7 @@ func_mode_link ()
if test "$prev" = dlfiles; then
if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
- dlfiles="$dlfiles $pic_object"
+ func_append dlfiles " $pic_object"
prev=
continue
else
@@ -3763,7 +5348,7 @@ func_mode_link ()
# CHECK ME: I think I busted this. -Ossama
if test "$prev" = dlprefiles; then
# Preload the old-style object.
- dlprefiles="$dlprefiles $pic_object"
+ func_append dlprefiles " $pic_object"
prev=
fi
@@ -3833,12 +5418,12 @@ func_mode_link ()
if test "$prev" = rpath; then
case "$rpath " in
*" $arg "*) ;;
- *) rpath="$rpath $arg" ;;
+ *) func_append rpath " $arg" ;;
esac
else
case "$xrpath " in
*" $arg "*) ;;
- *) xrpath="$xrpath $arg" ;;
+ *) func_append xrpath " $arg" ;;
esac
fi
prev=
@@ -3850,28 +5435,28 @@ func_mode_link ()
continue
;;
weak)
- weak_libs="$weak_libs $arg"
+ func_append weak_libs " $arg"
prev=
continue
;;
xcclinker)
- linker_flags="$linker_flags $qarg"
- compiler_flags="$compiler_flags $qarg"
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $qarg"
prev=
func_append compile_command " $qarg"
func_append finalize_command " $qarg"
continue
;;
xcompiler)
- compiler_flags="$compiler_flags $qarg"
+ func_append compiler_flags " $qarg"
prev=
func_append compile_command " $qarg"
func_append finalize_command " $qarg"
continue
;;
xlinker)
- linker_flags="$linker_flags $qarg"
- compiler_flags="$compiler_flags $wl$qarg"
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $wl$qarg"
prev=
func_append compile_command " $wl$qarg"
func_append finalize_command " $wl$qarg"
@@ -3907,6 +5492,11 @@ func_mode_link ()
continue
;;
+ -bindir)
+ prev=bindir
+ continue
+ ;;
+
-dlopen)
prev=dlfiles
continue
@@ -3957,8 +5547,16 @@ func_mode_link ()
;;
-L*)
- func_stripname '-L' '' "$arg"
- dir=$func_stripname_result
+ func_stripname "-L" '' "$arg"
+ if test -z "$func_stripname_result"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between \`-L' and \`$1'"
+ else
+ func_fatal_error "need path for \`-L' option"
+ fi
+ fi
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
# We need an absolute path.
case $dir in
[\\/]* | [A-Za-z]:[\\/]*) ;;
@@ -3970,22 +5568,30 @@ func_mode_link ()
;;
esac
case "$deplibs " in
- *" -L$dir "*) ;;
+ *" -L$dir "* | *" $arg "*)
+ # Will only happen for absolute or sysroot arguments
+ ;;
*)
- deplibs="$deplibs -L$dir"
- lib_search_path="$lib_search_path $dir"
+ # Preserve sysroot, but never include relative directories
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+ *) func_append deplibs " -L$dir" ;;
+ esac
+ func_append lib_search_path " $dir"
;;
esac
case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
- testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'`
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
case :$dllsearchpath: in
*":$dir:"*) ;;
- *) dllsearchpath="$dllsearchpath:$dir";;
+ ::) dllsearchpath=$dir;;
+ *) func_append dllsearchpath ":$dir";;
esac
case :$dllsearchpath: in
*":$testbindir:"*) ;;
- *) dllsearchpath="$dllsearchpath:$testbindir";;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
esac
;;
esac
@@ -3995,7 +5601,7 @@ func_mode_link ()
-l*)
if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*)
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
# These systems don't actually have a C or math library (as such)
continue
;;
@@ -4009,7 +5615,7 @@ func_mode_link ()
;;
*-*-rhapsody* | *-*-darwin1.[012])
# Rhapsody C and math libraries are in the System framework
- deplibs="$deplibs System.ltframework"
+ func_append deplibs " System.ltframework"
continue
;;
*-*-sco3.2v5* | *-*-sco5v6*)
@@ -4029,7 +5635,7 @@ func_mode_link ()
;;
esac
fi
- deplibs="$deplibs $arg"
+ func_append deplibs " $arg"
continue
;;
@@ -4041,21 +5647,22 @@ func_mode_link ()
# Tru64 UNIX uses -model [arg] to determine the layout of C++
# classes, name mangling, and exception handling.
# Darwin uses the -arch flag to determine output architecture.
- -model|-arch|-isysroot)
- compiler_flags="$compiler_flags $arg"
+ -model|-arch|-isysroot|--sysroot)
+ func_append compiler_flags " $arg"
func_append compile_command " $arg"
func_append finalize_command " $arg"
prev=xcompiler
continue
;;
- -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
- compiler_flags="$compiler_flags $arg"
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ func_append compiler_flags " $arg"
func_append compile_command " $arg"
func_append finalize_command " $arg"
case "$new_inherited_linker_flags " in
*" $arg "*) ;;
- * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;;
+ * ) func_append new_inherited_linker_flags " $arg" ;;
esac
continue
;;
@@ -4072,7 +5679,7 @@ func_mode_link ()
-no-install)
case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin*)
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
# The PATH hackery in wrapper scripts is required on Windows
# and Darwin in order for the loader to find any dlls it needs.
func_warning "\`-no-install' is ignored for $host"
@@ -4122,13 +5729,17 @@ func_mode_link ()
# We need an absolute path.
case $dir in
[\\/]* | [A-Za-z]:[\\/]*) ;;
+ =*)
+ func_stripname '=' '' "$dir"
+ dir=$lt_sysroot$func_stripname_result
+ ;;
*)
func_fatal_error "only absolute run-paths are allowed"
;;
esac
case "$xrpath " in
*" $dir "*) ;;
- *) xrpath="$xrpath $dir" ;;
+ *) func_append xrpath " $dir" ;;
esac
continue
;;
@@ -4181,8 +5792,8 @@ func_mode_link ()
for flag in $args; do
IFS="$save_ifs"
func_quote_for_eval "$flag"
- arg="$arg $wl$func_quote_for_eval_result"
- compiler_flags="$compiler_flags $func_quote_for_eval_result"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
done
IFS="$save_ifs"
func_stripname ' ' '' "$arg"
@@ -4197,9 +5808,9 @@ func_mode_link ()
for flag in $args; do
IFS="$save_ifs"
func_quote_for_eval "$flag"
- arg="$arg $wl$func_quote_for_eval_result"
- compiler_flags="$compiler_flags $wl$func_quote_for_eval_result"
- linker_flags="$linker_flags $func_quote_for_eval_result"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
done
IFS="$save_ifs"
func_stripname ' ' '' "$arg"
@@ -4227,23 +5838,27 @@ func_mode_link ()
arg="$func_quote_for_eval_result"
;;
- # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
- # -r[0-9][0-9]* specifies the processor on the SGI compiler
- # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
- # +DA*, +DD* enable 64-bit mode on the HP compiler
- # -q* pass through compiler args for the IBM compiler
- # -m*, -t[45]*, -txscale* pass through architecture-specific
- # compiler args for GCC
- # -F/path gives path to uninstalled frameworks, gcc on darwin
- # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
- # @file GCC response files
+ # Flags to be passed through unchanged, with rationale:
+ # -64, -mips[0-9] enable 64-bit mode for the SGI compiler
+ # -r[0-9][0-9]* specify processor for the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+ # +DA*, +DD* enable 64-bit mode for the HP compiler
+ # -q* compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+ # -F/path path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* profiling flags for GCC
+ # @file GCC response files
+ # -tp=* Portland pgcc target processor selection
+ # --sysroot=* for sysroot support
+ # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
-64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
- -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
func_quote_for_eval "$arg"
arg="$func_quote_for_eval_result"
func_append compile_command " $arg"
func_append finalize_command " $arg"
- compiler_flags="$compiler_flags $arg"
+ func_append compiler_flags " $arg"
continue
;;
@@ -4255,7 +5870,7 @@ func_mode_link ()
*.$objext)
# A standard object.
- objs="$objs $arg"
+ func_append objs " $arg"
;;
*.lo)
@@ -4286,7 +5901,7 @@ func_mode_link ()
if test "$prev" = dlfiles; then
if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
- dlfiles="$dlfiles $pic_object"
+ func_append dlfiles " $pic_object"
prev=
continue
else
@@ -4298,7 +5913,7 @@ func_mode_link ()
# CHECK ME: I think I busted this. -Ossama
if test "$prev" = dlprefiles; then
# Preload the old-style object.
- dlprefiles="$dlprefiles $pic_object"
+ func_append dlprefiles " $pic_object"
prev=
fi
@@ -4343,24 +5958,25 @@ func_mode_link ()
*.$libext)
# An archive.
- deplibs="$deplibs $arg"
- old_deplibs="$old_deplibs $arg"
+ func_append deplibs " $arg"
+ func_append old_deplibs " $arg"
continue
;;
*.la)
# A libtool-controlled library.
+ func_resolve_sysroot "$arg"
if test "$prev" = dlfiles; then
# This library was specified with -dlopen.
- dlfiles="$dlfiles $arg"
+ func_append dlfiles " $func_resolve_sysroot_result"
prev=
elif test "$prev" = dlprefiles; then
# The library was specified with -dlpreopen.
- dlprefiles="$dlprefiles $arg"
+ func_append dlprefiles " $func_resolve_sysroot_result"
prev=
else
- deplibs="$deplibs $arg"
+ func_append deplibs " $func_resolve_sysroot_result"
fi
continue
;;
@@ -4398,7 +6014,7 @@ func_mode_link ()
if test -n "$shlibpath_var"; then
# get the directories listed in $shlibpath_var
- eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+ eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
else
shlib_search_path=
fi
@@ -4407,6 +6023,8 @@ func_mode_link ()
func_dirname "$output" "/" ""
output_objdir="$func_dirname_result$objdir"
+ func_to_tool_file "$output_objdir/"
+ tool_output_objdir=$func_to_tool_file_result
# Create the object directory.
func_mkdir_p "$output_objdir"
@@ -4427,12 +6045,12 @@ func_mode_link ()
# Find all interdependent deplibs by searching for libraries
# that are linked more than once (e.g. -la -lb -la)
for deplib in $deplibs; do
- if $opt_duplicate_deps ; then
+ if $opt_preserve_dup_deps ; then
case "$libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
esac
fi
- libs="$libs $deplib"
+ func_append libs " $deplib"
done
if test "$linkmode" = lib; then
@@ -4445,9 +6063,9 @@ func_mode_link ()
if $opt_duplicate_compiler_generated_deps; then
for pre_post_dep in $predeps $postdeps; do
case "$pre_post_deps " in
- *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+ *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
esac
- pre_post_deps="$pre_post_deps $pre_post_dep"
+ func_append pre_post_deps " $pre_post_dep"
done
fi
pre_post_deps=
@@ -4506,7 +6124,10 @@ func_mode_link ()
case $pass in
dlopen) libs="$dlfiles" ;;
dlpreopen) libs="$dlprefiles" ;;
- link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ link)
+ libs="$deplibs %DEPLIBS%"
+ test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+ ;;
esac
fi
if test "$linkmode,$pass" = "lib,dlpreopen"; then
@@ -4514,17 +6135,19 @@ func_mode_link ()
for lib in $dlprefiles; do
# Ignore non-libtool-libs
dependency_libs=
+ func_resolve_sysroot "$lib"
case $lib in
- *.la) func_source "$lib" ;;
+ *.la) func_source "$func_resolve_sysroot_result" ;;
esac
# Collect preopened libtool deplibs, except any this library
# has declared as weak libs
for deplib in $dependency_libs; do
- deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"`
+ func_basename "$deplib"
+ deplib_base=$func_basename_result
case " $weak_libs " in
*" $deplib_base "*) ;;
- *) deplibs="$deplibs $deplib" ;;
+ *) func_append deplibs " $deplib" ;;
esac
done
done
@@ -4540,16 +6163,17 @@ func_mode_link ()
lib=
found=no
case $deplib in
- -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
if test "$linkmode,$pass" = "prog,link"; then
compile_deplibs="$deplib $compile_deplibs"
finalize_deplibs="$deplib $finalize_deplibs"
else
- compiler_flags="$compiler_flags $deplib"
+ func_append compiler_flags " $deplib"
if test "$linkmode" = lib ; then
case "$new_inherited_linker_flags " in
*" $deplib "*) ;;
- * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
esac
fi
fi
@@ -4634,7 +6258,7 @@ func_mode_link ()
if test "$linkmode" = lib ; then
case "$new_inherited_linker_flags " in
*" $deplib "*) ;;
- * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
esac
fi
fi
@@ -4647,7 +6271,8 @@ func_mode_link ()
test "$pass" = conv && continue
newdependency_libs="$deplib $newdependency_libs"
func_stripname '-L' '' "$deplib"
- newlib_search_path="$newlib_search_path $func_stripname_result"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
;;
prog)
if test "$pass" = conv; then
@@ -4661,7 +6286,8 @@ func_mode_link ()
finalize_deplibs="$deplib $finalize_deplibs"
fi
func_stripname '-L' '' "$deplib"
- newlib_search_path="$newlib_search_path $func_stripname_result"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
;;
*)
func_warning "\`-L' is ignored for archives/objects"
@@ -4672,17 +6298,21 @@ func_mode_link ()
-R*)
if test "$pass" = link; then
func_stripname '-R' '' "$deplib"
- dir=$func_stripname_result
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
# Make sure the xrpath contains only unique directories.
case "$xrpath " in
*" $dir "*) ;;
- *) xrpath="$xrpath $dir" ;;
+ *) func_append xrpath " $dir" ;;
esac
fi
deplibs="$deplib $deplibs"
continue
;;
- *.la) lib="$deplib" ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ lib=$func_resolve_sysroot_result
+ ;;
*.$libext)
if test "$pass" = conv; then
deplibs="$deplib $deplibs"
@@ -4700,7 +6330,7 @@ func_mode_link ()
match_pattern*)
set dummy $deplibs_check_method; shift
match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
- if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \
+ if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
| $EGREP "$match_pattern_regex" > /dev/null; then
valid_a_lib=yes
fi
@@ -4710,15 +6340,15 @@ func_mode_link ()
;;
esac
if test "$valid_a_lib" != yes; then
- $ECHO
+ echo
$ECHO "*** Warning: Trying to link with static lib archive $deplib."
- $ECHO "*** I have the capability to make that library automatically link in when"
- $ECHO "*** you link to this library. But I can only do this if you have a"
- $ECHO "*** shared version of the library, which you do not appear to have"
- $ECHO "*** because the file extensions .$libext of this argument makes me believe"
- $ECHO "*** that it is just a static archive that I should not use here."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not use here."
else
- $ECHO
+ echo
$ECHO "*** Warning: Linking the shared library $output against the"
$ECHO "*** static library $deplib is not portable!"
deplibs="$deplib $deplibs"
@@ -4745,11 +6375,11 @@ func_mode_link ()
if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
# If there is no dlopen support or we're linking statically,
# we need to preload.
- newdlprefiles="$newdlprefiles $deplib"
+ func_append newdlprefiles " $deplib"
compile_deplibs="$deplib $compile_deplibs"
finalize_deplibs="$deplib $finalize_deplibs"
else
- newdlfiles="$newdlfiles $deplib"
+ func_append newdlfiles " $deplib"
fi
fi
continue
@@ -4791,20 +6421,20 @@ func_mode_link ()
# Convert "-framework foo" to "foo.ltframework"
if test -n "$inherited_linker_flags"; then
- tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
case " $new_inherited_linker_flags " in
*" $tmp_inherited_linker_flag "*) ;;
- *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";;
+ *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
esac
done
fi
- dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
if test "$linkmode,$pass" = "lib,link" ||
test "$linkmode,$pass" = "prog,scan" ||
{ test "$linkmode" != prog && test "$linkmode" != lib; }; then
- test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
- test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+ test -n "$dlopen" && func_append dlfiles " $dlopen"
+ test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
fi
if test "$pass" = conv; then
@@ -4815,30 +6445,36 @@ func_mode_link ()
func_fatal_error "cannot find name of link library for \`$lib'"
fi
# It is a libtool convenience library, so add in its objects.
- convenience="$convenience $ladir/$objdir/$old_library"
- old_convenience="$old_convenience $ladir/$objdir/$old_library"
+ func_append convenience " $ladir/$objdir/$old_library"
+ func_append old_convenience " $ladir/$objdir/$old_library"
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
elif test "$linkmode" != prog && test "$linkmode" != lib; then
func_fatal_error "\`$lib' is not a convenience library"
fi
- tmp_libs=
- for deplib in $dependency_libs; do
- deplibs="$deplib $deplibs"
- if $opt_duplicate_deps ; then
- case "$tmp_libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
- esac
- fi
- tmp_libs="$tmp_libs $deplib"
- done
continue
fi # $pass = conv
# Get the name of the library we link against.
linklib=
- for l in $old_library $library_names; do
- linklib="$l"
- done
+ if test -n "$old_library" &&
+ { test "$prefer_static_libs" = yes ||
+ test "$prefer_static_libs,$installed" = "built,no"; }; then
+ linklib=$old_library
+ else
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ fi
if test -z "$linklib"; then
func_fatal_error "cannot find name of link library for \`$lib'"
fi
@@ -4855,9 +6491,9 @@ func_mode_link ()
# statically, we need to preload. We also need to preload any
# dependent libraries so libltdl's deplib preloader doesn't
# bomb out in the load deplibs phase.
- dlprefiles="$dlprefiles $lib $dependency_libs"
+ func_append dlprefiles " $lib $dependency_libs"
else
- newdlfiles="$newdlfiles $lib"
+ func_append newdlfiles " $lib"
fi
continue
fi # $pass = dlopen
@@ -4879,14 +6515,14 @@ func_mode_link ()
# Find the relevant object directory and library name.
if test "X$installed" = Xyes; then
- if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
func_warning "library \`$lib' was moved."
dir="$ladir"
absdir="$abs_ladir"
libdir="$abs_ladir"
else
- dir="$libdir"
- absdir="$libdir"
+ dir="$lt_sysroot$libdir"
+ absdir="$lt_sysroot$libdir"
fi
test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
else
@@ -4894,12 +6530,12 @@ func_mode_link ()
dir="$ladir"
absdir="$abs_ladir"
# Remove this search path later
- notinst_path="$notinst_path $abs_ladir"
+ func_append notinst_path " $abs_ladir"
else
dir="$ladir/$objdir"
absdir="$abs_ladir/$objdir"
# Remove this search path later
- notinst_path="$notinst_path $abs_ladir"
+ func_append notinst_path " $abs_ladir"
fi
fi # $installed = yes
func_stripname 'lib' '.la' "$laname"
@@ -4910,20 +6546,46 @@ func_mode_link ()
if test -z "$libdir" && test "$linkmode" = prog; then
func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
fi
- # Prefer using a static library (so that no silly _DYNAMIC symbols
- # are required to link).
- if test -n "$old_library"; then
- newdlprefiles="$newdlprefiles $dir/$old_library"
- # Keep a list of preopened convenience libraries to check
- # that they are being used correctly in the link pass.
- test -z "$libdir" && \
- dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
- # Otherwise, use the dlname, so that lt_dlopen finds it.
- elif test -n "$dlname"; then
- newdlprefiles="$newdlprefiles $dir/$dlname"
- else
- newdlprefiles="$newdlprefiles $dir/$linklib"
- fi
+ case "$host" in
+ # special handling for platforms with PE-DLLs.
+ *cygwin* | *mingw* | *cegcc* )
+ # Linker will automatically link against shared library if both
+ # static and shared are present. Therefore, ensure we extract
+ # symbols from the import library if a shared library is present
+ # (otherwise, the dlopen module name will be incorrect). We do
+ # this by putting the import library name into $newdlprefiles.
+ # We recover the dlopen module name by 'saving' the la file
+ # name in a special purpose variable, and (later) extracting the
+ # dlname from the la file.
+ if test -n "$dlname"; then
+ func_tr_sh "$dir/$linklib"
+ eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+ func_append newdlprefiles " $dir/$linklib"
+ else
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ fi
+ ;;
+ * )
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ func_append newdlprefiles " $dir/$dlname"
+ else
+ func_append newdlprefiles " $dir/$linklib"
+ fi
+ ;;
+ esac
fi # $pass = dlpreopen
if test -z "$libdir"; then
@@ -4941,7 +6603,7 @@ func_mode_link ()
if test "$linkmode" = prog && test "$pass" != link; then
- newlib_search_path="$newlib_search_path $ladir"
+ func_append newlib_search_path " $ladir"
deplibs="$lib $deplibs"
linkalldeplibs=no
@@ -4954,7 +6616,8 @@ func_mode_link ()
for deplib in $dependency_libs; do
case $deplib in
-L*) func_stripname '-L' '' "$deplib"
- newlib_search_path="$newlib_search_path $func_stripname_result"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
;;
esac
# Need to link against all dependency_libs?
@@ -4965,12 +6628,12 @@ func_mode_link ()
# or/and link against static libraries
newdependency_libs="$deplib $newdependency_libs"
fi
- if $opt_duplicate_deps ; then
+ if $opt_preserve_dup_deps ; then
case "$tmp_libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
esac
fi
- tmp_libs="$tmp_libs $deplib"
+ func_append tmp_libs " $deplib"
done # for deplib
continue
fi # $linkmode = prog...
@@ -4985,7 +6648,7 @@ func_mode_link ()
# Make sure the rpath contains only unique directories.
case "$temp_rpath:" in
*"$absdir:"*) ;;
- *) temp_rpath="$temp_rpath$absdir:" ;;
+ *) func_append temp_rpath "$absdir:" ;;
esac
fi
@@ -4997,7 +6660,7 @@ func_mode_link ()
*)
case "$compile_rpath " in
*" $absdir "*) ;;
- *) compile_rpath="$compile_rpath $absdir"
+ *) func_append compile_rpath " $absdir" ;;
esac
;;
esac
@@ -5006,7 +6669,7 @@ func_mode_link ()
*)
case "$finalize_rpath " in
*" $libdir "*) ;;
- *) finalize_rpath="$finalize_rpath $libdir"
+ *) func_append finalize_rpath " $libdir" ;;
esac
;;
esac
@@ -5029,14 +6692,14 @@ func_mode_link ()
if test -n "$library_names" &&
{ test "$use_static_libs" = no || test -z "$old_library"; }; then
case $host in
- *cygwin* | *mingw*)
+ *cygwin* | *mingw* | *cegcc*)
# No point in relinking DLLs because paths are not encoded
- notinst_deplibs="$notinst_deplibs $lib"
+ func_append notinst_deplibs " $lib"
need_relink=no
;;
*)
if test "$installed" = no; then
- notinst_deplibs="$notinst_deplibs $lib"
+ func_append notinst_deplibs " $lib"
need_relink=yes
fi
;;
@@ -5053,7 +6716,7 @@ func_mode_link ()
fi
done
if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
- $ECHO
+ echo
if test "$linkmode" = prog; then
$ECHO "*** Warning: Linking the executable $output against the loadable module"
else
@@ -5071,7 +6734,7 @@ func_mode_link ()
*)
case "$compile_rpath " in
*" $absdir "*) ;;
- *) compile_rpath="$compile_rpath $absdir"
+ *) func_append compile_rpath " $absdir" ;;
esac
;;
esac
@@ -5080,7 +6743,7 @@ func_mode_link ()
*)
case "$finalize_rpath " in
*" $libdir "*) ;;
- *) finalize_rpath="$finalize_rpath $libdir"
+ *) func_append finalize_rpath " $libdir" ;;
esac
;;
esac
@@ -5099,7 +6762,7 @@ func_mode_link ()
elif test -n "$soname_spec"; then
# bleh windows
case $host in
- *cygwin* | mingw*)
+ *cygwin* | mingw* | *cegcc*)
func_arith $current - $age
major=$func_arith_result
versuffix="-$major"
@@ -5134,7 +6797,7 @@ func_mode_link ()
linklib=$newlib
fi # test -n "$old_archive_from_expsyms_cmds"
- if test "$linkmode" = prog || test "$mode" != relink; then
+ if test "$linkmode" = prog || test "$opt_mode" != relink; then
add_shlibpath=
add_dir=
add=
@@ -5156,9 +6819,9 @@ func_mode_link ()
if test "X$dlopenmodule" != "X$lib"; then
$ECHO "*** Warning: lib $linklib is a module, not a shared library"
if test -z "$old_library" ; then
- $ECHO
- $ECHO "*** And there doesn't seem to be a static archive available"
- $ECHO "*** The link will probably fail, sorry"
+ echo
+ echo "*** And there doesn't seem to be a static archive available"
+ echo "*** The link will probably fail, sorry"
else
add="$dir/$old_library"
fi
@@ -5185,12 +6848,12 @@ func_mode_link ()
test "$hardcode_direct_absolute" = no; then
add="$dir/$linklib"
elif test "$hardcode_minus_L" = yes; then
- add_dir="-L$dir"
+ add_dir="-L$absdir"
# Try looking first in the location we're being installed to.
if test -n "$inst_prefix_dir"; then
case $libdir in
[\\/]*)
- add_dir="$add_dir -L$inst_prefix_dir$libdir"
+ func_append add_dir " -L$inst_prefix_dir$libdir"
;;
esac
fi
@@ -5212,7 +6875,7 @@ func_mode_link ()
if test -n "$add_shlibpath"; then
case :$compile_shlibpath: in
*":$add_shlibpath:"*) ;;
- *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+ *) func_append compile_shlibpath "$add_shlibpath:" ;;
esac
fi
if test "$linkmode" = prog; then
@@ -5226,13 +6889,13 @@ func_mode_link ()
test "$hardcode_shlibpath_var" = yes; then
case :$finalize_shlibpath: in
*":$libdir:"*) ;;
- *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
esac
fi
fi
fi
- if test "$linkmode" = prog || test "$mode" = relink; then
+ if test "$linkmode" = prog || test "$opt_mode" = relink; then
add_shlibpath=
add_dir=
add=
@@ -5246,7 +6909,7 @@ func_mode_link ()
elif test "$hardcode_shlibpath_var" = yes; then
case :$finalize_shlibpath: in
*":$libdir:"*) ;;
- *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
esac
add="-l$name"
elif test "$hardcode_automatic" = yes; then
@@ -5263,7 +6926,7 @@ func_mode_link ()
if test -n "$inst_prefix_dir"; then
case $libdir in
[\\/]*)
- add_dir="$add_dir -L$inst_prefix_dir$libdir"
+ func_append add_dir " -L$inst_prefix_dir$libdir"
;;
esac
fi
@@ -5298,21 +6961,21 @@ func_mode_link ()
# Just print a warning and add the library to dependency_libs so
# that the program can be linked against the static library.
- $ECHO
+ echo
$ECHO "*** Warning: This system can not link to static lib archive $lib."
- $ECHO "*** I have the capability to make that library automatically link in when"
- $ECHO "*** you link to this library. But I can only do this if you have a"
- $ECHO "*** shared version of the library, which you do not appear to have."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
if test "$module" = yes; then
- $ECHO "*** But as you try to build a module library, libtool will still create "
- $ECHO "*** a static module, that should work as long as the dlopening application"
- $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
if test -z "$global_symbol_pipe"; then
- $ECHO
- $ECHO "*** However, this would only work if libtool was able to extract symbol"
- $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
- $ECHO "*** not find such a program. So, this module is probably useless."
- $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
fi
if test "$build_old_libs" = no; then
build_libtool_libs=module
@@ -5340,37 +7003,46 @@ func_mode_link ()
temp_xrpath=$func_stripname_result
case " $xrpath " in
*" $temp_xrpath "*) ;;
- *) xrpath="$xrpath $temp_xrpath";;
+ *) func_append xrpath " $temp_xrpath";;
esac;;
- *) temp_deplibs="$temp_deplibs $libdir";;
+ *) func_append temp_deplibs " $libdir";;
esac
done
dependency_libs="$temp_deplibs"
fi
- newlib_search_path="$newlib_search_path $absdir"
+ func_append newlib_search_path " $absdir"
# Link against this library
test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
# ... and its dependency_libs
tmp_libs=
for deplib in $dependency_libs; do
newdependency_libs="$deplib $newdependency_libs"
- if $opt_duplicate_deps ; then
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result";;
+ *) func_resolve_sysroot "$deplib" ;;
+ esac
+ if $opt_preserve_dup_deps ; then
case "$tmp_libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ *" $func_resolve_sysroot_result "*)
+ func_append specialdeplibs " $func_resolve_sysroot_result" ;;
esac
fi
- tmp_libs="$tmp_libs $deplib"
+ func_append tmp_libs " $func_resolve_sysroot_result"
done
if test "$link_all_deplibs" != no; then
# Add the search paths of all dependency libraries
for deplib in $dependency_libs; do
+ path=
case $deplib in
-L*) path="$deplib" ;;
*.la)
+ func_resolve_sysroot "$deplib"
+ deplib=$func_resolve_sysroot_result
func_dirname "$deplib" "" "."
- dir="$func_dirname_result"
+ dir=$func_dirname_result
# We need an absolute path.
case $dir in
[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
@@ -5397,8 +7069,8 @@ func_mode_link ()
if test -z "$darwin_install_name"; then
darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
fi
- compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
- linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}"
+ func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+ func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
path=
fi
fi
@@ -5431,7 +7103,7 @@ func_mode_link ()
compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
else
- compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
fi
fi
dependency_libs="$newdependency_libs"
@@ -5448,7 +7120,7 @@ func_mode_link ()
for dir in $newlib_search_path; do
case "$lib_search_path " in
*" $dir "*) ;;
- *) lib_search_path="$lib_search_path $dir" ;;
+ *) func_append lib_search_path " $dir" ;;
esac
done
newlib_search_path=
@@ -5506,10 +7178,10 @@ func_mode_link ()
-L*)
case " $tmp_libs " in
*" $deplib "*) ;;
- *) tmp_libs="$tmp_libs $deplib" ;;
+ *) func_append tmp_libs " $deplib" ;;
esac
;;
- *) tmp_libs="$tmp_libs $deplib" ;;
+ *) func_append tmp_libs " $deplib" ;;
esac
done
eval $var=\"$tmp_libs\"
@@ -5525,7 +7197,7 @@ func_mode_link ()
;;
esac
if test -n "$i" ; then
- tmp_libs="$tmp_libs $i"
+ func_append tmp_libs " $i"
fi
done
dependency_libs=$tmp_libs
@@ -5566,7 +7238,7 @@ func_mode_link ()
# Now set the variables for building old libraries.
build_libtool_libs=no
oldlibs="$output"
- objs="$objs$old_deplibs"
+ func_append objs "$old_deplibs"
;;
lib)
@@ -5599,10 +7271,10 @@ func_mode_link ()
if test "$deplibs_check_method" != pass_all; then
func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
else
- $ECHO
+ echo
$ECHO "*** Warning: Linking the shared library $output against the non-libtool"
$ECHO "*** objects $objs is not portable!"
- libobjs="$libobjs $objs"
+ func_append libobjs " $objs"
fi
fi
@@ -5661,13 +7333,14 @@ func_mode_link ()
# which has an extra 1 added just for fun
#
case $version_type in
+ # correct linux to gnu/linux during the next big refactor
darwin|linux|osf|windows|none)
func_arith $number_major + $number_minor
current=$func_arith_result
age="$number_minor"
revision="$number_revision"
;;
- freebsd-aout|freebsd-elf|sunos)
+ freebsd-aout|freebsd-elf|qnx|sunos)
current="$number_major"
revision="$number_minor"
age="0"
@@ -5679,6 +7352,9 @@ func_mode_link ()
revision="$number_minor"
lt_irix_increment=no
;;
+ *)
+ func_fatal_configuration "$modename: unknown library version type \`$version_type'"
+ ;;
esac
;;
no)
@@ -5777,7 +7453,7 @@ func_mode_link ()
versuffix="$major.$revision"
;;
- linux)
+ linux) # correct to gnu/linux during the next big refactor
func_arith $current - $age
major=.$func_arith_result
versuffix="$major.$age.$revision"
@@ -5800,7 +7476,7 @@ func_mode_link ()
done
# Make executables depend on our current version.
- verstring="$verstring:${current}.0"
+ func_append verstring ":${current}.0"
;;
qnx)
@@ -5868,17 +7544,17 @@ func_mode_link ()
fi
func_generate_dlsyms "$libname" "$libname" "yes"
- libobjs="$libobjs $symfileobj"
+ func_append libobjs " $symfileobj"
test "X$libobjs" = "X " && libobjs=
- if test "$mode" != relink; then
+ if test "$opt_mode" != relink; then
# Remove our outputs, but don't remove object files since they
# may have been created when compiling PIC objects.
removelist=
tempremovelist=`$ECHO "$output_objdir/*"`
for p in $tempremovelist; do
case $p in
- *.$objext)
+ *.$objext | *.gcno)
;;
$output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
if test "X$precious_files_regex" != "X"; then
@@ -5887,7 +7563,7 @@ func_mode_link ()
continue
fi
fi
- removelist="$removelist $p"
+ func_append removelist " $p"
;;
*) ;;
esac
@@ -5898,27 +7574,28 @@ func_mode_link ()
# Now set the variables for building old libraries.
if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
- oldlibs="$oldlibs $output_objdir/$libname.$libext"
+ func_append oldlibs " $output_objdir/$libname.$libext"
# Transform .lo files to .o files.
- oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
fi
# Eliminate all temporary directories.
#for path in $notinst_path; do
- # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"`
- # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"`
- # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"`
+ # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+ # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
#done
if test -n "$xrpath"; then
# If the user specified any rpath flags, then add them.
temp_xrpath=
for libdir in $xrpath; do
- temp_xrpath="$temp_xrpath -R$libdir"
+ func_replace_sysroot "$libdir"
+ func_append temp_xrpath " -R$func_replace_sysroot_result"
case "$finalize_rpath " in
*" $libdir "*) ;;
- *) finalize_rpath="$finalize_rpath $libdir" ;;
+ *) func_append finalize_rpath " $libdir" ;;
esac
done
if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
@@ -5932,7 +7609,7 @@ func_mode_link ()
for lib in $old_dlfiles; do
case " $dlprefiles $dlfiles " in
*" $lib "*) ;;
- *) dlfiles="$dlfiles $lib" ;;
+ *) func_append dlfiles " $lib" ;;
esac
done
@@ -5942,19 +7619,19 @@ func_mode_link ()
for lib in $old_dlprefiles; do
case "$dlprefiles " in
*" $lib "*) ;;
- *) dlprefiles="$dlprefiles $lib" ;;
+ *) func_append dlprefiles " $lib" ;;
esac
done
if test "$build_libtool_libs" = yes; then
if test -n "$rpath"; then
case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
# these systems don't actually have a c library (as such)!
;;
*-*-rhapsody* | *-*-darwin1.[012])
# Rhapsody C library is in the System framework
- deplibs="$deplibs System.ltframework"
+ func_append deplibs " System.ltframework"
;;
*-*-netbsd*)
# Don't link with libc until the a.out ld.so is fixed.
@@ -5971,7 +7648,7 @@ func_mode_link ()
*)
# Add libc to deplibs on all other systems if necessary.
if test "$build_libtool_need_lc" = "yes"; then
- deplibs="$deplibs -lc"
+ func_append deplibs " -lc"
fi
;;
esac
@@ -6020,7 +7697,7 @@ EOF
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
case " $predeps $postdeps " in
*" $i "*)
- newdeplibs="$newdeplibs $i"
+ func_append newdeplibs " $i"
i=""
;;
esac
@@ -6031,21 +7708,21 @@ EOF
set dummy $deplib_matches; shift
deplib_match=$1
if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
- newdeplibs="$newdeplibs $i"
+ func_append newdeplibs " $i"
else
droppeddeps=yes
- $ECHO
+ echo
$ECHO "*** Warning: dynamic linker does not accept needed library $i."
- $ECHO "*** I have the capability to make that library automatically link in when"
- $ECHO "*** you link to this library. But I can only do this if you have a"
- $ECHO "*** shared version of the library, which I believe you do not have"
- $ECHO "*** because a test_compile did reveal that the linker did not use it for"
- $ECHO "*** its dynamic dependency list that programs get resolved with at runtime."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
fi
fi
;;
*)
- newdeplibs="$newdeplibs $i"
+ func_append newdeplibs " $i"
;;
esac
done
@@ -6063,7 +7740,7 @@ EOF
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
case " $predeps $postdeps " in
*" $i "*)
- newdeplibs="$newdeplibs $i"
+ func_append newdeplibs " $i"
i=""
;;
esac
@@ -6074,29 +7751,29 @@ EOF
set dummy $deplib_matches; shift
deplib_match=$1
if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
- newdeplibs="$newdeplibs $i"
+ func_append newdeplibs " $i"
else
droppeddeps=yes
- $ECHO
+ echo
$ECHO "*** Warning: dynamic linker does not accept needed library $i."
- $ECHO "*** I have the capability to make that library automatically link in when"
- $ECHO "*** you link to this library. But I can only do this if you have a"
- $ECHO "*** shared version of the library, which you do not appear to have"
- $ECHO "*** because a test_compile did reveal that the linker did not use this one"
- $ECHO "*** as a dynamic dependency that programs can get resolved with at runtime."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
fi
fi
else
droppeddeps=yes
- $ECHO
+ echo
$ECHO "*** Warning! Library $i is needed by this library but I was not able to"
- $ECHO "*** make it link in! You will probably need to install it or some"
- $ECHO "*** library that it depends on before this library will be fully"
- $ECHO "*** functional. Installing it before continuing would be even better."
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
fi
;;
*)
- newdeplibs="$newdeplibs $i"
+ func_append newdeplibs " $i"
;;
esac
done
@@ -6113,15 +7790,27 @@ EOF
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
case " $predeps $postdeps " in
*" $a_deplib "*)
- newdeplibs="$newdeplibs $a_deplib"
+ func_append newdeplibs " $a_deplib"
a_deplib=""
;;
esac
fi
if test -n "$a_deplib" ; then
libname=`eval "\\$ECHO \"$libname_spec\""`
+ if test -n "$file_magic_glob"; then
+ libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+ else
+ libnameglob=$libname
+ fi
+ test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
- potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ if test "$want_nocaseglob" = yes; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
for potent_lib in $potential_libs; do
# Follow soft links.
if ls -lLd "$potent_lib" 2>/dev/null |
@@ -6138,13 +7827,13 @@ EOF
potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
case $potliblink in
[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
- *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+ *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
esac
done
if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
$SED -e 10q |
$EGREP "$file_magic_regex" > /dev/null; then
- newdeplibs="$newdeplibs $a_deplib"
+ func_append newdeplibs " $a_deplib"
a_deplib=""
break 2
fi
@@ -6153,12 +7842,12 @@ EOF
fi
if test -n "$a_deplib" ; then
droppeddeps=yes
- $ECHO
+ echo
$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
- $ECHO "*** I have the capability to make that library automatically link in when"
- $ECHO "*** you link to this library. But I can only do this if you have a"
- $ECHO "*** shared version of the library, which you do not appear to have"
- $ECHO "*** because I did check the linker path looking for a file starting"
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
if test -z "$potlib" ; then
$ECHO "*** with $libname but no candidates were found. (...for file magic test)"
else
@@ -6169,7 +7858,7 @@ EOF
;;
*)
# Add a -L argument.
- newdeplibs="$newdeplibs $a_deplib"
+ func_append newdeplibs " $a_deplib"
;;
esac
done # Gone through all deplibs.
@@ -6185,7 +7874,7 @@ EOF
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
case " $predeps $postdeps " in
*" $a_deplib "*)
- newdeplibs="$newdeplibs $a_deplib"
+ func_append newdeplibs " $a_deplib"
a_deplib=""
;;
esac
@@ -6196,9 +7885,9 @@ EOF
potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
for potent_lib in $potential_libs; do
potlib="$potent_lib" # see symlink-check above in file_magic test
- if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \
+ if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
$EGREP "$match_pattern_regex" > /dev/null; then
- newdeplibs="$newdeplibs $a_deplib"
+ func_append newdeplibs " $a_deplib"
a_deplib=""
break 2
fi
@@ -6207,12 +7896,12 @@ EOF
fi
if test -n "$a_deplib" ; then
droppeddeps=yes
- $ECHO
+ echo
$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
- $ECHO "*** I have the capability to make that library automatically link in when"
- $ECHO "*** you link to this library. But I can only do this if you have a"
- $ECHO "*** shared version of the library, which you do not appear to have"
- $ECHO "*** because I did check the linker path looking for a file starting"
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
if test -z "$potlib" ; then
$ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
else
@@ -6223,32 +7912,32 @@ EOF
;;
*)
# Add a -L argument.
- newdeplibs="$newdeplibs $a_deplib"
+ func_append newdeplibs " $a_deplib"
;;
esac
done # Gone through all deplibs.
;;
none | unknown | *)
newdeplibs=""
- tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \
- -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'`
+ tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
for i in $predeps $postdeps ; do
# can't use Xsed below, because $i might contain '/'
- tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"`
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
done
fi
- if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' |
- $GREP . >/dev/null; then
- $ECHO
+ case $tmp_deplibs in
+ *[!\ \ ]*)
+ echo
if test "X$deplibs_check_method" = "Xnone"; then
- $ECHO "*** Warning: inter-library dependencies are not supported in this platform."
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
else
- $ECHO "*** Warning: inter-library dependencies are not known to be supported."
+ echo "*** Warning: inter-library dependencies are not known to be supported."
fi
- $ECHO "*** All declared inter-library dependencies are being dropped."
+ echo "*** All declared inter-library dependencies are being dropped."
droppeddeps=yes
- fi
+ ;;
+ esac
;;
esac
versuffix=$versuffix_save
@@ -6260,23 +7949,23 @@ EOF
case $host in
*-*-rhapsody* | *-*-darwin1.[012])
# On Rhapsody replace the C library with the System framework
- newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
;;
esac
if test "$droppeddeps" = yes; then
if test "$module" = yes; then
- $ECHO
- $ECHO "*** Warning: libtool could not satisfy all declared inter-library"
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
$ECHO "*** dependencies of module $libname. Therefore, libtool will create"
- $ECHO "*** a static module, that should work as long as the dlopening"
- $ECHO "*** application is linked with the -dlopen flag."
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
if test -z "$global_symbol_pipe"; then
- $ECHO
- $ECHO "*** However, this would only work if libtool was able to extract symbol"
- $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
- $ECHO "*** not find such a program. So, this module is probably useless."
- $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
fi
if test "$build_old_libs" = no; then
oldlibs="$output_objdir/$libname.$libext"
@@ -6286,16 +7975,16 @@ EOF
build_libtool_libs=no
fi
else
- $ECHO "*** The inter-library dependencies that have been dropped here will be"
- $ECHO "*** automatically added whenever a program is linked with this library"
- $ECHO "*** or is declared to -dlopen it."
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
if test "$allow_undefined" = no; then
- $ECHO
- $ECHO "*** Since this library must not contain undefined symbols,"
- $ECHO "*** because either the platform does not support them or"
- $ECHO "*** it was explicitly requested with -no-undefined,"
- $ECHO "*** libtool will only create a static version of it."
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
if test "$build_old_libs" = no; then
oldlibs="$output_objdir/$libname.$libext"
build_libtool_libs=module
@@ -6312,9 +8001,9 @@ EOF
# Time to change all our "foo.ltframework" stuff back to "-framework foo"
case $host in
*-*-darwin*)
- newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
- new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
- deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
;;
esac
@@ -6327,7 +8016,7 @@ EOF
*)
case " $deplibs " in
*" -L$path/$objdir "*)
- new_libs="$new_libs -L$path/$objdir" ;;
+ func_append new_libs " -L$path/$objdir" ;;
esac
;;
esac
@@ -6337,10 +8026,10 @@ EOF
-L*)
case " $new_libs " in
*" $deplib "*) ;;
- *) new_libs="$new_libs $deplib" ;;
+ *) func_append new_libs " $deplib" ;;
esac
;;
- *) new_libs="$new_libs $deplib" ;;
+ *) func_append new_libs " $deplib" ;;
esac
done
deplibs="$new_libs"
@@ -6352,15 +8041,22 @@ EOF
# Test again, we may have decided not to build it any more
if test "$build_libtool_libs" = yes; then
+ # Remove ${wl} instances when linking with ld.
+ # FIXME: should test the right _cmds variable.
+ case $archive_cmds in
+ *\$LD\ *) wl= ;;
+ esac
if test "$hardcode_into_libs" = yes; then
# Hardcode the library paths
hardcode_libdirs=
dep_rpath=
rpath="$finalize_rpath"
- test "$mode" != relink && rpath="$compile_rpath$rpath"
+ test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
for libdir in $rpath; do
if test -n "$hardcode_libdir_flag_spec"; then
if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
if test -z "$hardcode_libdirs"; then
hardcode_libdirs="$libdir"
else
@@ -6369,18 +8065,18 @@ EOF
*"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
;;
*)
- hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
;;
esac
fi
else
eval flag=\"$hardcode_libdir_flag_spec\"
- dep_rpath="$dep_rpath $flag"
+ func_append dep_rpath " $flag"
fi
elif test -n "$runpath_var"; then
case "$perm_rpath " in
*" $libdir "*) ;;
- *) perm_rpath="$perm_rpath $libdir" ;;
+ *) func_append perm_rpath " $libdir" ;;
esac
fi
done
@@ -6388,17 +8084,13 @@ EOF
if test -n "$hardcode_libdir_separator" &&
test -n "$hardcode_libdirs"; then
libdir="$hardcode_libdirs"
- if test -n "$hardcode_libdir_flag_spec_ld"; then
- eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
- else
- eval dep_rpath=\"$hardcode_libdir_flag_spec\"
- fi
+ eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
fi
if test -n "$runpath_var" && test -n "$perm_rpath"; then
# We should set the runpath_var.
rpath=
for dir in $perm_rpath; do
- rpath="$rpath$dir:"
+ func_append rpath "$dir:"
done
eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
fi
@@ -6406,7 +8098,7 @@ EOF
fi
shlibpath="$finalize_shlibpath"
- test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
if test -n "$shlibpath"; then
eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
fi
@@ -6432,23 +8124,23 @@ EOF
linknames=
for link
do
- linknames="$linknames $link"
+ func_append linknames " $link"
done
# Use standard objects if they are pic
- test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
test "X$libobjs" = "X " && libobjs=
delfiles=
if test -n "$export_symbols" && test -n "$include_expsyms"; then
$opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
export_symbols="$output_objdir/$libname.uexp"
- delfiles="$delfiles $export_symbols"
+ func_append delfiles " $export_symbols"
fi
orig_export_symbols=
case $host_os in
- cygwin* | mingw*)
+ cygwin* | mingw* | cegcc*)
if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
# exporting using user supplied symfile
if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
@@ -6474,13 +8166,45 @@ EOF
$opt_dry_run || $RM $export_symbols
cmds=$export_symbols_cmds
save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
+ for cmd1 in $cmds; do
IFS="$save_ifs"
- eval cmd=\"$cmd\"
- func_len " $cmd"
- len=$func_len_result
- if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test "$try_normal_branch" = yes \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=${output_objdir}/${output_la}.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
skipped_export=false
else
# The command line is too long to execute in one step.
@@ -6502,7 +8226,7 @@ EOF
if test -n "$export_symbols" && test -n "$include_expsyms"; then
tmp_export_symbols="$export_symbols"
test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
- $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
fi
if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
@@ -6514,7 +8238,7 @@ EOF
# global variables. join(1) would be nice here, but unfortunately
# isn't a blessed tool.
$opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
- delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
export_symbols=$output_objdir/$libname.def
$opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
fi
@@ -6524,7 +8248,7 @@ EOF
case " $convenience " in
*" $test_deplib "*) ;;
*)
- tmp_deplibs="$tmp_deplibs $test_deplib"
+ func_append tmp_deplibs " $test_deplib"
;;
esac
done
@@ -6544,21 +8268,21 @@ EOF
test "X$libobjs" = "X " && libobjs=
else
gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
+ func_append generated " $gentop"
func_extract_archives $gentop $convenience
- libobjs="$libobjs $func_extract_archives_result"
+ func_append libobjs " $func_extract_archives_result"
test "X$libobjs" = "X " && libobjs=
fi
fi
if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
eval flag=\"$thread_safe_flag_spec\"
- linker_flags="$linker_flags $flag"
+ func_append linker_flags " $flag"
fi
# Make a backup of the uninstalled library when relinking
- if test "$mode" = relink; then
+ if test "$opt_mode" = relink; then
$opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
fi
@@ -6603,7 +8327,8 @@ EOF
save_libobjs=$libobjs
fi
save_output=$output
- output_la=`$ECHO "X$output" | $Xsed -e "$basename"`
+ func_basename "$output"
+ output_la=$func_basename_result
# Clear the reloadable object creation command queue and
# initialize k to one.
@@ -6616,13 +8341,16 @@ EOF
if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
output=${output_objdir}/${output_la}.lnkscript
func_verbose "creating GNU ld script: $output"
- $ECHO 'INPUT (' > $output
+ echo 'INPUT (' > $output
for obj in $save_libobjs
do
- $ECHO "$obj" >> $output
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
done
- $ECHO ')' >> $output
- delfiles="$delfiles $output"
+ echo ')' >> $output
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
output=${output_objdir}/${output_la}.lnk
func_verbose "creating linker input file list: $output"
@@ -6636,10 +8364,12 @@ EOF
fi
for obj
do
- $ECHO "$obj" >> $output
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
done
- delfiles="$delfiles $output"
- output=$firstobj\"$file_list_spec$output\"
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
else
if test -n "$save_libobjs"; then
func_verbose "creating reloadable object files..."
@@ -6663,17 +8393,19 @@ EOF
# command to the queue.
if test "$k" -eq 1 ; then
# The first file doesn't have a previous command to add.
- eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+ reload_objs=$objlist
+ eval concat_cmds=\"$reload_cmds\"
else
# All subsequent reloadable object files will link in
# the last one created.
- eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\"
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
fi
last_robj=$output_objdir/$output_la-${k}.$objext
func_arith $k + 1
k=$func_arith_result
output=$output_objdir/$output_la-${k}.$objext
- objlist=$obj
+ objlist=" $obj"
func_len " $last_robj"
func_arith $len0 + $func_len_result
len=$func_arith_result
@@ -6683,11 +8415,12 @@ EOF
# reloadable object file. All subsequent reloadable object
# files will link in the last one created.
test -z "$concat_cmds" || concat_cmds=$concat_cmds~
- eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
if test -n "$last_robj"; then
eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
fi
- delfiles="$delfiles $output"
+ func_append delfiles " $output"
else
output=
@@ -6721,7 +8454,7 @@ EOF
lt_exit=$?
# Restore the uninstalled library and exit
- if test "$mode" = relink; then
+ if test "$opt_mode" = relink; then
( cd "$output_objdir" && \
$RM "${realname}T" && \
$MV "${realname}U" "$realname" )
@@ -6742,7 +8475,7 @@ EOF
if test -n "$export_symbols" && test -n "$include_expsyms"; then
tmp_export_symbols="$export_symbols"
test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
- $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
fi
if test -n "$orig_export_symbols"; then
@@ -6754,7 +8487,7 @@ EOF
# global variables. join(1) would be nice here, but unfortunately
# isn't a blessed tool.
$opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
- delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
export_symbols=$output_objdir/$libname.def
$opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
fi
@@ -6795,10 +8528,10 @@ EOF
# Add any objects from preloaded convenience libraries
if test -n "$dlprefiles"; then
gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
+ func_append generated " $gentop"
func_extract_archives $gentop $dlprefiles
- libobjs="$libobjs $func_extract_archives_result"
+ func_append libobjs " $func_extract_archives_result"
test "X$libobjs" = "X " && libobjs=
fi
@@ -6814,7 +8547,7 @@ EOF
lt_exit=$?
# Restore the uninstalled library and exit
- if test "$mode" = relink; then
+ if test "$opt_mode" = relink; then
( cd "$output_objdir" && \
$RM "${realname}T" && \
$MV "${realname}U" "$realname" )
@@ -6826,7 +8559,7 @@ EOF
IFS="$save_ifs"
# Restore the uninstalled library and exit
- if test "$mode" = relink; then
+ if test "$opt_mode" = relink; then
$opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
if test -n "$convenience"; then
@@ -6907,18 +8640,21 @@ EOF
if test -n "$convenience"; then
if test -n "$whole_archive_flag_spec"; then
eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
- reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
+ reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
else
gentop="$output_objdir/${obj}x"
- generated="$generated $gentop"
+ func_append generated " $gentop"
func_extract_archives $gentop $convenience
reload_conv_objs="$reload_objs $func_extract_archives_result"
fi
fi
+ # If we're not building shared, we need to use non_pic_objs
+ test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
# Create the old-style object.
- reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+ reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
output="$obj"
func_execute_cmds "$reload_cmds" 'exit $?'
@@ -6978,8 +8714,8 @@ EOF
case $host in
*-*-rhapsody* | *-*-darwin1.[012])
# On Rhapsody replace the C library is the System framework
- compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
- finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
;;
esac
@@ -6990,14 +8726,14 @@ EOF
if test "$tagname" = CXX ; then
case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
10.[0123])
- compile_command="$compile_command ${wl}-bind_at_load"
- finalize_command="$finalize_command ${wl}-bind_at_load"
+ func_append compile_command " ${wl}-bind_at_load"
+ func_append finalize_command " ${wl}-bind_at_load"
;;
esac
fi
# Time to change all our "foo.ltframework" stuff back to "-framework foo"
- compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
- finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
;;
esac
@@ -7011,7 +8747,7 @@ EOF
*)
case " $compile_deplibs " in
*" -L$path/$objdir "*)
- new_libs="$new_libs -L$path/$objdir" ;;
+ func_append new_libs " -L$path/$objdir" ;;
esac
;;
esac
@@ -7021,17 +8757,17 @@ EOF
-L*)
case " $new_libs " in
*" $deplib "*) ;;
- *) new_libs="$new_libs $deplib" ;;
+ *) func_append new_libs " $deplib" ;;
esac
;;
- *) new_libs="$new_libs $deplib" ;;
+ *) func_append new_libs " $deplib" ;;
esac
done
compile_deplibs="$new_libs"
- compile_command="$compile_command $compile_deplibs"
- finalize_command="$finalize_command $finalize_deplibs"
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
if test -n "$rpath$xrpath"; then
# If the user specified any rpath flags, then add them.
@@ -7039,7 +8775,7 @@ EOF
# This is the magic to use -rpath.
case "$finalize_rpath " in
*" $libdir "*) ;;
- *) finalize_rpath="$finalize_rpath $libdir" ;;
+ *) func_append finalize_rpath " $libdir" ;;
esac
done
fi
@@ -7058,30 +8794,32 @@ EOF
*"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
;;
*)
- hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
;;
esac
fi
else
eval flag=\"$hardcode_libdir_flag_spec\"
- rpath="$rpath $flag"
+ func_append rpath " $flag"
fi
elif test -n "$runpath_var"; then
case "$perm_rpath " in
*" $libdir "*) ;;
- *) perm_rpath="$perm_rpath $libdir" ;;
+ *) func_append perm_rpath " $libdir" ;;
esac
fi
case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
case :$dllsearchpath: in
*":$libdir:"*) ;;
- *) dllsearchpath="$dllsearchpath:$libdir";;
+ ::) dllsearchpath=$libdir;;
+ *) func_append dllsearchpath ":$libdir";;
esac
case :$dllsearchpath: in
*":$testbindir:"*) ;;
- *) dllsearchpath="$dllsearchpath:$testbindir";;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
esac
;;
esac
@@ -7107,18 +8845,18 @@ EOF
*"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
;;
*)
- hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
;;
esac
fi
else
eval flag=\"$hardcode_libdir_flag_spec\"
- rpath="$rpath $flag"
+ func_append rpath " $flag"
fi
elif test -n "$runpath_var"; then
case "$finalize_perm_rpath " in
*" $libdir "*) ;;
- *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
esac
fi
done
@@ -7132,8 +8870,8 @@ EOF
if test -n "$libobjs" && test "$build_old_libs" = yes; then
# Transform all the library objects into standard objects.
- compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
- finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
fi
func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
@@ -7145,6 +8883,10 @@ EOF
wrappers_required=yes
case $host in
+ *cegcc* | *mingw32ce*)
+ # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+ wrappers_required=no
+ ;;
*cygwin* | *mingw* )
if test "$build_libtool_libs" != yes; then
wrappers_required=no
@@ -7158,13 +8900,19 @@ EOF
esac
if test "$wrappers_required" = no; then
# Replace the output file specification.
- compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
link_command="$compile_command$compile_rpath"
# We have no uninstalled library dependencies, so finalize right now.
exit_status=0
func_show_eval "$link_command" 'exit_status=$?'
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
# Delete the generated files.
if test -f "$output_objdir/${outputname}S.${objext}"; then
func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
@@ -7187,7 +8935,7 @@ EOF
# We should set the runpath_var.
rpath=
for dir in $perm_rpath; do
- rpath="$rpath$dir:"
+ func_append rpath "$dir:"
done
compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
fi
@@ -7195,7 +8943,7 @@ EOF
# We should set the runpath_var.
rpath=
for dir in $finalize_perm_rpath; do
- rpath="$rpath$dir:"
+ func_append rpath "$dir:"
done
finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
fi
@@ -7205,11 +8953,18 @@ EOF
# We don't need to create a wrapper script.
link_command="$compile_var$compile_command$compile_rpath"
# Replace the output file specification.
- link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
# Delete the old output file.
$opt_dry_run || $RM $output
# Link the executable and exit
func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
exit $EXIT_SUCCESS
fi
@@ -7224,7 +8979,7 @@ EOF
if test "$fast_install" != no; then
link_command="$finalize_var$compile_command$finalize_rpath"
if test "$fast_install" = yes; then
- relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
else
# fast_install is set to needless
relink_command=
@@ -7236,13 +8991,19 @@ EOF
fi
# Replace the output file specification.
- link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
# Delete the old output files.
$opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
func_show_eval "$link_command" 'exit $?'
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
# Now create the wrapper script.
func_verbose "creating $output"
@@ -7260,18 +9021,7 @@ EOF
fi
done
relink_command="(cd `pwd`; $relink_command)"
- relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
- fi
-
- # Quote $ECHO for shipping.
- if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then
- case $progpath in
- [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
- *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
- esac
- qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"`
- else
- qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"`
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
fi
# Only actually do things if not in dry run mode.
@@ -7302,11 +9052,10 @@ EOF
func_emit_cwrapperexe_src > $cwrappersource
- # we should really use a build-platform specific compiler
- # here, but OTOH, the wrappers (shell script and this C one)
- # are only useful if you want to execute the "real" binary.
- # Since the "real" binary is built for $host, then this
- # wrapper might as well be built for $host, too.
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
$opt_dry_run || {
$LTCC $LTCFLAGS -o $cwrapper $cwrappersource
$STRIP $cwrapper
@@ -7352,7 +9101,7 @@ EOF
else
oldobjs="$old_deplibs $non_pic_objects"
if test "$preload" = yes && test -f "$symfileobj"; then
- oldobjs="$oldobjs $symfileobj"
+ func_append oldobjs " $symfileobj"
fi
fi
addlibs="$old_convenience"
@@ -7360,10 +9109,10 @@ EOF
if test -n "$addlibs"; then
gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
+ func_append generated " $gentop"
func_extract_archives $gentop $addlibs
- oldobjs="$oldobjs $func_extract_archives_result"
+ func_append oldobjs " $func_extract_archives_result"
fi
# Do each command in the archive commands.
@@ -7374,10 +9123,10 @@ EOF
# Add any objects from preloaded convenience libraries
if test -n "$dlprefiles"; then
gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
+ func_append generated " $gentop"
func_extract_archives $gentop $dlprefiles
- oldobjs="$oldobjs $func_extract_archives_result"
+ func_append oldobjs " $func_extract_archives_result"
fi
# POSIX demands no paths to be encoded in archives. We have
@@ -7393,9 +9142,9 @@ EOF
done | sort | sort -uc >/dev/null 2>&1); then
:
else
- $ECHO "copying selected object files to avoid basename conflicts..."
+ echo "copying selected object files to avoid basename conflicts..."
gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
+ func_append generated " $gentop"
func_mkdir_p "$gentop"
save_oldobjs=$oldobjs
oldobjs=
@@ -7419,18 +9168,30 @@ EOF
esac
done
func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
- oldobjs="$oldobjs $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
;;
- *) oldobjs="$oldobjs $obj" ;;
+ *) func_append oldobjs " $obj" ;;
esac
done
fi
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
eval cmds=\"$old_archive_cmds\"
func_len " $cmds"
len=$func_len_result
if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
else
# the command line is too long to link in one step, link in parts
func_verbose "using piecewise archive linking..."
@@ -7504,7 +9265,7 @@ EOF
done
# Quote the link command for shipping.
relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
- relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
if test "$hardcode_automatic" = yes ; then
relink_command=
fi
@@ -7524,12 +9285,23 @@ EOF
*.la)
func_basename "$deplib"
name="$func_basename_result"
- eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ func_resolve_sysroot "$deplib"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
test -z "$libdir" && \
func_fatal_error "\`$deplib' is not a valid libtool archive"
- newdependency_libs="$newdependency_libs $libdir/$name"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
;;
- *) newdependency_libs="$newdependency_libs $deplib" ;;
+ *) func_append newdependency_libs " $deplib" ;;
esac
done
dependency_libs="$newdependency_libs"
@@ -7543,9 +9315,9 @@ EOF
eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
test -z "$libdir" && \
func_fatal_error "\`$lib' is not a valid libtool archive"
- newdlfiles="$newdlfiles $libdir/$name"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
;;
- *) newdlfiles="$newdlfiles $lib" ;;
+ *) func_append newdlfiles " $lib" ;;
esac
done
dlfiles="$newdlfiles"
@@ -7562,7 +9334,7 @@ EOF
eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
test -z "$libdir" && \
func_fatal_error "\`$lib' is not a valid libtool archive"
- newdlprefiles="$newdlprefiles $libdir/$name"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
;;
esac
done
@@ -7574,7 +9346,7 @@ EOF
[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
*) abs=`pwd`"/$lib" ;;
esac
- newdlfiles="$newdlfiles $abs"
+ func_append newdlfiles " $abs"
done
dlfiles="$newdlfiles"
newdlprefiles=
@@ -7583,15 +9355,33 @@ EOF
[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
*) abs=`pwd`"/$lib" ;;
esac
- newdlprefiles="$newdlprefiles $abs"
+ func_append newdlprefiles " $abs"
done
dlprefiles="$newdlprefiles"
fi
$RM $output
# place dlname in correct position for cygwin
+ # In fact, it would be nice if we could use this code for all target
+ # systems that can't hard-code library paths into their executables
+ # and that have no shared library path variable independent of PATH,
+ # but it turns out we can't easily determine that from inspecting
+ # libtool variables, so we have to hard-code the OSs to which it
+ # applies here; at the moment, that means platforms that use the PE
+ # object format with DLL files. See the long comment at the top of
+ # tests/bindir.at for full details.
tdlname=$dlname
case $host,$output,$installed,$module,$dlname in
- *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+ # If a -bindir argument was supplied, place the dll there.
+ if test "x$bindir" != x ;
+ then
+ func_relative_path "$install_libdir" "$bindir"
+ tdlname=$func_relative_path_result$dlname
+ else
+ # Otherwise fall back on heuristic.
+ tdlname=../bin/$dlname
+ fi
+ ;;
esac
$ECHO > $output "\
# $outputname - a libtool library file
@@ -7650,7 +9440,7 @@ relink_command=\"$relink_command\""
exit $EXIT_SUCCESS
}
-{ test "$mode" = link || test "$mode" = relink; } &&
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
func_mode_link ${1+"$@"}
@@ -7670,9 +9460,9 @@ func_mode_uninstall ()
for arg
do
case $arg in
- -f) RM="$RM $arg"; rmforce=yes ;;
- -*) RM="$RM $arg" ;;
- *) files="$files $arg" ;;
+ -f) func_append RM " $arg"; rmforce=yes ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
esac
done
@@ -7681,24 +9471,23 @@ func_mode_uninstall ()
rmdirs=
- origobjdir="$objdir"
for file in $files; do
func_dirname "$file" "" "."
dir="$func_dirname_result"
if test "X$dir" = X.; then
- objdir="$origobjdir"
+ odir="$objdir"
else
- objdir="$dir/$origobjdir"
+ odir="$dir/$objdir"
fi
func_basename "$file"
name="$func_basename_result"
- test "$mode" = uninstall && objdir="$dir"
+ test "$opt_mode" = uninstall && odir="$dir"
- # Remember objdir for removal later, being careful to avoid duplicates
- if test "$mode" = clean; then
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test "$opt_mode" = clean; then
case " $rmdirs " in
- *" $objdir "*) ;;
- *) rmdirs="$rmdirs $objdir" ;;
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
esac
fi
@@ -7724,18 +9513,17 @@ func_mode_uninstall ()
# Delete the libtool libraries and symlinks.
for n in $library_names; do
- rmfiles="$rmfiles $objdir/$n"
+ func_append rmfiles " $odir/$n"
done
- test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
- case "$mode" in
+ case "$opt_mode" in
clean)
- case " $library_names " in
- # " " in the beginning catches empty $dlname
+ case " $library_names " in
*" $dlname "*) ;;
- *) rmfiles="$rmfiles $objdir/$dlname" ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
esac
- test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
;;
uninstall)
if test -n "$library_names"; then
@@ -7763,19 +9551,19 @@ func_mode_uninstall ()
# Add PIC object to the list of files to remove.
if test -n "$pic_object" &&
test "$pic_object" != none; then
- rmfiles="$rmfiles $dir/$pic_object"
+ func_append rmfiles " $dir/$pic_object"
fi
# Add non-PIC object to the list of files to remove.
if test -n "$non_pic_object" &&
test "$non_pic_object" != none; then
- rmfiles="$rmfiles $dir/$non_pic_object"
+ func_append rmfiles " $dir/$non_pic_object"
fi
fi
;;
*)
- if test "$mode" = clean ; then
+ if test "$opt_mode" = clean ; then
noexename=$name
case $file in
*.exe)
@@ -7785,7 +9573,7 @@ func_mode_uninstall ()
noexename=$func_stripname_result
# $file with .exe has already been added to rmfiles,
# add $file without .exe
- rmfiles="$rmfiles $file"
+ func_append rmfiles " $file"
;;
esac
# Do a test to see if this is a libtool program.
@@ -7794,7 +9582,7 @@ func_mode_uninstall ()
func_ltwrapper_scriptname "$file"
relink_command=
func_source $func_ltwrapper_scriptname_result
- rmfiles="$rmfiles $func_ltwrapper_scriptname_result"
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
else
relink_command=
func_source $dir/$noexename
@@ -7802,12 +9590,12 @@ func_mode_uninstall ()
# note $name still contains .exe if it was in $file originally
# as does the version of $file that was added into $rmfiles
- rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+ func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
if test "$fast_install" = yes && test -n "$relink_command"; then
- rmfiles="$rmfiles $objdir/lt-$name"
+ func_append rmfiles " $odir/lt-$name"
fi
if test "X$noexename" != "X$name" ; then
- rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+ func_append rmfiles " $odir/lt-${noexename}.c"
fi
fi
fi
@@ -7815,7 +9603,6 @@ func_mode_uninstall ()
esac
func_show_eval "$RM $rmfiles" 'exit_status=1'
done
- objdir="$origobjdir"
# Try to remove the ${objdir}s in the directories where we deleted files
for dir in $rmdirs; do
@@ -7827,16 +9614,16 @@ func_mode_uninstall ()
exit $exit_status
}
-{ test "$mode" = uninstall || test "$mode" = clean; } &&
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
func_mode_uninstall ${1+"$@"}
-test -z "$mode" && {
+test -z "$opt_mode" && {
help="$generic_help"
func_fatal_help "you must specify a MODE"
}
test -z "$exec_cmd" && \
- func_fatal_help "invalid operation mode \`$mode'"
+ func_fatal_help "invalid operation mode \`$opt_mode'"
if test -n "$exec_cmd"; then
eval exec "$exec_cmd"
diff --git a/m4/acx_check_suncc.m4 b/m4/acx_check_suncc.m4
index 4e8f961..8918593 100644
--- a/m4/acx_check_suncc.m4
+++ b/m4/acx_check_suncc.m4
@@ -42,6 +42,7 @@ 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
diff --git a/m4/acx_pthread.m4 b/m4/acx_pthread.m4
index 2cf20de..89d42c7 100644
--- a/m4/acx_pthread.m4
+++ b/m4/acx_pthread.m4
@@ -340,6 +340,40 @@ if test "x$acx_pthread_ok" = xyes; then
acx_pthread_ok=no
fi
+ AC_MSG_CHECKING([whether what we have so far is sufficient with -nostdlib])
+ CFLAGS="-nostdlib $CFLAGS"
+ # we need c with nostdlib
+ LIBS="$LIBS -lc"
+ AC_TRY_LINK([#include <pthread.h>],
+ [pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+ [done=yes],[done=no])
+
+ if test "x$done" = xyes; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+
+ if test x"$done" = xno; then
+ AC_MSG_CHECKING([whether -lpthread saves the day])
+ LIBS="-lpthread $LIBS"
+ AC_TRY_LINK([#include <pthread.h>],
+ [pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+ [done=yes],[done=no])
+
+ if test "x$done" = xyes; then
+ AC_MSG_RESULT([yes])
+ PTHREAD_LIBS="$PTHREAD_LIBS -lpthread"
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries and -nostdlib])
+ fi
+ fi
+
CFLAGS="$save_CFLAGS"
LIBS="$save_LIBS"
CC="$save_CC"
diff --git a/m4/libtool.m4 b/m4/libtool.m4
index 4ceb7f1..d7c043f 100644
--- a/m4/libtool.m4
+++ b/m4/libtool.m4
@@ -1,7 +1,8 @@
# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
#
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-# 2006, 2007, 2008 Free Software Foundation, Inc.
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
# Written by Gordon Matzigkeit, 1996
#
# This file is free software; the Free Software Foundation gives
@@ -10,7 +11,8 @@
m4_define([_LT_COPYING], [dnl
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-# 2006, 2007, 2008 Free Software Foundation, Inc.
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
# Written by Gordon Matzigkeit, 1996
#
# This file is part of GNU Libtool.
@@ -37,7 +39,7 @@ m4_define([_LT_COPYING], [dnl
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
])
-# serial 56 LT_INIT
+# serial 57 LT_INIT
# LT_PREREQ(VERSION)
@@ -66,6 +68,7 @@ esac
# ------------------
AC_DEFUN([LT_INIT],
[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
AC_BEFORE([$0], [LT_LANG])dnl
AC_BEFORE([$0], [LT_OUTPUT])dnl
AC_BEFORE([$0], [LTDL_INIT])dnl
@@ -82,6 +85,8 @@ AC_REQUIRE([LTVERSION_VERSION])dnl
AC_REQUIRE([LTOBSOLETE_VERSION])dnl
m4_require([_LT_PROG_LTMAIN])dnl
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
dnl Parse OPTIONS
_LT_SET_OPTIONS([$0], [$1])
@@ -118,7 +123,7 @@ m4_defun([_LT_CC_BASENAME],
*) break;;
esac
done
-cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
])
@@ -138,6 +143,11 @@ m4_defun([_LT_FILEUTILS_DEFAULTS],
m4_defun([_LT_SETUP],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
_LT_DECL([], [host_alias], [0], [The host system])dnl
_LT_DECL([], [host], [0])dnl
_LT_DECL([], [host_os], [0])dnl
@@ -160,10 +170,13 @@ _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
dnl
m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
m4_require([_LT_CMD_RELOAD])dnl
m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
m4_require([_LT_CMD_OLD_ARCHIVE])dnl
m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
_LT_CONFIG_LIBTOOL_INIT([
# See if we are running on zsh, and set the options which allow our
@@ -179,7 +192,6 @@ fi
_LT_CHECK_OBJDIR
m4_require([_LT_TAG_COMPILER])dnl
-_LT_PROG_ECHO_BACKSLASH
case $host_os in
aix3*)
@@ -193,23 +205,6 @@ aix3*)
;;
esac
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\([["`\\]]\)/\\\1/g'
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to delay expansion of an escaped single quote.
-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
# Global variables:
ofile=libtool
can_build_shared=yes
@@ -250,6 +245,28 @@ _LT_CONFIG_COMMANDS
])# _LT_SETUP
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
# _LT_PROG_LTMAIN
# ---------------
# Note that this code is called both from `configure', and `config.status'
@@ -380,12 +397,12 @@ m4_define([lt_decl_dquote_varnames],
# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
# ---------------------------------------------------
m4_define([lt_decl_varnames_tagged],
-[_$0(m4_quote(m4_default([$1], [[, ]])),
- m4_quote(m4_if([$2], [],
- m4_quote(lt_decl_tag_varnames),
- m4_quote(m4_shift($@)))),
- m4_split(m4_normalize(m4_quote(_LT_TAGS))))])
-m4_define([_lt_decl_varnames_tagged], [lt_combine([$1], [$2], [_], $3)])
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
@@ -408,7 +425,7 @@ m4_define([_lt_decl_all_varnames],
# declaration there will have the same value as in `configure'. VARNAME
# must have a single quote delimited value for this to work.
m4_define([_LT_CONFIG_STATUS_DECLARE],
-[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`'])
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
# _LT_CONFIG_STATUS_DECLARATIONS
@@ -418,7 +435,7 @@ m4_define([_LT_CONFIG_STATUS_DECLARE],
# embedded single quotes properly. In configure, this macro expands
# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
#
-# <var>='`$ECHO "X$<var>" | $Xsed -e "$delay_single_quote_subst"`'
+# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
[m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
@@ -517,12 +534,20 @@ LTCC='$LTCC'
LTCFLAGS='$LTCFLAGS'
compiler='$compiler_DEFAULT'
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
# Quote evaled strings.
for var in lt_decl_all_varnames([[ \
]], lt_decl_quote_varnames); do
- case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[[\\\\\\\`\\"\\\$]]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
;;
*)
eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -533,9 +558,9 @@ done
# Double-quote double-evaled strings.
for var in lt_decl_all_varnames([[ \
]], lt_decl_dquote_varnames); do
- case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[[\\\\\\\`\\"\\\$]]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
;;
*)
eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -543,16 +568,38 @@ for var in lt_decl_all_varnames([[ \
esac
done
-# Fix-up fallback echo if it was mangled by the above quoting rules.
-case \$lt_ECHO in
-*'\\\[$]0 --fallback-echo"')dnl "
- lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\`
- ;;
-esac
-
_LT_OUTPUT_LIBTOOL_INIT
])
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable. If COMMENT is supplied, it is inserted after the
+# `#!' sequence but before initialization text begins. After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script. The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test $lt_write_fail = 0 && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
# LT_OUTPUT
# ---------
@@ -562,20 +609,11 @@ _LT_OUTPUT_LIBTOOL_INIT
AC_DEFUN([LT_OUTPUT],
[: ${CONFIG_LT=./config.lt}
AC_MSG_NOTICE([creating $CONFIG_LT])
-cat >"$CONFIG_LT" <<_LTEOF
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate a libtool stub with the current configuration.
-
-lt_cl_silent=false
-SHELL=\${CONFIG_SHELL-$SHELL}
-_LTEOF
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
cat >>"$CONFIG_LT" <<\_LTEOF
-AS_SHELL_SANITIZE
-_AS_PREPARE
-
-exec AS_MESSAGE_FD>&1
+lt_cl_silent=false
exec AS_MESSAGE_LOG_FD>>config.log
{
echo
@@ -601,7 +639,7 @@ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
configured by $[0], generated by m4_PACKAGE_STRING.
-Copyright (C) 2008 Free Software Foundation, Inc.
+Copyright (C) 2011 Free Software Foundation, Inc.
This config.lt script is free software; the Free Software Foundation
gives unlimited permision to copy, distribute and modify it."
@@ -646,15 +684,13 @@ chmod +x "$CONFIG_LT"
# appending to config.log, which fails on DOS, as config.log is still kept
# open by configure. Here we exec the FD to /dev/null, effectively closing
# config.log, so it can be properly (re)opened and appended to by config.lt.
-if test "$no_create" != yes; then
- lt_cl_success=:
- test "$silent" = yes &&
- lt_config_lt_args="$lt_config_lt_args --quiet"
- exec AS_MESSAGE_LOG_FD>/dev/null
- $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
- exec AS_MESSAGE_LOG_FD>>config.log
- $lt_cl_success || AS_EXIT(1)
-fi
+lt_cl_success=:
+test "$silent" = yes &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
])# LT_OUTPUT
@@ -717,15 +753,12 @@ _LT_EOF
# if finds mixed CR/LF and LF-only lines. Since sed operates in
# text mode, it properly converts lines to CR/LF. This bash problem
# is reportedly fixed, but why not run on old versions too?
- sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
- || (rm -f "$cfgfile"; exit 1)
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
- _LT_PROG_XSI_SHELLFNS
+ _LT_PROG_REPLACE_SHELLFNS
- sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
- || (rm -f "$cfgfile"; exit 1)
-
- mv -f "$cfgfile" "$ofile" ||
+ mv -f "$cfgfile" "$ofile" ||
(rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
chmod +x "$ofile"
],
@@ -770,6 +803,7 @@ AC_DEFUN([LT_LANG],
m4_case([$1],
[C], [_LT_LANG(C)],
[C++], [_LT_LANG(CXX)],
+ [Go], [_LT_LANG(GO)],
[Java], [_LT_LANG(GCJ)],
[Fortran 77], [_LT_LANG(F77)],
[Fortran], [_LT_LANG(FC)],
@@ -791,6 +825,31 @@ m4_defun([_LT_LANG],
])# _LT_LANG
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_GO. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC], [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+ fi
+fi
+if test -z "$GOC"; then
+ AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
# _LT_LANG_DEFAULT_CONFIG
# -----------------------
m4_defun([_LT_LANG_DEFAULT_CONFIG],
@@ -821,6 +880,10 @@ AC_PROVIDE_IFELSE([AC_PROG_GCJ],
m4_ifdef([LT_PROG_GCJ],
[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+ [LT_LANG(GO)],
+ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
AC_PROVIDE_IFELSE([LT_PROG_RC],
[LT_LANG(RC)],
[m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
@@ -831,11 +894,13 @@ AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
dnl AC_DEFUN([AC_LIBTOOL_F77], [])
dnl AC_DEFUN([AC_LIBTOOL_FC], [])
dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
# _LT_TAG_COMPILER
@@ -921,7 +986,13 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
-dynamiclib -Wl,-single_module conftest.c 2>conftest.err
_lt_result=$?
- if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
lt_cv_apple_cc_single_mod=yes
else
cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -929,6 +1000,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
rm -rf libconftest.dylib*
rm -f conftest.*
fi])
+
AC_CACHE_CHECK([for -exported_symbols_list linker flag],
[lt_cv_ld_exported_symbols_list],
[lt_cv_ld_exported_symbols_list=no
@@ -940,15 +1012,43 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
[lt_cv_ld_exported_symbols_list=no])
LDFLAGS="$save_LDFLAGS"
])
+
+ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+ [lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+ ])
case $host_os in
rhapsody* | darwin1.[[012]])
_lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
darwin1.*)
_lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- darwin*) # darwin 5.x on
+ darwin*) # darwin 5.x on
# if running on 10.5 or later, the deployment target defaults
# to the OS version, if on x86, and 10.4, the deployment
- # target defaults to 10.4. Don't you love it?
+ # target defaults to 10.4. Don't you love it?
case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
_lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
@@ -967,7 +1067,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
else
_lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
fi
- if test "$DSYMUTIL" != ":"; then
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
_lt_dsymutil='~$DSYMUTIL $lib || :'
else
_lt_dsymutil=
@@ -977,8 +1077,8 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
])
-# _LT_DARWIN_LINKER_FEATURES
-# --------------------------
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
# Checks for linker and compiler features on darwin
m4_defun([_LT_DARWIN_LINKER_FEATURES],
[
@@ -987,11 +1087,21 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_automatic, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
- _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ fi
_LT_TAGVAR(link_all_deplibs, $1)=yes
_LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
- if test "$GCC" = "yes"; then
- output_verbose_link_cmd=echo
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
_LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
_LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
_LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
@@ -1007,203 +1117,142 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
fi
])
-# _LT_SYS_MODULE_PATH_AIX
-# -----------------------
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
# Links a minimal program and checks the executable
# for the system default hardcoded library path. In most cases,
# this is /usr/lib:/lib, but when the MPI compilers are used
# the location of the communication and MPI libs are included too.
# If we don't find anything, use the default library path according
# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
m4_defun([_LT_SYS_MODULE_PATH_AIX],
[m4_require([_LT_DECL_SED])dnl
-AC_LINK_IFELSE(AC_LANG_PROGRAM,[
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi],[])
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+ lt_aix_libpath_sed='[
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }]'
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi],[])
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+ fi
+ ])
+ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
])# _LT_SYS_MODULE_PATH_AIX
# _LT_SHELL_INIT(ARG)
# -------------------
m4_define([_LT_SHELL_INIT],
-[ifdef([AC_DIVERSION_NOTICE],
- [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
- [AC_DIVERT_PUSH(NOTICE)])
-$1
-AC_DIVERT_POP
-])# _LT_SHELL_INIT
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
# _LT_PROG_ECHO_BACKSLASH
# -----------------------
-# Add some code to the start of the generated configure script which
-# will find an echo command which doesn't interpret backslashes.
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
m4_defun([_LT_PROG_ECHO_BACKSLASH],
-[_LT_SHELL_INIT([
-# Check that we are running under the correct shell.
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-case X$lt_ECHO in
-X*--fallback-echo)
- # Remove one level of quotation (which was required for Make).
- ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
- ;;
-esac
-
-ECHO=${lt_ECHO-echo}
-if test "X[$]1" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
-elif test "X[$]1" = X--fallback-echo; then
- # Avoid inline document here, it may be left over
- :
-elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
- # Yippee, $ECHO works!
- :
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
else
- # Restart under the correct shell.
- exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
-fi
-
-if test "X[$]1" = X--fallback-echo; then
- # used as fallback echo
- shift
- cat <<_LT_EOF
-[$]*
-_LT_EOF
- exit 0
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
fi
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test -z "$lt_ECHO"; then
- if test "X${echo_test_string+set}" != Xset; then
- # find a string as large as possible, as long as the shell can cope with it
- for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
- # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
- if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
- { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
- then
- break
- fi
- done
- fi
-
- if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- :
- else
- # The Solaris, AIX, and Digital Unix default echo programs unquote
- # backslashes. This makes it impossible to quote backslashes using
- # echo "$something" | sed 's/\\/\\\\/g'
- #
- # So, first we look for a working echo in the user's PATH.
-
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for dir in $PATH /usr/ucb; do
- IFS="$lt_save_ifs"
- if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
- test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- ECHO="$dir/echo"
- break
- fi
- done
- IFS="$lt_save_ifs"
-
- if test "X$ECHO" = Xecho; then
- # We didn't find a better echo, so look for alternatives.
- if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # This shell has a builtin print -r that does the trick.
- ECHO='print -r'
- elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
- test "X$CONFIG_SHELL" != X/bin/ksh; then
- # If we have ksh, try running configure again with it.
- ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
- export ORIGINAL_CONFIG_SHELL
- CONFIG_SHELL=/bin/ksh
- export CONFIG_SHELL
- exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
- else
- # Try using printf.
- ECHO='printf %s\n'
- if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # Cool, printf works
- :
- elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
- export CONFIG_SHELL
- SHELL="$CONFIG_SHELL"
- export SHELL
- ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
- elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
- else
- # maybe with a smaller string...
- prev=:
-
- for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
- if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
- then
- break
- fi
- prev="$cmd"
- done
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
- if test "$prev" != 'sed 50q "[$]0"'; then
- echo_test_string=`eval $prev`
- export echo_test_string
- exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
- else
- # Oops. We lost completely, so just stick with echo.
- ECHO=echo
- fi
- fi
- fi
- fi
- fi
-fi
+case "$ECHO" in
+ printf*) AC_MSG_RESULT([printf]) ;;
+ print*) AC_MSG_RESULT([print -r]) ;;
+ *) AC_MSG_RESULT([cat]) ;;
+esac
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-lt_ECHO=$ECHO
-if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
- lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
-fi
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test "X`printf %s $ECHO`" = "X$ECHO" \
+ || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
-AC_SUBST(lt_ECHO)
-])
_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
-_LT_DECL([], [ECHO], [1],
- [An echo program that does not interpret backslashes])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
])# _LT_PROG_ECHO_BACKSLASH
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[ --with-sysroot[=DIR] Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted. We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ AC_MSG_RESULT([${with_sysroot}])
+ AC_MSG_ERROR([The sysroot must be an absolute path.])
+ ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and in which our libraries should be installed.])])
+
# _LT_ENABLE_LOCK
# ---------------
m4_defun([_LT_ENABLE_LOCK],
@@ -1232,7 +1281,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
if test "$lt_cv_prog_gnu_ld" = yes; then
case `/usr/bin/file conftest.$ac_objext` in
@@ -1263,7 +1312,7 @@ ia64-*-hpux*)
rm -rf conftest*
;;
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
@@ -1275,9 +1324,19 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
LD="${LD-ld} -m elf_i386_fbsd"
;;
x86_64-*linux*)
- LD="${LD-ld} -m elf_i386"
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*)
+ LD="${LD-ld} -m elf32lppclinux"
;;
- ppc64-*linux*|powerpc64-*linux*)
+ powerpc64-*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
@@ -1296,7 +1355,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
- ppc*-*linux*|powerpc*-*linux*)
+ powerpcle-*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
@@ -1325,14 +1387,27 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
CFLAGS="$SAVE_CFLAGS"
fi
;;
-sparc*-*solaris*)
+*-*solaris*)
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.o` in
*64-bit*)
case $lt_cv_prog_gnu_ld in
- yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ yes*)
+ case $host in
+ i?86-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD="${LD-ld}_sol2"
+ fi
+ ;;
*)
if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
LD="${LD-ld} -64"
@@ -1350,14 +1425,47 @@ need_locks="$enable_libtool_lock"
])# _LT_ENABLE_LOCK
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+ [lt_cv_ar_at_file=no
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+ ])
+ ])
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+ [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
# _LT_CMD_OLD_ARCHIVE
# -------------------
m4_defun([_LT_CMD_OLD_ARCHIVE],
-[AC_CHECK_TOOL(AR, ar, false)
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
-_LT_DECL([], [AR], [1], [The archiver])
-_LT_DECL([], [AR_FLAGS], [1])
+[_LT_PROG_AR
AC_CHECK_TOOL(STRIP, strip, :)
test -z "$STRIP" && STRIP=:
@@ -1376,18 +1484,27 @@ old_postuninstall_cmds=
if test -n "$RANLIB"; then
case $host_os in
openbsd*)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
;;
*)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
;;
esac
- old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
_LT_DECL([], [old_postinstall_cmds], [2])
_LT_DECL([], [old_postuninstall_cmds], [2])
_LT_TAGDECL([], [old_archive_cmds], [2],
[Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+ [Whether to use a lock for old archive extraction])
])# _LT_CMD_OLD_ARCHIVE
@@ -1412,15 +1529,15 @@ AC_CACHE_CHECK([$1], [$2],
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&AS_MESSAGE_LOG_FD
- echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
$SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
$2=yes
@@ -1460,7 +1577,7 @@ AC_CACHE_CHECK([$1], [$2],
if test -s conftest.err; then
# Append any errors to the config.log.
cat conftest.err 1>&AS_MESSAGE_LOG_FD
- $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
$SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
if diff conftest.exp conftest.er2 >/dev/null; then
$2=yes
@@ -1512,7 +1629,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
lt_cv_sys_max_cmd_len=-1;
;;
- cygwin* | mingw*)
+ cygwin* | mingw* | cegcc*)
# On Win9x/ME, this test blows up -- it succeeds, but takes
# about 5 minutes as the teststring grows exponentially.
# Worse, since 9x/ME are not pre-emptively multitasking,
@@ -1523,6 +1640,11 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
lt_cv_sys_max_cmd_len=8192;
;;
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
amigaos*)
# On AmigaOS with pdksh, this test takes hours, literally.
# So we just punt and use a minimum line length of 8192.
@@ -1548,6 +1670,11 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
lt_cv_sys_max_cmd_len=196608
;;
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
osf*)
# Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
# due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
@@ -1574,7 +1701,8 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
;;
*)
lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len"; then
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
else
@@ -1587,8 +1715,8 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
# If test is not a shell built-in, we'll probably end up computing a
# maximum length that is only half of the actual maximum length, but
# we can't tell.
- while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
- = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
test $i != 17 # 1/2 MB should be enough
do
i=`expr $i + 1`
@@ -1639,7 +1767,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-[#line __oline__ "configure"
+[#line $LINENO "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -1680,11 +1808,13 @@ else
# endif
#endif
-#ifdef __cplusplus
-extern "C" void exit (int);
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
#endif
-void fnord() { int i=42;}
+int fnord () { return 42; }
int main ()
{
void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
@@ -1693,13 +1823,17 @@ int main ()
if (self)
{
if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
/* dlclose (self); */
}
else
puts (dlerror ());
- exit (status);
+ return status;
}]
_LT_EOF
if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
@@ -1738,7 +1872,7 @@ else
lt_cv_dlopen_self=yes
;;
- mingw* | pw32*)
+ mingw* | pw32* | cegcc*)
lt_cv_dlopen="LoadLibrary"
lt_cv_dlopen_libs=
;;
@@ -1869,16 +2003,16 @@ AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&AS_MESSAGE_LOG_FD
- echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
- $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
$SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
@@ -2035,7 +2169,9 @@ m4_defun([_LT_SYS_DYNAMIC_LINKER],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
m4_require([_LT_DECL_EGREP])dnl
m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
AC_MSG_CHECKING([dynamic linker characteristics])
m4_if([$1],
[], [
@@ -2044,16 +2180,23 @@ if test "$GCC" = yes; then
darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
*) lt_awk_arg="/^libraries:/" ;;
esac
- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
# if the path contains ";" then we assume it to be the separator
# otherwise default to the standard path separator (i.e. ":") - it is
# assumed that no part of a normal pathname contains ";" but that should
# okay in the real world where ";" in dirpaths is itself problematic.
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
- else
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
# Ok, now we have the path, separated by spaces, we can step through it
# and add multilib dir if necessary.
lt_tmp_lt_search_path_spec=
@@ -2066,7 +2209,7 @@ if test "$GCC" = yes; then
lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
fi
done
- lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
BEGIN {RS=" "; FS="/|\n";} {
lt_foo="";
lt_count=0;
@@ -2086,7 +2229,13 @@ BEGIN {RS=" "; FS="/|\n";} {
if (lt_foo != "") { lt_freq[[lt_foo]]++; }
if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
}'`
- sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
else
sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
fi])
@@ -2112,7 +2261,7 @@ need_version=unknown
case $host_os in
aix3*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
shlibpath_var=LIBPATH
@@ -2121,7 +2270,7 @@ aix3*)
;;
aix[[4-9]]*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
hardcode_into_libs=yes
@@ -2174,7 +2323,7 @@ amigaos*)
m68k)
library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;;
esac
;;
@@ -2186,7 +2335,7 @@ beos*)
;;
bsdi[[45]]*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
@@ -2199,14 +2348,15 @@ bsdi[[45]]*)
# libtool to hard-code these into programs
;;
-cygwin* | mingw* | pw32*)
+cygwin* | mingw* | pw32* | cegcc*)
version_type=windows
shrext_cmds=".dll"
need_version=no
need_lib_prefix=no
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32*)
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
library_names_spec='$libname.dll.a'
# DLL is installed to $(libdir)/../bin by postinstall_cmds
postinstall_cmds='base_file=`basename \${file}`~
@@ -2227,36 +2377,83 @@ cygwin* | mingw* | pw32*)
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
;;
- mingw*)
+ mingw* | cegcc*)
# MinGW DLLs use traditional 'lib' prefix
soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
;;
esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
;;
*)
+ # Assume MSVC wrapper
library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
;;
esac
- dynamic_linker='Win32 ld.exe'
# FIXME: first we should search . and the directory the executable is in
shlibpath_var=PATH
;;
@@ -2277,7 +2474,7 @@ m4_if([$1], [],[
;;
dgux*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
@@ -2285,10 +2482,6 @@ dgux*)
shlibpath_var=LD_LIBRARY_PATH
;;
-freebsd1*)
- dynamic_linker=no
- ;;
-
freebsd* | dragonfly*)
# DragonFly does not have aout. When/if they implement a new
# versioning mechanism, adjust this.
@@ -2296,7 +2489,7 @@ freebsd* | dragonfly*)
objformat=`/usr/bin/objformat`
else
case $host_os in
- freebsd[[123]]*) objformat=aout ;;
+ freebsd[[23]].*) objformat=aout ;;
*) objformat=elf ;;
esac
fi
@@ -2314,7 +2507,7 @@ freebsd* | dragonfly*)
esac
shlibpath_var=LD_LIBRARY_PATH
case $host_os in
- freebsd2*)
+ freebsd2.*)
shlibpath_overrides_runpath=yes
;;
freebsd3.[[01]]* | freebsdelf3.[[01]]*)
@@ -2333,13 +2526,16 @@ freebsd* | dragonfly*)
esac
;;
-gnu*)
- version_type=linux
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
+ dynamic_linker="$host_os runtime_loader"
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
hardcode_into_libs=yes
;;
@@ -2385,12 +2581,14 @@ hpux9* | hpux10* | hpux11*)
soname_spec='${libname}${release}${shared_ext}$major'
;;
esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
;;
interix[[3-9]]*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
@@ -2406,7 +2604,7 @@ irix5* | irix6* | nonstopux*)
nonstopux*) version_type=nonstopux ;;
*)
if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
else
version_type=irix
fi ;;
@@ -2443,9 +2641,9 @@ linux*oldld* | linux*aout* | linux*coff*)
dynamic_linker=no
;;
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
- version_type=linux
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -2453,16 +2651,21 @@ linux* | k*bsd*-gnu)
finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
+
# Some binutils ld are patched to set DT_RUNPATH
- save_LDFLAGS=$LDFLAGS
- save_libdir=$libdir
- eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
- LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
- AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
- [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
- [shlibpath_overrides_runpath=yes])])
- LDFLAGS=$save_LDFLAGS
- libdir=$save_libdir
+ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+ [lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [lt_cv_shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+ ])
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
# This implies no fast_install, which is unacceptable.
# Some rework will be needed to allow for fast_install
@@ -2471,7 +2674,7 @@ linux* | k*bsd*-gnu)
# Append ld.so.conf contents to the search path
if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
fi
@@ -2484,6 +2687,18 @@ linux* | k*bsd*-gnu)
dynamic_linker='GNU/Linux ld.so'
;;
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
netbsd*)
version_type=sunos
need_lib_prefix=no
@@ -2503,7 +2718,7 @@ netbsd*)
;;
newsos6)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
@@ -2572,7 +2787,7 @@ rdos*)
;;
solaris*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -2597,7 +2812,7 @@ sunos4*)
;;
sysv4 | sysv4.3*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
@@ -2621,7 +2836,7 @@ sysv4 | sysv4.3*)
sysv4*MP*)
if test -d /usr/nec ;then
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
soname_spec='$libname${shared_ext}.$major'
shlibpath_var=LD_LIBRARY_PATH
@@ -2652,17 +2867,17 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
tpf*)
# TPF is a cross-target only. Preferred cross-host = GNU/Linux.
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_name_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
;;
uts4*)
- version_type=linux
+ version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
@@ -2679,7 +2894,7 @@ variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
if test "$GCC" = yes; then
variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
fi
-
+
if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
fi
@@ -2704,6 +2919,8 @@ _LT_DECL([], [library_names_spec], [1],
The last name is the one that the linker finds with -lNAME]])
_LT_DECL([], [soname_spec], [1],
[[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+ [Permission mode override for installation of shared libraries])
_LT_DECL([], [postinstall_cmds], [2],
[Command to use after installation of a shared archive])
_LT_DECL([], [postuninstall_cmds], [2],
@@ -2816,6 +3033,7 @@ AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
m4_require([_LT_DECL_SED])dnl
m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
AC_ARG_WITH([gnu-ld],
[AS_HELP_STRING([--with-gnu-ld],
@@ -2937,6 +3155,11 @@ case $reload_flag in
esac
reload_cmds='$LD$reload_flag -o $output$reload_objs'
case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
darwin*)
if test "$GCC" = yes; then
reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
@@ -2945,8 +3168,8 @@ case $host_os in
fi
;;
esac
-_LT_DECL([], [reload_flag], [1], [How to create reloadable object files])dnl
-_LT_DECL([], [reload_cmds], [2])dnl
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
])# _LT_CMD_RELOAD
@@ -2956,6 +3179,7 @@ _LT_DECL([], [reload_cmds], [2])dnl
# -- PORTME fill in with the dynamic library characteristics
m4_defun([_LT_CHECK_MAGIC_METHOD],
[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
AC_CACHE_CHECK([how to recognize dependent libraries],
lt_cv_deplibs_check_method,
[lt_cv_file_magic_cmd='$MAGIC_CMD'
@@ -2997,15 +3221,23 @@ mingw* | pw32*)
# Base MSYS/MinGW do not provide the 'file' command needed by
# func_win32_libid shell function, so use a weaker test based on 'objdump',
# unless we find 'file', for example because we are cross-compiling.
- if ( file / ) >/dev/null 2>&1; then
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
lt_cv_file_magic_cmd='func_win32_libid'
else
- lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
lt_cv_file_magic_cmd='$OBJDUMP -f'
fi
;;
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
darwin* | rhapsody*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -3026,7 +3258,7 @@ freebsd* | dragonfly*)
fi
;;
-gnu*)
+haiku*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -3038,11 +3270,11 @@ hpux10.20* | hpux11*)
lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
;;
hppa*64*)
- [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
;;
*)
- lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
lt_cv_file_magic_test_file=/usr/lib/libc.sl
;;
esac
@@ -3063,12 +3295,12 @@ irix5* | irix6* | nonstopux*)
lt_cv_deplibs_check_method=pass_all
;;
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
lt_cv_deplibs_check_method=pass_all
;;
-netbsd*)
+netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
else
@@ -3142,6 +3374,21 @@ tpf*)
;;
esac
])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
file_magic_cmd=$lt_cv_file_magic_cmd
deplibs_check_method=$lt_cv_deplibs_check_method
test -z "$deplibs_check_method" && deplibs_check_method=unknown
@@ -3149,7 +3396,11 @@ test -z "$deplibs_check_method" && deplibs_check_method=unknown
_LT_DECL([], [deplibs_check_method], [1],
[Method to check whether dependent libraries are shared objects])
_LT_DECL([], [file_magic_cmd], [1],
- [Command to use when deplibs_check_method == "file_magic"])
+ [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+ [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
])# _LT_CHECK_MAGIC_METHOD
@@ -3206,7 +3457,19 @@ if test "$lt_cv_path_NM" != "no"; then
NM="$lt_cv_path_NM"
else
# Didn't find any BSD compatible name lister, look for dumpbin.
- AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :)
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
AC_SUBST([DUMPBIN])
if test "$DUMPBIN" != ":"; then
NM="$DUMPBIN"
@@ -3219,13 +3482,13 @@ _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
[lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&AS_MESSAGE_LOG_FD
- (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&AS_MESSAGE_LOG_FD
- (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD)
+ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
cat conftest.out >&AS_MESSAGE_LOG_FD
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -3240,6 +3503,67 @@ dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_PROG_NM], [])
dnl AC_DEFUN([AC_PROG_NM], [])
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+ [lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*])
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
# LT_LIB_M
# --------
@@ -3248,7 +3572,7 @@ AC_DEFUN([LT_LIB_M],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
LIBM=
case $host in
-*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
# These system don't have libm, or don't need it
;;
*-ncr-sysv4.3*)
@@ -3276,7 +3600,12 @@ m4_defun([_LT_COMPILER_NO_RTTI],
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
if test "$GCC" = yes; then
- _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ case $cc_basename in
+ nvcc*)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+ esac
_LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
lt_cv_prog_compiler_rtti_exceptions,
@@ -3293,6 +3622,7 @@ _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([LT_PATH_NM])dnl
AC_REQUIRE([LT_PATH_LD])dnl
m4_require([_LT_DECL_SED])dnl
@@ -3317,7 +3647,7 @@ case $host_os in
aix*)
symcode='[[BCDT]]'
;;
-cygwin* | mingw* | pw32*)
+cygwin* | mingw* | pw32* | cegcc*)
symcode='[[ABCDGISTW]]'
;;
hpux*)
@@ -3360,8 +3690,8 @@ esac
lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
# Handle CRLF in mingw tool chain
opt_cr=
@@ -3385,6 +3715,7 @@ for ac_symprfx in "" "_"; do
# which start with @ or ?.
lt_cv_sys_global_symbol_pipe="$AWK ['"\
" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
" \$ 0!~/External *\|/{next};"\
" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
@@ -3397,6 +3728,7 @@ for ac_symprfx in "" "_"; do
else
lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
# Check to see that the pipe works correctly.
pipe_works=no
@@ -3418,7 +3750,7 @@ _LT_EOF
if AC_TRY_EVAL(ac_compile); then
# Now try to grab the symbols.
nlist=conftest.nm
- if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
# Try sorting and uniquifying the output.
if sort "$nlist" | uniq > "$nlist"T; then
mv -f "$nlist"T "$nlist"
@@ -3430,6 +3762,18 @@ _LT_EOF
if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT@&t@_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -3441,7 +3785,7 @@ _LT_EOF
cat <<_LT_EOF >> conftest.$ac_ext
/* The mapping between symbol names and symbols. */
-const struct {
+LT@&t@_DLSYM_CONST struct {
const char *name;
void *address;
}
@@ -3467,15 +3811,15 @@ static const void *lt_preloaded_setup() {
_LT_EOF
# Now try linking the two files.
mv conftest.$ac_objext conftstm.$ac_objext
- lt_save_LIBS="$LIBS"
- lt_save_CFLAGS="$CFLAGS"
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
LIBS="conftstm.$ac_objext"
CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
pipe_works=yes
fi
- LIBS="$lt_save_LIBS"
- CFLAGS="$lt_save_CFLAGS"
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
else
echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
fi
@@ -3508,6 +3852,13 @@ else
AC_MSG_RESULT(ok)
fi
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
[Take the output of nm and produce a listing of raw symbols and C names])
_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
@@ -3518,6 +3869,8 @@ _LT_DECL([global_symbol_to_c_name_address],
_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
[lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
[Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([], [nm_file_list_spec], [1],
+ [Specify filename containing input files for $NM])
]) # _LT_CMD_GLOBAL_SYMBOLS
@@ -3529,7 +3882,6 @@ _LT_TAGVAR(lt_prog_compiler_wl, $1)=
_LT_TAGVAR(lt_prog_compiler_pic, $1)=
_LT_TAGVAR(lt_prog_compiler_static, $1)=
-AC_MSG_CHECKING([for $compiler option to produce PIC])
m4_if([$1], [CXX], [
# C++ specific cases for pic, static, wl, etc.
if test "$GXX" = yes; then
@@ -3563,7 +3915,7 @@ m4_if([$1], [CXX], [
beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
# PIC is the default for these OSes.
;;
- mingw* | cygwin* | os2* | pw32*)
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
# This hack is so that the source file can tell whether it is being
# built for inclusion in a dll (and should export symbols for example).
# Although the cygwin gcc ignores -fPIC, still need this for old-style
@@ -3580,6 +3932,11 @@ m4_if([$1], [CXX], [
# DJGPP does not support shared libraries at all
_LT_TAGVAR(lt_prog_compiler_pic, $1)=
;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
interix[[3-9]]*)
# Interix 3.x gcc -fpic/-fPIC options generate broken code.
# Instead, we relocate shared libraries at runtime.
@@ -3590,10 +3947,11 @@ m4_if([$1], [CXX], [
fi
;;
hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
case $host_cpu in
- hppa*64*|ia64*)
+ hppa*64*)
;;
*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
@@ -3628,6 +3986,12 @@ m4_if([$1], [CXX], [
;;
esac
;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
dgux*)
case $cc_basename in
ec++*)
@@ -3684,19 +4048,26 @@ m4_if([$1], [CXX], [
;;
esac
;;
- linux* | k*bsd*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
KCC*)
# KAI C++ Compiler
_LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
- icpc* | ecpc* )
- # Intel C++
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
pgCC* | pgcpp*)
# Portland Group C++ compiler
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
@@ -3710,8 +4081,8 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)=
_LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
;;
- xlc* | xlC*)
- # IBM XL 8.0 on PPC
+ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
@@ -3741,7 +4112,7 @@ m4_if([$1], [CXX], [
;;
esac
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu)
;;
*qnx* | *nto*)
# QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -3773,7 +4144,7 @@ m4_if([$1], [CXX], [
;;
solaris*)
case $cc_basename in
- CC*)
+ CC* | sunCC*)
# Sun C++ 4.2, 5.x and Centerline C++
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
@@ -3862,7 +4233,7 @@ m4_if([$1], [CXX], [
# PIC is the default for these OSes.
;;
- mingw* | cygwin* | pw32* | os2*)
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
# This hack is so that the source file can tell whether it is being
# built for inclusion in a dll (and should export symbols for example).
# Although the cygwin gcc ignores -fPIC, still need this for old-style
@@ -3877,11 +4248,18 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+
hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
case $host_cpu in
- hppa*64*|ia64*)
+ hppa*64*)
# +Z the default
;;
*)
@@ -3918,6 +4296,15 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+ fi
+ ;;
+ esac
else
# PORTME Check for flag to pass linker flags through the system compiler.
case $host_os in
@@ -3931,7 +4318,7 @@ m4_if([$1], [CXX], [
fi
;;
- mingw* | cygwin* | pw32* | os2*)
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
# This hack is so that the source file can tell whether it is being
# built for inclusion in a dll (and should export symbols for example).
m4_if([$1], [GCJ], [],
@@ -3960,14 +4347,34 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
;;
- linux* | k*bsd*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
- icc* | ecc* | ifort*)
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
- pgcc* | pgf77* | pgf90* | pgf95*)
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
# Portland Group compilers (*not* the Pentium gcc compiler,
# which looks to be a dead project)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
@@ -3979,25 +4386,40 @@ m4_if([$1], [CXX], [
# All Alpha code is PIC.
_LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
;;
- xl*)
- # IBM XL C 8.0/Fortran 10.1 on PPC
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
;;
*)
case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
*Sun\ C*)
# Sun C 5.9
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
;;
- *Sun\ F*)
- # Sun Fortran 8.3 passes all unrecognized flags to the linker
- _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ *Intel*\ [[CF]]*Compiler*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ *Portland\ Group*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
;;
esac
;;
@@ -4029,7 +4451,7 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
case $cc_basename in
- f77* | f90* | f95*)
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
@@ -4086,9 +4508,11 @@ case $host_os in
_LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
;;
esac
-AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
-_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
- [How to pass a linker flag through the compiler])
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
#
# Check to make sure the PIC flag actually works.
@@ -4107,6 +4531,8 @@ fi
_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
[Additional compiler flags for building library objects])
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
#
# Check to make sure the static flag actually works.
#
@@ -4127,6 +4553,7 @@ _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
m4_defun([_LT_LINKER_SHLIBS],
[AC_REQUIRE([LT_PATH_LD])dnl
AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_DECL_EGREP])dnl
m4_require([_LT_DECL_SED])dnl
@@ -4135,27 +4562,40 @@ m4_require([_LT_TAG_COMPILER])dnl
AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
m4_if([$1], [CXX], [
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
case $host_os in
aix[[4-9]]*)
# If we're using GNU nm, then we don't want the "-C" option.
# -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global defined
+ # symbols, whereas GNU nm marks them as "W".
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
else
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
fi
;;
pw32*)
_LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
- ;;
- cygwin* | mingw*)
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
*)
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
+ ;;
esac
- _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
], [
runpath_var=
_LT_TAGVAR(allow_undefined_flag, $1)=
@@ -4170,7 +4610,6 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=no
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
- _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
_LT_TAGVAR(hardcode_libdir_separator, $1)=
_LT_TAGVAR(hardcode_minus_L, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
@@ -4200,7 +4639,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
extract_expsyms_cmds=
case $host_os in
- cygwin* | mingw* | pw32*)
+ cygwin* | mingw* | pw32* | cegcc*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
@@ -4215,10 +4654,39 @@ dnl Note also adjust exclude_expsyms for C++ above.
openbsd*)
with_gnu_ld=no
;;
+ linux* | k*bsd*-gnu | gnu*)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
esac
_LT_TAGVAR(ld_shlibs, $1)=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
# If archive_cmds runs LD, not CC, wlarc should be empty
wlarc='${wl}'
@@ -4236,6 +4704,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
fi
supports_anon_versioning=no
case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
*\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
*\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
*\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
@@ -4251,11 +4720,12 @@ dnl Note also adjust exclude_expsyms for C++ above.
_LT_TAGVAR(ld_shlibs, $1)=no
cat <<_LT_EOF 1>&2
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** Warning: the GNU linker, at least up to release 2.19, is reported
*** to be unable to reliably create shared libraries on AIX.
*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
_LT_EOF
fi
@@ -4287,14 +4757,16 @@ _LT_EOF
fi
;;
- cygwin* | mingw* | pw32*)
+ cygwin* | mingw* | pw32* | cegcc*)
# _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
# as there is no search path for DLLs.
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_TAGVAR(always_export_symbols, $1)=no
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
@@ -4312,6 +4784,11 @@ _LT_EOF
fi
;;
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
interix[[3-9]]*)
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -4327,7 +4804,7 @@ _LT_EOF
_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
- gnu* | linux* | tpf* | k*bsd*-gnu)
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
tmp_diet=no
if test "$host_os" = linux-dietlibc; then
case $cc_basename in
@@ -4337,15 +4814,16 @@ _LT_EOF
if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
&& test "$tmp_diet" = no
then
- tmp_addflag=
+ tmp_addflag=' $pic_flag'
tmp_sharedflag='-shared'
case $cc_basename,$host_cpu in
pgcc*) # Portland Group C compiler
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag'
;;
- pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag -Mnomain' ;;
ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
tmp_addflag=' -i_dynamic' ;;
@@ -4353,13 +4831,20 @@ _LT_EOF
tmp_addflag=' -i_dynamic -nofor_main' ;;
ifc* | ifort*) # Intel Fortran compiler
tmp_addflag=' -nofor_main' ;;
- xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
tmp_sharedflag='-qmkshrobj'
tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ ;;
esac
case `$CC -V 2>&1 | sed 5q` in
*Sun\ C*) # Sun C 5.9
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
_LT_TAGVAR(compiler_needs_object, $1)=yes
tmp_sharedflag='-G' ;;
*Sun\ F*) # Sun Fortran 8.3
@@ -4375,17 +4860,16 @@ _LT_EOF
fi
case $cc_basename in
- xlf*)
+ xlf* | bgf* | bgxlf* | mpixlf*)
# IBM XL Fortran 10.1 on PPC cannot create shared libs itself
_LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
- _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
- _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
if test "x$supports_anon_versioning" = xyes; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
echo "local: *; };" >> $output_objdir/$libname.ver~
- $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
fi
;;
esac
@@ -4394,13 +4878,13 @@ _LT_EOF
fi
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
fi
;;
@@ -4418,8 +4902,8 @@ _LT_EOF
_LT_EOF
elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
@@ -4465,8 +4949,8 @@ _LT_EOF
*)
if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
@@ -4506,8 +4990,10 @@ _LT_EOF
else
# If we're using GNU nm, then we don't want the "-C" option.
# -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
else
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
fi
@@ -4569,6 +5055,7 @@ _LT_EOF
if test "$aix_use_runtimelinking" = yes; then
shared_flag="$shared_flag "'${wl}-G'
fi
+ _LT_TAGVAR(link_all_deplibs, $1)=no
else
# not using gcc
if test "$host_cpu" = ia64; then
@@ -4584,6 +5071,7 @@ _LT_EOF
fi
fi
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
# It seems that -bexpall does not export symbols beginning with
# underscore (_), so it is better to generate a list of symbols to export.
_LT_TAGVAR(always_export_symbols, $1)=yes
@@ -4593,9 +5081,9 @@ _LT_EOF
_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
# Determine the default libpath from the value encoded in an
# empty executable.
- _LT_SYS_MODULE_PATH_AIX
+ _LT_SYS_MODULE_PATH_AIX([$1])
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
if test "$host_cpu" = ia64; then
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
@@ -4604,14 +5092,19 @@ _LT_EOF
else
# Determine the default libpath from the value encoded in an
# empty executable.
- _LT_SYS_MODULE_PATH_AIX
+ _LT_SYS_MODULE_PATH_AIX([$1])
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
# Warning - without using the other run time loading flags,
# -berok will link without error, but may produce a broken library.
_LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
# This is similar to how AIX traditionally builds its shared libraries.
_LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
@@ -4638,25 +5131,69 @@ _LT_EOF
_LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
;;
- cygwin* | mingw* | pw32*)
+ cygwin* | mingw* | pw32* | cegcc*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
- # FIXME: Should let the user specify the lib program.
- _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
- _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
- _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+ esac
;;
darwin* | rhapsody*)
@@ -4669,10 +5206,6 @@ _LT_EOF
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
- freebsd1*)
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
# FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
# support. Future versions do this automatically, but an explicit c++rt0.o
# does not break anything, and helps significantly (at the cost of a little
@@ -4685,7 +5218,7 @@ _LT_EOF
;;
# Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
+ freebsd2.*)
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_minus_L, $1)=yes
@@ -4694,7 +5227,7 @@ _LT_EOF
# FreeBSD 3 and greater uses gcc -shared to do shared libraries.
freebsd* | dragonfly*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -4702,7 +5235,7 @@ _LT_EOF
hpux9*)
if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
else
_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
fi
@@ -4717,14 +5250,13 @@ _LT_EOF
;;
hpux10*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
else
_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
fi
if test "$with_gnu_ld" = no; then
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
@@ -4736,16 +5268,16 @@ _LT_EOF
;;
hpux11*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
else
@@ -4757,7 +5289,14 @@ _LT_EOF
_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ m4_if($1, [], [
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ _LT_LINKER_OPTION([if $CC understands -b],
+ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
;;
esac
fi
@@ -4785,19 +5324,34 @@ _LT_EOF
irix5* | irix6* | nonstopux*)
if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
# Try to use the -exported_symbol ld option, if it does not
# work, assume that -exports_file does not work either and
# implicitly export all symbols.
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
- AC_LINK_IFELSE(int foo(void) {},
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
- )
- LDFLAGS="$save_LDFLAGS"
+ # This should be the same for all languages, so no per-tag cache variable.
+ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+ [lt_cv_irix_exported_symbol],
+ [save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE(
+ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+ [C++], [[int foo (void) { return 0; }]],
+ [Fortran 77], [[
+ subroutine foo
+ end]],
+ [Fortran], [[
+ subroutine foo
+ end]])])],
+ [lt_cv_irix_exported_symbol=yes],
+ [lt_cv_irix_exported_symbol=no])
+ LDFLAGS="$save_LDFLAGS"])
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)='no'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
@@ -4806,7 +5360,7 @@ _LT_EOF
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
@@ -4859,17 +5413,17 @@ _LT_EOF
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_minus_L, $1)=yes
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
_LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
;;
osf3*)
if test "$GCC" = yes; then
_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
else
_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)='no'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
@@ -4879,13 +5433,13 @@ _LT_EOF
osf4* | osf5*) # as osf3* with the addition of -msym flag
if test "$GCC" = yes; then
_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
else
_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
# Both c and cxx compiler support -rpath directly
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -4898,9 +5452,9 @@ _LT_EOF
_LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
if test "$GCC" = yes; then
wlarc='${wl}'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
else
case `$CC -V 2>&1` in
*"Compilers 5.0"*)
@@ -5076,36 +5630,38 @@ x|xyes)
# Test whether the compiler implicitly links with -lc since on some
# systems, -lgcc has to come before -lc. If gcc already passes -lc
# to ld, don't add -lc before -lgcc.
- AC_MSG_CHECKING([whether -lc should be explicitly linked in])
- $RM conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
- pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
- _LT_TAGVAR(allow_undefined_flag, $1)=
- if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
- then
- _LT_TAGVAR(archive_cmds_need_lc, $1)=no
- else
- _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
- fi
- _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $RM conftest*
- AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)])
+ AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+ [$RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ ])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
;;
esac
fi
@@ -5142,9 +5698,6 @@ _LT_TAGDECL([], [no_undefined_flag], [1],
_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
[Flag to hardcode $libdir into a binary during linking.
This must work even if $libdir does not exist])
-_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
- [[If ld is used when linking, flag to hardcode $libdir into a binary
- during linking. This must work even if $libdir does not exist]])
_LT_TAGDECL([], [hardcode_libdir_separator], [1],
[Whether we need a single "-rpath" flag with a separated argument])
_LT_TAGDECL([], [hardcode_direct], [0],
@@ -5170,8 +5723,6 @@ _LT_TAGDECL([], [inherit_rpath], [0],
to runtime path list])
_LT_TAGDECL([], [link_all_deplibs], [0],
[Whether libtool must link a program against all its dependency libraries])
-_LT_TAGDECL([], [fix_srcfile_path], [1],
- [Fix the shell variable $srcfile for the compiler])
_LT_TAGDECL([], [always_export_symbols], [0],
[Set to "yes" if exported symbols are required])
_LT_TAGDECL([], [export_symbols_cmds], [2],
@@ -5182,6 +5733,8 @@ _LT_TAGDECL([], [include_expsyms], [1],
[Symbols that must always be exported])
_LT_TAGDECL([], [prelink_cmds], [2],
[Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+ [Commands necessary for finishing linking programs])
_LT_TAGDECL([], [file_list_spec], [1],
[Specify filename containing input files])
dnl FIXME: Not yet implemented
@@ -5275,37 +5828,22 @@ CC="$lt_save_CC"
])# _LT_LANG_C_CONFIG
-# _LT_PROG_CXX
-# ------------
-# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++
-# compiler, we have our own version here.
-m4_defun([_LT_PROG_CXX],
-[
-pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes])
-AC_PROG_CXX
-if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
- ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
- (test "X$CXX" != "Xg++"))) ; then
- AC_PROG_CXXCPP
-else
- _lt_caught_CXX_error=yes
-fi
-popdef([AC_MSG_ERROR])
-])# _LT_PROG_CXX
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([_LT_PROG_CXX], [])
-
-
# _LT_LANG_CXX_CONFIG([TAG])
# --------------------------
# Ensure that the configuration variables for a C++ compiler are suitably
# defined. These variables are subsequently used by _LT_CONFIG to write
# the compiler configuration to `libtool'.
m4_defun([_LT_LANG_CXX_CONFIG],
-[AC_REQUIRE([_LT_PROG_CXX])dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
AC_LANG_PUSH(C++)
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
@@ -5317,7 +5855,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=no
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
_LT_TAGVAR(hardcode_libdir_separator, $1)=
_LT_TAGVAR(hardcode_minus_L, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
@@ -5327,6 +5864,8 @@ _LT_TAGVAR(module_cmds, $1)=
_LT_TAGVAR(module_expsym_cmds, $1)=
_LT_TAGVAR(link_all_deplibs, $1)=unknown
_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
_LT_TAGVAR(no_undefined_flag, $1)=
_LT_TAGVAR(whole_archive_flag_spec, $1)=
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
@@ -5358,6 +5897,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Allow CC to be a program name with arguments.
lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
lt_save_LD=$LD
lt_save_GCC=$GCC
GCC=$GXX
@@ -5375,6 +5915,7 @@ if test "$_lt_caught_CXX_error" != yes; then
fi
test -z "${LDCXX+set}" || LD=$LDCXX
CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
compiler=$CC
_LT_TAGVAR(compiler, $1)=$CC
_LT_CC_BASENAME([$compiler])
@@ -5396,8 +5937,8 @@ if test "$_lt_caught_CXX_error" != yes; then
# Check if GNU C++ uses GNU ld as the underlying linker, since the
# archiving commands below assume that GNU ld is being used.
if test "$with_gnu_ld" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
@@ -5429,7 +5970,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
GXX=no
@@ -5527,6 +6068,7 @@ if test "$_lt_caught_CXX_error" != yes; then
fi
fi
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
# It seems that -bexpall does not export symbols beginning with
# underscore (_), so it is better to generate a list of symbols to
# export.
@@ -5537,10 +6079,10 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
# Determine the default libpath from the value encoded in an empty
# executable.
- _LT_SYS_MODULE_PATH_AIX
+ _LT_SYS_MODULE_PATH_AIX([$1])
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
if test "$host_cpu" = ia64; then
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
@@ -5549,14 +6091,19 @@ if test "$_lt_caught_CXX_error" != yes; then
else
# Determine the default libpath from the value encoded in an
# empty executable.
- _LT_SYS_MODULE_PATH_AIX
+ _LT_SYS_MODULE_PATH_AIX([$1])
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
# Warning - without using the other run time loading flags,
# -berok will link without error, but may produce a broken library.
_LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
# This is similar to how AIX traditionally builds its shared
# libraries.
@@ -5585,29 +6132,76 @@ if test "$_lt_caught_CXX_error" != yes; then
esac
;;
- cygwin* | mingw* | pw32*)
- # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
- # as there is no search path for DLLs.
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_TAGVAR(always_export_symbols, $1)=no
- _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-
- if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- _LT_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
darwin* | rhapsody*)
_LT_DARWIN_LINKER_FEATURES($1)
;;
@@ -5630,7 +6224,7 @@ if test "$_lt_caught_CXX_error" != yes; then
esac
;;
- freebsd[[12]]*)
+ freebsd2.*)
# C++ shared libraries reported to be fairly broken before
# switch to ELF
_LT_TAGVAR(ld_shlibs, $1)=no
@@ -5646,7 +6240,9 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(ld_shlibs, $1)=yes
;;
- gnu*)
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
;;
hpux9*)
@@ -5673,11 +6269,11 @@ if test "$_lt_caught_CXX_error" != yes; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test "$GXX" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
else
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
@@ -5738,7 +6334,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test "$GXX" = yes; then
@@ -5748,10 +6344,10 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
esac
fi
@@ -5781,7 +6377,7 @@ if test "$_lt_caught_CXX_error" != yes; then
case $cc_basename in
CC*)
# SGI C++
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
# Archives containing C++ object files must be created using
# "CC -ar", where "CC" is the IRIX C++ compiler. This is
@@ -5792,9 +6388,9 @@ if test "$_lt_caught_CXX_error" != yes; then
*)
if test "$GXX" = yes; then
if test "$with_gnu_ld" = no; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
fi
fi
_LT_TAGVAR(link_all_deplibs, $1)=yes
@@ -5805,7 +6401,7 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(inherit_rpath, $1)=yes
;;
- linux* | k*bsd*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
@@ -5823,7 +6419,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
@@ -5860,26 +6456,26 @@ if test "$_lt_caught_CXX_error" != yes; then
pgCC* | pgcpp*)
# Portland Group C++ compiler
case `$CC -V` in
- *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*)
+ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
_LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
rm -rf $tpldir~
$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
- compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
_LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
rm -rf $tpldir~
$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
- $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
$RANLIB $oldlib'
_LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
rm -rf $tpldir~
$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
rm -rf $tpldir~
$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
;;
- *) # Version 6 will use weak symbols
+ *) # Version 6 and above use weak symbols
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
;;
@@ -5887,7 +6483,7 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
;;
cxx*)
# Compaq C++
@@ -5906,9 +6502,9 @@ if test "$_lt_caught_CXX_error" != yes; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
;;
- xl*)
+ xl* | mpixl* | bgxl*)
# IBM XL 8.0 on PPC, with GNU ld
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
@@ -5928,13 +6524,13 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
_LT_TAGVAR(compiler_needs_object, $1)=yes
# Not sure whether something based on
# $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
# would be better.
- output_verbose_link_cmd='echo'
+ output_verbose_link_cmd='func_echo_all'
# Archives containing C++ object files must be created using
# "CC -xar", where "CC" is the Sun C++ compiler. This is
@@ -6003,7 +6599,7 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
_LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
fi
- output_verbose_link_cmd=echo
+ output_verbose_link_cmd=func_echo_all
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
@@ -6038,15 +6634,15 @@ if test "$_lt_caught_CXX_error" != yes; then
case $host in
osf3*)
_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
;;
*)
_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
echo "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
$RM $lib.exp'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
;;
@@ -6062,17 +6658,17 @@ if test "$_lt_caught_CXX_error" != yes; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test "$GXX" = yes && test "$with_gnu_ld" = no; then
_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
case $host in
osf3*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
;;
esac
@@ -6082,7 +6678,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
# FIXME: insert proper C++ library support
@@ -6118,7 +6714,7 @@ if test "$_lt_caught_CXX_error" != yes; then
solaris*)
case $cc_basename in
- CC*)
+ CC* | sunCC*)
# Sun C++ 4.2, 5.x and Centerline C++
_LT_TAGVAR(archive_cmds_need_lc,$1)=yes
_LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
@@ -6139,7 +6735,7 @@ if test "$_lt_caught_CXX_error" != yes; then
esac
_LT_TAGVAR(link_all_deplibs, $1)=yes
- output_verbose_link_cmd='echo'
+ output_verbose_link_cmd='func_echo_all'
# Archives containing C++ object files must be created using
# "CC -xar", where "CC" is the Sun C++ compiler. This is
@@ -6159,14 +6755,14 @@ if test "$_lt_caught_CXX_error" != yes; then
if test "$GXX" = yes && test "$with_gnu_ld" = no; then
_LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
if $CC --version | $GREP -v '^2\.7' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
# g++ 2.7 appears to require `-G' NOT `-shared' on this
# platform.
@@ -6177,7 +6773,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
fi
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
@@ -6231,6 +6827,10 @@ if test "$_lt_caught_CXX_error" != yes; then
CC*)
_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+ '"$_LT_TAGVAR(reload_cmds, $1)"
;;
*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
@@ -6286,6 +6886,7 @@ if test "$_lt_caught_CXX_error" != yes; then
fi # test -n "$compiler"
CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
LDCXX=$LD
LD=$lt_save_LD
GCC=$lt_save_GCC
@@ -6300,6 +6901,29 @@ AC_LANG_POP
])# _LT_LANG_CXX_CONFIG
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
# ---------------------------------
# Figure out "hidden" library dependencies from verbose
@@ -6308,6 +6932,7 @@ AC_LANG_POP
# objects, libraries and library flags.
m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
# Dependencies to place before and after the object being linked:
_LT_TAGVAR(predep_objects, $1)=
_LT_TAGVAR(postdep_objects, $1)=
@@ -6357,7 +6982,20 @@ public class foo {
}
};
_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
dnl Parse the compiler output and extract the necessary
dnl objects, libraries and library flags.
if AC_TRY_EVAL(ac_compile); then
@@ -6369,7 +7007,7 @@ if AC_TRY_EVAL(ac_compile); then
pre_test_object_deps_done=no
for p in `eval "$output_verbose_link_cmd"`; do
- case $p in
+ case ${prev}${p} in
-L* | -R* | -l*)
# Some compilers place space between "-{L,R}" and the path.
@@ -6378,13 +7016,22 @@ if AC_TRY_EVAL(ac_compile); then
test $p = "-R"; then
prev=$p
continue
- else
- prev=
fi
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
if test "$pre_test_object_deps_done" = no; then
- case $p in
- -L* | -R*)
+ case ${prev} in
+ -L | -R)
# Internal compiler library paths should come after those
# provided the user. The postdeps already come after the
# user supplied libs so there is no need to process them.
@@ -6404,8 +7051,10 @@ if AC_TRY_EVAL(ac_compile); then
_LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
fi
fi
+ prev=
;;
+ *.lto.$objext) ;; # Ignore GCC LTO objects
*.$objext)
# This assumes that the test object file only shows up
# once in the compiler output.
@@ -6441,6 +7090,7 @@ else
fi
$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
# PORTME: override above test on systems where it is broken
m4_if([$1], [CXX],
@@ -6477,7 +7127,7 @@ linux*)
solaris*)
case $cc_basename in
- CC*)
+ CC* | sunCC*)
# The more standards-conforming stlport4 library is
# incompatible with the Cstd library. Avoid specifying
# it if it's in CXXFLAGS. Ignore libCrun as
@@ -6521,32 +7171,16 @@ _LT_TAGDECL([], [compiler_lib_search_path], [1],
])# _LT_SYS_HIDDEN_LIBDEPS
-# _LT_PROG_F77
-# ------------
-# Since AC_PROG_F77 is broken, in that it returns the empty string
-# if there is no fortran compiler, we have our own version here.
-m4_defun([_LT_PROG_F77],
-[
-pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes])
-AC_PROG_F77
-if test -z "$F77" || test "X$F77" = "Xno"; then
- _lt_disable_F77=yes
-fi
-popdef([AC_MSG_ERROR])
-])# _LT_PROG_F77
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([_LT_PROG_F77], [])
-
-
# _LT_LANG_F77_CONFIG([TAG])
# --------------------------
# Ensure that the configuration variables for a Fortran 77 compiler are
# suitably defined. These variables are subsequently used by _LT_CONFIG
# to write the compiler configuration to `libtool'.
m4_defun([_LT_LANG_F77_CONFIG],
-[AC_REQUIRE([_LT_PROG_F77])dnl
-AC_LANG_PUSH(Fortran 77)
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test "X$F77" = "Xno"; then
+ _lt_disable_F77=yes
+fi
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(allow_undefined_flag, $1)=
@@ -6556,7 +7190,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=no
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
_LT_TAGVAR(hardcode_libdir_separator, $1)=
_LT_TAGVAR(hardcode_minus_L, $1)=no
_LT_TAGVAR(hardcode_automatic, $1)=no
@@ -6565,6 +7198,8 @@ _LT_TAGVAR(module_cmds, $1)=
_LT_TAGVAR(module_expsym_cmds, $1)=
_LT_TAGVAR(link_all_deplibs, $1)=unknown
_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
_LT_TAGVAR(no_undefined_flag, $1)=
_LT_TAGVAR(whole_archive_flag_spec, $1)=
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
@@ -6604,7 +7239,9 @@ if test "$_lt_disable_F77" != yes; then
# Allow CC to be a program name with arguments.
lt_save_CC="$CC"
lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
compiler=$CC
_LT_TAGVAR(compiler, $1)=$CC
_LT_CC_BASENAME([$compiler])
@@ -6658,38 +7295,24 @@ if test "$_lt_disable_F77" != yes; then
GCC=$lt_save_GCC
CC="$lt_save_CC"
+ CFLAGS="$lt_save_CFLAGS"
fi # test "$_lt_disable_F77" != yes
AC_LANG_POP
])# _LT_LANG_F77_CONFIG
-# _LT_PROG_FC
-# -----------
-# Since AC_PROG_FC is broken, in that it returns the empty string
-# if there is no fortran compiler, we have our own version here.
-m4_defun([_LT_PROG_FC],
-[
-pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes])
-AC_PROG_FC
-if test -z "$FC" || test "X$FC" = "Xno"; then
- _lt_disable_FC=yes
-fi
-popdef([AC_MSG_ERROR])
-])# _LT_PROG_FC
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([_LT_PROG_FC], [])
-
-
# _LT_LANG_FC_CONFIG([TAG])
# -------------------------
# Ensure that the configuration variables for a Fortran compiler are
# suitably defined. These variables are subsequently used by _LT_CONFIG
# to write the compiler configuration to `libtool'.
m4_defun([_LT_LANG_FC_CONFIG],
-[AC_REQUIRE([_LT_PROG_FC])dnl
-AC_LANG_PUSH(Fortran)
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+ _lt_disable_FC=yes
+fi
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(allow_undefined_flag, $1)=
@@ -6699,7 +7322,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=no
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
_LT_TAGVAR(hardcode_libdir_separator, $1)=
_LT_TAGVAR(hardcode_minus_L, $1)=no
_LT_TAGVAR(hardcode_automatic, $1)=no
@@ -6708,6 +7330,8 @@ _LT_TAGVAR(module_cmds, $1)=
_LT_TAGVAR(module_expsym_cmds, $1)=
_LT_TAGVAR(link_all_deplibs, $1)=unknown
_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
_LT_TAGVAR(no_undefined_flag, $1)=
_LT_TAGVAR(whole_archive_flag_spec, $1)=
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
@@ -6747,7 +7371,9 @@ if test "$_lt_disable_FC" != yes; then
# Allow CC to be a program name with arguments.
lt_save_CC="$CC"
lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
CC=${FC-"f95"}
+ CFLAGS=$FCFLAGS
compiler=$CC
GCC=$ac_cv_fc_compiler_gnu
@@ -6803,7 +7429,8 @@ if test "$_lt_disable_FC" != yes; then
fi # test -n "$compiler"
GCC=$lt_save_GCC
- CC="$lt_save_CC"
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
fi # test "$_lt_disable_FC" != yes
AC_LANG_POP
@@ -6840,10 +7467,12 @@ _LT_COMPILER_BOILERPLATE
_LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
lt_save_GCC=$GCC
GCC=yes
CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
compiler=$CC
_LT_TAGVAR(compiler, $1)=$CC
_LT_TAGVAR(LD, $1)="$LD"
@@ -6853,6 +7482,8 @@ _LT_CC_BASENAME([$compiler])
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
## CAVEAT EMPTOR:
## There is no encapsulation within the following macros, do not change
@@ -6872,10 +7503,82 @@ fi
AC_LANG_RESTORE
GCC=$lt_save_GCC
-CC="$lt_save_CC"
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
])# _LT_LANG_GCJ_CONFIG
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
# _LT_LANG_RC_CONFIG([TAG])
# -------------------------
# Ensure that the configuration variables for the Windows resource compiler
@@ -6907,9 +7610,11 @@ _LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
lt_save_GCC=$GCC
GCC=
CC=${RC-"windres"}
+CFLAGS=
compiler=$CC
_LT_TAGVAR(compiler, $1)=$CC
_LT_CC_BASENAME([$compiler])
@@ -6922,7 +7627,8 @@ fi
GCC=$lt_save_GCC
AC_LANG_RESTORE
-CC="$lt_save_CC"
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
])# _LT_LANG_RC_CONFIG
@@ -6942,6 +7648,13 @@ dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
# LT_PROG_RC
# ----------
AC_DEFUN([LT_PROG_RC],
@@ -6970,6 +7683,27 @@ AC_SUBST([GREP])
])
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
# _LT_DECL_SED
# ------------
# Check for a fully-functional sed program, that truncates
@@ -7062,8 +7796,8 @@ m4_defun([_LT_CHECK_SHELL_FEATURES],
# Try some XSI features
xsi_shell=no
( _lt_dummy="a/b/c"
- test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
- = c,a/b,, \
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
&& eval 'test $(( 1 + 1 )) -eq 2 \
&& test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
&& xsi_shell=yes
@@ -7102,208 +7836,162 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
])# _LT_CHECK_SHELL_FEATURES
-# _LT_PROG_XSI_SHELLFNS
-# ---------------------
-# Bourne and XSI compatible variants of some useful shell functions.
-m4_defun([_LT_PROG_XSI_SHELLFNS],
-[case $xsi_shell in
- yes)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac
-}
-
-# func_basename file
-func_basename ()
-{
- func_basename_result="${1##*/}"
-}
-
-# func_dirname_and_basename file append nondir_replacement
-# perform func_basename and func_dirname in a single function
-# call:
-# dirname: Compute the dirname of FILE. If nonempty,
-# add APPEND to the result, otherwise set result
-# to NONDIR_REPLACEMENT.
-# value returned in "$func_dirname_result"
-# basename: Compute filename of FILE.
-# value retuned in "$func_basename_result"
-# Implementation must be kept synchronized with func_dirname
-# and func_basename. For efficiency, we do not delegate to
-# those functions but instead duplicate the functionality here.
-func_dirname_and_basename ()
-{
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac
- func_basename_result="${1##*/}"
-}
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-func_stripname ()
-{
- # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
- # positional parameters, so assign one to ordinary parameter first.
- func_stripname_result=${3}
- func_stripname_result=${func_stripname_result#"${1}"}
- func_stripname_result=${func_stripname_result%"${2}"}
-}
-
-# func_opt_split
-func_opt_split ()
-{
- func_opt_split_opt=${1%%=*}
- func_opt_split_arg=${1#*=}
-}
-
-# func_lo2o object
-func_lo2o ()
-{
- case ${1} in
- *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
- *) func_lo2o_result=${1} ;;
- esac
-}
-
-# func_xform libobj-or-source
-func_xform ()
-{
- func_xform_result=${1%.*}.lo
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
- func_arith_result=$(( $[*] ))
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
- func_len_result=${#1}
-}
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
-_LT_EOF
- ;;
- *) # Bourne compatible functions.
- cat << \_LT_EOF >> "$cfgfile"
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
- # Extract subdirectory from the argument.
- func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
- if test "X$func_dirname_result" = "X${1}"; then
- func_dirname_result="${3}"
- else
- func_dirname_result="$func_dirname_result${2}"
- fi
-}
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"])
-# func_basename file
-func_basename ()
-{
- func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
-}
+ _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}])
-dnl func_dirname_and_basename
-dnl A portable version of this function is already defined in general.m4sh
-dnl so there is no need for it here.
+ _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+ func_split_long_opt_name=${1%%=*}
+ func_split_long_opt_arg=${1#*=}])
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-# func_strip_suffix prefix name
-func_stripname ()
-{
- case ${2} in
- .*) func_stripname_result=`$ECHO "X${3}" \
- | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
- *) func_stripname_result=`$ECHO "X${3}" \
- | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
- esac
-}
+ _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+ func_split_short_opt_arg=${1#??}
+ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
-# sed scripts:
-my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q'
-my_sed_long_arg='1s/^-[[^=]]*=//'
+ _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac])
-# func_opt_split
-func_opt_split ()
-{
- func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
- func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
-}
+ _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo])
-# func_lo2o object
-func_lo2o ()
-{
- func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
-}
+ _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))])
-# func_xform libobj-or-source
-func_xform ()
-{
- func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'`
-}
+ _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}])
+fi
-# func_arith arithmetic-term...
-func_arith ()
-{
- func_arith_result=`expr "$[@]"`
-}
+if test x"$lt_shell_append" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"])
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
- func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len`
-}
+ _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+ func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+ eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
-_LT_EOF
-esac
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
-case $lt_shell_append in
- yes)
- cat << \_LT_EOF >> "$cfgfile"
+if test x"$_lt_function_replace_fail" = x":"; then
+ AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
- eval "$[1]+=\$[2]"
-}
-_LT_EOF
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
;;
- *)
- cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
- eval "$[1]=\$$[1]\$[2]"
-}
-
-_LT_EOF
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
;;
- esac
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+ [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+ [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4
index e970119..5d9acd8 100644
--- a/m4/ltoptions.m4
+++ b/m4/ltoptions.m4
@@ -1,13 +1,14 @@
# Helper functions for option handling. -*- Autoconf -*-
#
-# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
-# serial 6 ltoptions.m4
+# serial 7 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
@@ -125,7 +126,7 @@ LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
-*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
@@ -133,13 +134,13 @@ case $host in
esac
test -z "$AS" && AS=as
-_LT_DECL([], [AS], [0], [Assembler program])dnl
+_LT_DECL([], [AS], [1], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
-_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
-_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
@@ -325,9 +326,24 @@ dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
- [AS_HELP_STRING([--with-pic],
+ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
- [pic_mode="$withval"],
+ [lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for lt_pkg in $withval; do
+ IFS="$lt_save_ifs"
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
[pic_mode=default])
test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
diff --git a/m4/ltsugar.m4 b/m4/ltsugar.m4
index 0d258e0..9000a05 100644
--- a/m4/ltsugar.m4
+++ b/m4/ltsugar.m4
@@ -1,13 +1,13 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
-# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
-# Written by Gary V. Vaughan, 2004
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
-# serial 5 ltsugar.m4
+# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
@@ -63,14 +63,14 @@ m4_define([lt_append],
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
-[m4_if([$2], [], [],
- [m4_if([$4], [], [],
- [lt_join(m4_quote(m4_default([$1], [[, ]])),
- lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_prefix, [$2],
- [m4_foreach(_Lt_suffix, lt_car([m4_shiftn(3, $@)]),
- [_Lt_prefix[]$3[]_Lt_suffix ])])))))])])dnl
-])
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
diff --git a/m4/ltversion.m4 b/m4/ltversion.m4
index 45cb155..07a8602 100644
--- a/m4/ltversion.m4
+++ b/m4/ltversion.m4
@@ -7,17 +7,17 @@
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
-# Generated from ltversion.in.
+# @configure_input@
-# serial 2976 ltversion.m4
+# serial 3337 ltversion.m4
# This file is part of GNU Libtool
-m4_define([LT_PACKAGE_VERSION], [2.2.4])
-m4_define([LT_PACKAGE_REVISION], [1.2976])
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.2.4'
-macro_revision='1.2976'
+[macro_version='2.4.2'
+macro_revision='1.3337'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])
diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4
index 637bb20..c573da9 100644
--- a/m4/lt~obsolete.m4
+++ b/m4/lt~obsolete.m4
@@ -1,13 +1,13 @@
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
-# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
-# serial 4 lt~obsolete.m4
+# serial 5 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
@@ -77,7 +77,6 @@ m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
-m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
@@ -90,3 +89,10 @@ m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
diff --git a/m4/stl_hash.m4 b/m4/stl_hash.m4
index 08813c9..0722b14 100644
--- a/m4/stl_hash.m4
+++ b/m4/stl_hash.m4
@@ -1,60 +1,72 @@
-# We check two things: where the include file is for hash_map, and
-# what namespace hash_map lives in within that include file. We
+# We check two things: where the include file is for
+# unordered_map/hash_map (we prefer the first form), and what
+# namespace unordered/hash_map lives in within that include file. We
# include AC_TRY_COMPILE for all the combinations we've seen in the
-# wild. We define one of HAVE_HASH_MAP or HAVE_EXT_HASH_MAP depending
-# on location, and HASH_NAMESPACE to be the namespace hash_map is
-# defined in.
-#
-# Ideally we'd use AC_CACHE_CHECK, but that only lets us store one value
-# at a time, and we need to store two (filename and namespace).
-# prints messages itself, so we have to do the message-printing ourselves
-# via AC_MSG_CHECKING + AC_MSG_RESULT. (TODO(csilvers): can we cache?)
+# 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.
+# This also checks if unordered map exists.
AC_DEFUN([AC_CXX_STL_HASH],
- [AC_MSG_CHECKING(the location of hash_map)
- AC_LANG_SAVE
+ [
+ AC_MSG_CHECKING(the location of hash_map)
+ AC_LANG_SAVE
AC_LANG_CPLUSPLUS
- ac_cv_cxx_hash_map_header=""
- ac_cv_cxx_hash_map_class=""
- for location in [tr1/unordered_map ext/hash_map hash_map]; do
- for namespace in [std::tr1 __gnu_cxx "" std stdext]; do
- for name in [unordered_map hash_map]; do
-
- if test -z "$ac_cv_cxx_hash_map_header"; then
-
- # On OSX 1.5 / GCC 4.0.1 (the standard compiler on that platform),
- # calling find() on a const unordered_map does not compile. So, we
- # include a call to find() in our test to detect this broken
- # implementation and avoid using it. Note that ext/hash_map works
- # fine on this platform, so we'll end up using that.
- AC_TRY_COMPILE([#include <$location>],
- [const ${namespace}::$name<int, int> t;
- t.find(1);],
- [ac_cv_cxx_hash_map_header="<$location>";
- ac_cv_cxx_hash_namespace="$namespace";
- ac_cv_cxx_hash_map_class="$name";])
- fi
- done
+ ac_cv_cxx_hash_map=""
+ # First try unordered_map, but not on gcc's before 4.2 -- I've
+ # seen unexplainable unordered_map bugs with -O2 on older gcc's.
+ AC_TRY_COMPILE([#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
+ # error GCC too old for unordered_map
+ #endif
+ ],
+ [/* no program body necessary */],
+ [stl_hash_old_gcc=no],
+ [stl_hash_old_gcc=yes])
+ for location in unordered_map tr1/unordered_map; do
+ for namespace in std std::tr1; do
+ if test -z "$ac_cv_cxx_hash_map" -a "$stl_hash_old_gcc" != yes; then
+ # Some older gcc's have a buggy tr1, so test a bit of code.
+ AC_TRY_COMPILE([#include <$location>],
+ [const ${namespace}::unordered_map<int, int> t;
+ return t.find(5) == t.end();],
+ [ac_cv_cxx_hash_map="<$location>";
+ ac_cv_cxx_hash_namespace="$namespace";
+ ac_cv_cxx_hash_map_class="unordered_map";])
+ fi
done
done
- ac_cv_cxx_hash_set_header=`echo "$ac_cv_cxx_hash_map_header" | sed s/map/set/`;
+ # Now try hash_map
+ for location in ext/hash_map hash_map; do
+ for namespace in __gnu_cxx "" std stdext; do
+ if test -z "$ac_cv_cxx_hash_map"; then
+ AC_TRY_COMPILE([#include <$location>],
+ [${namespace}::hash_map<int, int> t],
+ [ac_cv_cxx_hash_map="<$location>";
+ ac_cv_cxx_hash_namespace="$namespace";
+ ac_cv_cxx_hash_map_class="hash_map";])
+ fi
+ done
+ done
+ ac_cv_cxx_hash_set=`echo "$ac_cv_cxx_hash_map" | sed s/map/set/`;
ac_cv_cxx_hash_set_class=`echo "$ac_cv_cxx_hash_map_class" | sed s/map/set/`;
- if test -n "$ac_cv_cxx_hash_map_header"; then
+ if test -n "$ac_cv_cxx_hash_map"; then
AC_DEFINE(HAVE_HASH_MAP, 1, [define if the compiler has hash_map])
AC_DEFINE(HAVE_HASH_SET, 1, [define if the compiler has hash_set])
- AC_DEFINE_UNQUOTED(HASH_MAP_H,$ac_cv_cxx_hash_map_header,
- [the location of <hash_map>])
- AC_DEFINE_UNQUOTED(HASH_SET_H,$ac_cv_cxx_hash_set_header,
- [the location of <hash_set>])
+ AC_DEFINE_UNQUOTED(HASH_MAP_H,$ac_cv_cxx_hash_map,
+ [the location of <unordered_map> or <hash_map>])
+ AC_DEFINE_UNQUOTED(HASH_SET_H,$ac_cv_cxx_hash_set,
+ [the location of <unordered_set> or <hash_set>])
+ AC_DEFINE_UNQUOTED(HASH_NAMESPACE,$ac_cv_cxx_hash_namespace,
+ [the namespace of hash_map/hash_set])
AC_DEFINE_UNQUOTED(HASH_MAP_CLASS,$ac_cv_cxx_hash_map_class,
- [the name of <hash_set>])
+ [the name of <hash_map>])
AC_DEFINE_UNQUOTED(HASH_SET_CLASS,$ac_cv_cxx_hash_set_class,
[the name of <hash_set>])
- AC_DEFINE_UNQUOTED(HASH_NAMESPACE,$ac_cv_cxx_hash_namespace,
- [the namespace of hash_map/hash_set])
- AC_MSG_RESULT([$ac_cv_cxx_hash_map_header])
+ AC_MSG_RESULT([$ac_cv_cxx_hash_map])
else
AC_MSG_RESULT()
AC_MSG_WARN([could not find an STL hash_map])
fi
])
+
diff --git a/missing b/missing
index 1c8ff70..db98974 100755
--- a/missing
+++ b/missing
@@ -1,11 +1,10 @@
#! /bin/sh
-# Common stub for a few missing GNU programs while installing.
+# Common wrapper for a few potentially missing GNU programs.
-scriptversion=2006-05-10.23
+scriptversion=2013-10-28.13; # UTC
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
-# Free Software Foundation, Inc.
-# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -18,9 +17,7 @@ scriptversion=2006-05-10.23
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -28,66 +25,40 @@ scriptversion=2006-05-10.23
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
- echo 1>&2 "Try \`$0 --help' for more information"
+ echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
-run=:
-sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
-sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
-
-# In the cases where this matters, `missing' is being run in the
-# srcdir already.
-if test -f configure.ac; then
- configure_ac=configure.ac
-else
- configure_ac=configure.in
-fi
+case $1 in
-msg="missing on your system"
+ --is-lightweight)
+ # Used by our autoconf macros to check whether the available missing
+ # script is modern enough.
+ exit 0
+ ;;
-case $1 in
---run)
- # Try to run requested program, and just exit if it succeeds.
- run=
- shift
- "$@" && exit 0
- # Exit code 63 means version mismatch. This often happens
- # when the user try to use an ancient version of a tool on
- # a file that requires a minimum version. In this case we
- # we should proceed has if the program had been absent, or
- # if --run hadn't been passed.
- if test $? = 63; then
- run=:
- msg="probably too old"
- fi
- ;;
+ --run)
+ # Back-compat with the calling convention used by older automake.
+ shift
+ ;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
-Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
-error status if there is no known handling for PROGRAM.
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
- --run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
- aclocal touch file \`aclocal.m4'
- autoconf touch file \`configure'
- autoheader touch file \`config.h.in'
- autom4te touch the output file, or create a stub one
- automake touch all \`Makefile.in' files
- bison create \`y.tab.[ch]', if possible, from existing .[ch]
- flex create \`lex.yy.c', if possible, from existing .c
- help2man touch the output file
- lex create \`lex.yy.c', if possible, from existing .c
- makeinfo touch the output file
- tar try tar, gnutar, gtar, then tar without non-portable flags
- yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+ aclocal autoconf autoheader autom4te automake makeinfo
+ bison yacc flex lex help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
@@ -99,269 +70,146 @@ Send bug reports to <bug-automake@gnu.org>."
;;
-*)
- echo 1>&2 "$0: Unknown \`$1' option"
- echo 1>&2 "Try \`$0 --help' for more information"
+ echo 1>&2 "$0: unknown '$1' option"
+ echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
-# Now exit if we have it, but it failed. Also exit now if we
-# don't have it and --version was passed (most likely to detect
-# the program).
-case $1 in
- lex|yacc)
- # Not GNU programs, they don't have --version.
- ;;
-
- tar)
- if test -n "$run"; then
- echo 1>&2 "ERROR: \`tar' requires --run"
- exit 1
- elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
- exit 1
- fi
- ;;
-
- *)
- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
- # We have it, but it failed.
- exit 1
- elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
- # Could not run --version or --help. This is probably someone
- # running `$TOOL --version' or `$TOOL --help' to check whether
- # $TOOL exists and not knowing $TOOL uses missing.
- exit 1
- fi
- ;;
-esac
-
-# If it does not exist, or fails to run (possibly an outdated version),
-# try to emulate it.
-case $1 in
- aclocal*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`acinclude.m4' or \`${configure_ac}'. You might want
- to install the \`Automake' and \`Perl' packages. Grab them from
- any GNU archive site."
- touch aclocal.m4
- ;;
-
- autoconf)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`${configure_ac}'. You might want to install the
- \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
- archive site."
- touch configure
- ;;
-
- autoheader)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`acconfig.h' or \`${configure_ac}'. You might want
- to install the \`Autoconf' and \`GNU m4' packages. Grab them
- from any GNU archive site."
- files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
- test -z "$files" && files="config.h"
- touch_files=
- for f in $files; do
- case $f in
- *:*) touch_files="$touch_files "`echo "$f" |
- sed -e 's/^[^:]*://' -e 's/:.*//'`;;
- *) touch_files="$touch_files $f.in";;
- esac
- done
- touch $touch_files
- ;;
-
- automake*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
- You might want to install the \`Automake' and \`Perl' packages.
- Grab them from any GNU archive site."
- find . -type f -name Makefile.am -print |
- sed 's/\.am$/.in/' |
- while read f; do touch "$f"; done
- ;;
-
- autom4te)
- echo 1>&2 "\
-WARNING: \`$1' is needed, but is $msg.
- You might have modified some files without having the
- proper tools for further handling them.
- You can get \`$1' as part of \`Autoconf' from any GNU
- archive site."
-
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -f "$file"; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo "#! /bin/sh"
- echo "# Created by GNU Automake missing as a replacement of"
- echo "# $ $@"
- echo "exit 0"
- chmod +x $file
- exit 1
- fi
- ;;
-
- bison|yacc)
- echo 1>&2 "\
-WARNING: \`$1' $msg. You should only need it if
- you modified a \`.y' file. You may need the \`Bison' package
- in order for those modifications to take effect. You can get
- \`Bison' from any GNU archive site."
- rm -f y.tab.c y.tab.h
- if test $# -ne 1; then
- eval LASTARG="\${$#}"
- case $LASTARG in
- *.y)
- SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" y.tab.c
- fi
- SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" y.tab.h
- fi
- ;;
- esac
- fi
- if test ! -f y.tab.h; then
- echo >y.tab.h
- fi
- if test ! -f y.tab.c; then
- echo 'main() { return 0; }' >y.tab.c
- fi
- ;;
-
- lex|flex)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a \`.l' file. You may need the \`Flex' package
- in order for those modifications to take effect. You can get
- \`Flex' from any GNU archive site."
- rm -f lex.yy.c
- if test $# -ne 1; then
- eval LASTARG="\${$#}"
- case $LASTARG in
- *.l)
- SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" lex.yy.c
- fi
- ;;
- esac
- fi
- if test ! -f lex.yy.c; then
- echo 'main() { return 0; }' >lex.yy.c
- fi
- ;;
-
- help2man)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a dependency of a manual page. You may need the
- \`Help2man' package in order for those modifications to take
- effect. You can get \`Help2man' from any GNU archive site."
-
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -f "$file"; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo ".ab help2man is required to generate this page"
- exit 1
- fi
- ;;
-
- makeinfo)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a \`.texi' or \`.texinfo' file, or any other file
- indirectly affecting the aspect of the manual. The spurious
- call might also be the consequence of using a buggy \`make' (AIX,
- DU, IRIX). You might want to install the \`Texinfo' package or
- the \`GNU make' package. Grab either from any GNU archive site."
- # The file to touch is that specified with -o ...
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -z "$file"; then
- # ... or it is the one specified with @setfilename ...
- infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
- file=`sed -n '
- /^@setfilename/{
- s/.* \([^ ]*\) *$/\1/
- p
- q
- }' $infile`
- # ... or it is derived from the source name (dir/f.texi becomes f.info)
- test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
- fi
- # If the file does not exist, the user really needs makeinfo;
- # let's fail without touching anything.
- test -f $file || exit 1
- touch $file
- ;;
-
- tar)
- shift
-
- # We have already tried tar in the generic part.
- # Look for gnutar/gtar before invocation to avoid ugly error
- # messages.
- if (gnutar --version > /dev/null 2>&1); then
- gnutar "$@" && exit 0
- fi
- if (gtar --version > /dev/null 2>&1); then
- gtar "$@" && exit 0
- fi
- firstarg="$1"
- if shift; then
- case $firstarg in
- *o*)
- firstarg=`echo "$firstarg" | sed s/o//`
- tar "$firstarg" "$@" && exit 0
- ;;
- esac
- case $firstarg in
- *h*)
- firstarg=`echo "$firstarg" | sed s/h//`
- tar "$firstarg" "$@" && exit 0
- ;;
- esac
- fi
-
- echo 1>&2 "\
-WARNING: I can't seem to be able to run \`tar' with the given arguments.
- You may want to install GNU tar or Free paxutils, or check the
- command line arguments."
- exit 1
- ;;
-
- *)
- echo 1>&2 "\
-WARNING: \`$1' is needed, and is $msg.
- You might have modified some files without having the
- proper tools for further handling them. Check the \`README' file,
- it often tells you about the needed prerequisites for installing
- this package. You may also peek at any GNU archive site, in case
- some other package would contain this missing \`$1' program."
- exit 1
- ;;
-esac
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch. This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+ msg="probably too old"
+elif test $st -eq 127; then
+ # Program was missing.
+ msg="missing on your system"
+else
+ # Program was found and executed, but failed. Give up.
+ exit $st
+fi
-exit 0
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+ case $1 in
+ aclocal|automake)
+ echo "The '$1' program is part of the GNU Automake package:"
+ echo "<$gnu_software_URL/automake>"
+ echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/autoconf>"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ autoconf|autom4te|autoheader)
+ echo "The '$1' program is part of the GNU Autoconf package:"
+ echo "<$gnu_software_URL/autoconf/>"
+ echo "It also requires GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ esac
+}
+
+give_advice ()
+{
+ # Normalize program name to check for.
+ normalized_program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+ printf '%s\n' "'$1' is $msg."
+
+ configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+ case $normalized_program in
+ autoconf*)
+ echo "You should only need it if you modified 'configure.ac',"
+ echo "or m4 files included by it."
+ program_details 'autoconf'
+ ;;
+ autoheader*)
+ echo "You should only need it if you modified 'acconfig.h' or"
+ echo "$configure_deps."
+ program_details 'autoheader'
+ ;;
+ automake*)
+ echo "You should only need it if you modified 'Makefile.am' or"
+ echo "$configure_deps."
+ program_details 'automake'
+ ;;
+ aclocal*)
+ echo "You should only need it if you modified 'acinclude.m4' or"
+ echo "$configure_deps."
+ program_details 'aclocal'
+ ;;
+ autom4te*)
+ echo "You might have modified some maintainer files that require"
+ echo "the 'autom4te' program to be rebuilt."
+ program_details 'autom4te'
+ ;;
+ bison*|yacc*)
+ echo "You should only need it if you modified a '.y' file."
+ echo "You may want to install the GNU Bison package:"
+ echo "<$gnu_software_URL/bison/>"
+ ;;
+ lex*|flex*)
+ echo "You should only need it if you modified a '.l' file."
+ echo "You may want to install the Fast Lexical Analyzer package:"
+ echo "<$flex_URL>"
+ ;;
+ help2man*)
+ echo "You should only need it if you modified a dependency" \
+ "of a man page."
+ echo "You may want to install the GNU Help2man package:"
+ echo "<$gnu_software_URL/help2man/>"
+ ;;
+ makeinfo*)
+ echo "You should only need it if you modified a '.texi' file, or"
+ echo "any other file indirectly affecting the aspect of the manual."
+ echo "You might want to install the Texinfo package:"
+ echo "<$gnu_software_URL/texinfo/>"
+ echo "The spurious makeinfo call might also be the consequence of"
+ echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+ echo "want to install GNU make:"
+ echo "<$gnu_software_URL/make/>"
+ ;;
+ *)
+ echo "You might have modified some files without having the proper"
+ echo "tools for further handling them. Check the 'README' file, it"
+ echo "often tells you about the needed prerequisites for installing"
+ echo "this package. You may also peek at any GNU archive site, in"
+ echo "case some other package contains this missing '$1' program."
+ ;;
+ esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+ -e '2,$s/^/ /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
# End:
diff --git a/more_tests/Makefile b/more_tests/Makefile
new file mode 100755
index 0000000..286cf0f
--- /dev/null
+++ b/more_tests/Makefile
@@ -0,0 +1,41 @@
+# Additional tests to run before releasing a package.
+#
+# Run like:
+# make PACKAGE=/path/to/protobuf-VERSION.tar.gz
+#
+# Some of these tests require tools or make assumptions that may not be
+# available on end-user machines, so these cannot be part of "make check". For
+# example, we test that the headers compile with strict warning settings, but
+# since different compilers produce wildly different warnings we cannot assume
+# that this test will pass everywhere. If we ran it as part of "make check",
+# it could unnecessarily block users from running the real tests just because
+# their compiler produces some extra warnings that probably aren't a big deal.
+# So we run it separately.
+
+all: header_warning_test
+
+clean:
+ rm -rf src target header_warning_test.cc header_warning_test.o header_warning_test
+
+# Unpack the package into src, then install it into target.
+PACKAGE=protobuf.tar.gz
+
+src: $(PACKAGE)
+ tar zxvf $(PACKAGE)
+ mv `basename $(PACKAGE) .tar.gz` src
+
+target: src
+ (cd src && ./configure --prefix=$$PWD/../target --disable-shared)
+ (cd src && make -j4 check)
+ (cd src && make install)
+
+# Verify that headers produce no warnings even under strict settings.
+header_warning_test.cc: target
+ ( (cd target/include && find google/protobuf -name '*.h') | \
+ awk '{print "#include \""$$1"\""} ' > header_warning_test.cc )
+
+header_warning_test: header_warning_test.cc
+ # TODO(kenton): Consider adding -pedantic and -Weffc++. Currently these
+ # produce tons of extra warnings so we'll need to do some work first.
+ g++ -Itarget/include -Wall -Werror -Wsign-compare -O2 -c header_warning_test.cc
+ touch header_warning_test
diff --git a/post_process_dist.sh b/post_process_dist.sh
new file mode 100755
index 0000000..7b2e599
--- /dev/null
+++ b/post_process_dist.sh
@@ -0,0 +1,60 @@
+#! /bin/sh
+
+# This script takes the result of "make dist" and:
+# 1) Unpacks it.
+# 2) Ensures all contents are user-writable. Some version control systems
+# keep code read-only until you explicitly ask to edit it, and the normal
+# "make dist" process does not correct for this, so the result is that
+# the entire dist is still marked read-only when unpacked, which is
+# annoying. So, we fix it.
+# 3) Convert MSVC project files to MSVC 2005, so that anyone who has version
+# 2005 *or* 2008 can open them. (In version control, we keep things in
+# MSVC 2008 format since that's what we use in development.)
+# 4) Uses the result to create .tar.gz, .tar.bz2, and .zip versions and
+# deposites them in the "dist" directory. In the .zip version, all
+# non-testdata .txt files are converted to Windows-style line endings.
+# 5) Cleans up after itself.
+
+if [ "$1" == "" ]; then
+ echo "USAGE: $1 DISTFILE" >&2
+ exit 1
+fi
+
+if [ ! -e $1 ]; then
+ echo $1": File not found." >&2
+ exit 1
+fi
+
+set -ex
+
+BASENAME=`basename $1 .tar.gz`
+
+# Create a directory called "dist", copy the tarball there and unpack it.
+mkdir dist
+cp $1 dist
+cd dist
+tar zxvf $BASENAME.tar.gz
+rm $BASENAME.tar.gz
+
+# Set the entire contents to be user-writable.
+chmod -R u+w $BASENAME
+
+# Convert the MSVC projects to MSVC 2005 format.
+cd $BASENAME/vsprojects
+./convert2008to2005.sh
+cd ..
+
+# Build the dist again in .tar.gz and .tar.bz2 formats.
+./configure
+make dist-gzip
+make dist-bzip2
+
+# Convert all text files to use DOS-style line endings, then build a .zip
+# distribution.
+todos *.txt */*.txt
+make dist-zip
+
+# Clean up.
+mv $BASENAME.tar.gz $BASENAME.tar.bz2 $BASENAME.zip ..
+cd ..
+rm -rf $BASENAME
diff --git a/protobuf.pc.in b/protobuf.pc.in
index 8a53a43..29f2487 100644
--- a/protobuf.pc.in
+++ b/protobuf.pc.in
@@ -6,7 +6,8 @@ includedir=@includedir@
Name: Protocol Buffers
Description: Google's Data Interchange Format
Version: @VERSION@
-Libs: -L${libdir} -lprotobuf @LIBS@ @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
+Libs: -L${libdir} -lprotobuf @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
+Libs.private: @LIBS@
Cflags: -I${includedir} @PTHREAD_CFLAGS@
# Commented out because it crashes pkg-config *sigh*:
# http://bugs.freedesktop.org/show_bug.cgi?id=13265
diff --git a/python/README.txt b/python/README.txt
index 96f1a73..da044af 100644
--- a/python/README.txt
+++ b/python/README.txt
@@ -6,7 +6,7 @@ This directory contains the Python Protocol Buffers runtime library.
Normally, this directory comes as part of the protobuf package, available
from:
- http://code.google.com/p/protobuf
+ https://developers.google.com/protocol-buffers/
The complete package includes the C++ source code, which includes the
Protocol Compiler (protoc). If you downloaded this package from PyPI
@@ -43,9 +43,13 @@ Installation
$ protoc --version
-4) Run the tests:
+4) Build and run the tests:
- $ python setup.py test
+ $ python setup.py build
+ $ python setup.py google_test
+
+ If you want to test c++ implementation, run:
+ $ python setup.py test --cpp_implementation
If some tests fail, this library may not work correctly on your
system. Continue at your own risk.
@@ -61,8 +65,13 @@ Installation
5) Install:
$ python setup.py install
+ or:
+ $ python setup.py install --cpp_implementation
This step may require superuser privileges.
+ NOTE: To use C++ implementation, you need to install C++ protobuf runtime
+ library of the same version and export the environment variable before this
+ step. See the "C++ Implementation" section below for more details.
Usage
=====
@@ -70,4 +79,27 @@ Usage
The complete documentation for Protocol Buffers is available via the
web at:
- http://code.google.com/apis/protocolbuffers/
+ https://developers.google.com/protocol-buffers/
+
+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
+ $ export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION=2
+
+You need to export this variable before running setup.py script to build and
+install the extension. You must also set the variable at runtime, 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.
+It is strongly recommended to run `python setup.py test` after setting the
+variable to "cpp", so the tests will be against C++ implemented Python
+messages.
+
diff --git a/python/ez_setup.py b/python/ez_setup.py
index b7a9849..3aec98e 100755
--- a/python/ez_setup.py
+++ b/python/ez_setup.py
@@ -2,7 +2,7 @@
# This file was obtained from:
# http://peak.telecommunity.com/dist/ez_setup.py
-# on 2009/4/17.
+# on 2011/1/21.
"""Bootstrap setuptools installation
@@ -19,7 +19,7 @@ the appropriate options to ``use_setuptools()``.
This file can also be run as a script to install or upgrade setuptools.
"""
import sys
-DEFAULT_VERSION = "0.6c9"
+DEFAULT_VERSION = "0.6c11"
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
md5_data = {
@@ -33,6 +33,14 @@ md5_data = {
'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
+ 'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
+ 'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
+ 'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
+ 'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
+ 'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
+ 'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
+ 'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
+ 'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
@@ -99,6 +107,7 @@ def use_setuptools(
except ImportError:
return do_download()
try:
+ return do_download()
pkg_resources.require("setuptools>="+version); return
except pkg_resources.VersionConflict, e:
if was_imported:
@@ -109,11 +118,11 @@ def use_setuptools(
"\n\n(Currently using %r)"
) % (version, e.args[0])
sys.exit(2)
- else:
- del pkg_resources, sys.modules['pkg_resources'] # reload ok
- return do_download()
except pkg_resources.DistributionNotFound:
- return do_download()
+ pass
+
+ del pkg_resources, sys.modules['pkg_resources'] # reload ok
+ return do_download()
def download_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
@@ -273,9 +282,3 @@ if __name__=='__main__':
update_md5(sys.argv[2:])
else:
main(sys.argv[1:])
-
-
-
-
-
-
diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py
index aa4ab96..6da8bb0 100755
--- a/python/google/protobuf/descriptor.py
+++ b/python/google/protobuf/descriptor.py
@@ -1,6 +1,6 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -28,15 +28,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-# TODO(robinson): We probably need to provide deep-copy methods for
-# descriptor types. When a FieldDescriptor is passed into
-# Descriptor.__init__(), we should make a deep copy and then set
-# containing_type on it. Alternatively, we could just get
-# rid of containing_type (iit's not needed for reflection.py, at least).
+# Needs to stay compatible with Python 2.5 due to GAE.
#
-# TODO(robinson): Print method?
-#
-# TODO(robinson): Useful __repr__?
+# Copyright 2007 Google Inc. All Rights Reserved.
"""Descriptors essentially contain exactly the information found in a .proto
file, in types that make this information accessible in Python.
@@ -44,11 +38,28 @@ file, in types that make this information accessible in Python.
__author__ = 'robinson@google.com (Will Robinson)'
+from google.protobuf.internal import api_implementation
+
+
+if api_implementation.Type() == 'cpp':
+ # Used by MakeDescriptor in cpp mode
+ import os
+ import uuid
+
+ if api_implementation.Version() == 2:
+ from google.protobuf.pyext import _message
+ else:
+ from google.protobuf.internal import cpp_message
+
class Error(Exception):
"""Base error for this module."""
+class TypeTransformationError(Error):
+ """Error transforming between python proto type and corresponding C++ type."""
+
+
class DescriptorBase(object):
"""Descriptors base class.
@@ -75,6 +86,18 @@ class DescriptorBase(object):
# Does this descriptor have non-default options?
self.has_options = options is not None
+ def _SetOptions(self, options, options_class_name):
+ """Sets the descriptor's options
+
+ This function is used in generated proto2 files to update descriptor
+ options. It must not be used outside proto2.
+ """
+ self._options = options
+ self._options_class_name = options_class_name
+
+ # Does this descriptor have non-default options?
+ self.has_options = options is not None
+
def GetOptions(self):
"""Retrieves descriptor options.
@@ -204,13 +227,21 @@ class Descriptor(_NestedDescriptorBase):
options: (descriptor_pb2.MessageOptions) Protocol message options or None
to use default message options.
+ oneofs: (list of OneofDescriptor) The list of descriptors for oneof fields
+ in this message.
+ oneofs_by_name: (dict str -> OneofDescriptor) Same objects as in |oneofs|,
+ but indexed by "name" attribute.
+
file: (FileDescriptor) Reference to file descriptor.
"""
+ # NOTE(tmarek): The file argument redefining a builtin is nothing we can
+ # fix right now since we don't know how many clients already rely on the
+ # name of the argument.
def __init__(self, name, full_name, filename, containing_type, fields,
nested_types, enum_types, extensions, options=None,
- is_extendable=True, extension_ranges=None, file=None,
- serialized_start=None, serialized_end=None):
+ is_extendable=True, extension_ranges=None, oneofs=None,
+ file=None, serialized_start=None, serialized_end=None): # pylint:disable=redefined-builtin
"""Arguments to __init__() are as described in the description
of Descriptor fields above.
@@ -220,7 +251,7 @@ class Descriptor(_NestedDescriptorBase):
super(Descriptor, self).__init__(
options, 'MessageOptions', name, full_name, file,
containing_type, serialized_start=serialized_start,
- serialized_end=serialized_start)
+ serialized_end=serialized_end)
# We have fields in addition to fields_by_name and fields_by_number,
# so that:
@@ -234,6 +265,8 @@ class Descriptor(_NestedDescriptorBase):
self.fields_by_name = dict((f.name, f) for f in fields)
self.nested_types = nested_types
+ for nested_type in nested_types:
+ nested_type.containing_type = self
self.nested_types_by_name = dict((t.name, t) for t in nested_types)
self.enum_types = enum_types
@@ -249,9 +282,28 @@ class Descriptor(_NestedDescriptorBase):
self.extensions_by_name = dict((f.name, f) for f in extensions)
self.is_extendable = is_extendable
self.extension_ranges = extension_ranges
+ self.oneofs = oneofs if oneofs is not None else []
+ self.oneofs_by_name = dict((o.name, o) for o in self.oneofs)
+ for oneof in self.oneofs:
+ oneof.containing_type = self
- self._serialized_start = serialized_start
- self._serialized_end = serialized_end
+ def EnumValueName(self, enum, value):
+ """Returns the string name of an enum value.
+
+ This is just a small helper method to simplify a common operation.
+
+ Args:
+ enum: string name of the Enum.
+ value: int, value of the enum.
+
+ Returns:
+ string name of the enum value.
+
+ Raises:
+ KeyError if either the Enum doesn't exist or the value is not a valid
+ value for the enum.
+ """
+ return self.enum_types_by_name[enum].values_by_number[value].name
def CopyToProto(self, proto):
"""Copies this to a descriptor_pb2.DescriptorProto.
@@ -278,7 +330,7 @@ class FieldDescriptor(DescriptorBase):
"""Descriptor for a single field in a .proto file.
- A FieldDescriptor instance has the following attriubtes:
+ A FieldDescriptor instance has the following attributes:
name: (str) Name of this field, exactly as it appears in .proto.
full_name: (str) Name of this field, including containing scope. This is
@@ -319,6 +371,9 @@ class FieldDescriptor(DescriptorBase):
options: (descriptor_pb2.FieldOptions) Protocol message field options or
None to use default field options.
+
+ containing_oneof: (OneofDescriptor) If the field is a member of a oneof
+ union, contains its descriptor. Otherwise, None.
"""
# Must be consistent with C++ FieldDescriptor::Type enum in
@@ -361,6 +416,27 @@ class FieldDescriptor(DescriptorBase):
CPPTYPE_MESSAGE = 10
MAX_CPPTYPE = 10
+ _PYTHON_TO_CPP_PROTO_TYPE_MAP = {
+ TYPE_DOUBLE: CPPTYPE_DOUBLE,
+ TYPE_FLOAT: CPPTYPE_FLOAT,
+ TYPE_ENUM: CPPTYPE_ENUM,
+ TYPE_INT64: CPPTYPE_INT64,
+ TYPE_SINT64: CPPTYPE_INT64,
+ TYPE_SFIXED64: CPPTYPE_INT64,
+ TYPE_UINT64: CPPTYPE_UINT64,
+ TYPE_FIXED64: CPPTYPE_UINT64,
+ TYPE_INT32: CPPTYPE_INT32,
+ TYPE_SFIXED32: CPPTYPE_INT32,
+ TYPE_SINT32: CPPTYPE_INT32,
+ TYPE_UINT32: CPPTYPE_UINT32,
+ TYPE_FIXED32: CPPTYPE_UINT32,
+ TYPE_BYTES: CPPTYPE_STRING,
+ TYPE_STRING: CPPTYPE_STRING,
+ TYPE_BOOL: CPPTYPE_BOOL,
+ TYPE_MESSAGE: CPPTYPE_MESSAGE,
+ TYPE_GROUP: CPPTYPE_MESSAGE
+ }
+
# Must be consistent with C++ FieldDescriptor::Label enum in
# descriptor.h.
#
@@ -370,10 +446,16 @@ class FieldDescriptor(DescriptorBase):
LABEL_REPEATED = 3
MAX_LABEL = 3
+ # Must be consistent with C++ constants kMaxNumber, kFirstReservedNumber,
+ # and kLastReservedNumber in descriptor.h
+ MAX_FIELD_NUMBER = (1 << 29) - 1
+ FIRST_RESERVED_FIELD_NUMBER = 19000
+ LAST_RESERVED_FIELD_NUMBER = 19999
+
def __init__(self, name, full_name, index, number, type, cpp_type, label,
default_value, message_type, enum_type, containing_type,
is_extension, extension_scope, options=None,
- has_default_value=True):
+ has_default_value=True, containing_oneof=None):
"""The arguments are as described in the description of FieldDescriptor
attributes above.
@@ -396,6 +478,45 @@ class FieldDescriptor(DescriptorBase):
self.enum_type = enum_type
self.is_extension = is_extension
self.extension_scope = extension_scope
+ self.containing_oneof = containing_oneof
+ if api_implementation.Type() == 'cpp':
+ if is_extension:
+ if api_implementation.Version() == 2:
+ # pylint: disable=protected-access
+ self._cdescriptor = (
+ _message.Message._GetExtensionDescriptor(full_name))
+ # pylint: enable=protected-access
+ else:
+ self._cdescriptor = cpp_message.GetExtensionDescriptor(full_name)
+ else:
+ if api_implementation.Version() == 2:
+ # pylint: disable=protected-access
+ self._cdescriptor = _message.Message._GetFieldDescriptor(full_name)
+ # pylint: enable=protected-access
+ else:
+ self._cdescriptor = cpp_message.GetFieldDescriptor(full_name)
+ else:
+ self._cdescriptor = None
+
+ @staticmethod
+ def ProtoTypeToCppProtoType(proto_type):
+ """Converts from a Python proto type to a C++ Proto Type.
+
+ The Python ProtocolBuffer classes specify both the 'Python' datatype and the
+ 'C++' datatype - and they're not the same. This helper method should
+ translate from one to another.
+
+ Args:
+ proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*)
+ Returns:
+ descriptor.FieldDescriptor.CPPTYPE_*, the C++ type.
+ Raises:
+ TypeTransformationError: when the Python proto type isn't known.
+ """
+ try:
+ return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type]
+ except KeyError:
+ raise TypeTransformationError('Unknown proto_type: %s' % proto_type)
class EnumDescriptor(_NestedDescriptorBase):
@@ -434,7 +555,7 @@ class EnumDescriptor(_NestedDescriptorBase):
super(EnumDescriptor, self).__init__(
options, 'EnumOptions', name, full_name, file,
containing_type, serialized_start=serialized_start,
- serialized_end=serialized_start)
+ serialized_end=serialized_end)
self.values = values
for value in self.values:
@@ -442,9 +563,6 @@ class EnumDescriptor(_NestedDescriptorBase):
self.values_by_name = dict((v.name, v) for v in values)
self.values_by_number = dict((v.number, v) for v in values)
- self._serialized_start = serialized_start
- self._serialized_end = serialized_end
-
def CopyToProto(self, proto):
"""Copies this to a descriptor_pb2.EnumDescriptorProto.
@@ -479,6 +597,29 @@ class EnumValueDescriptor(DescriptorBase):
self.type = type
+class OneofDescriptor(object):
+ """Descriptor for a oneof field.
+
+ name: (str) Name of the oneof field.
+ full_name: (str) Full name of the oneof field, including package name.
+ index: (int) 0-based index giving the order of the oneof field inside
+ its containing type.
+ containing_type: (Descriptor) Descriptor of the protocol message
+ type that contains this field. Set by the Descriptor constructor
+ if we're passed into one.
+ fields: (list of FieldDescriptor) The list of field descriptors this
+ oneof can contain.
+ """
+
+ def __init__(self, name, full_name, index, containing_type, fields):
+ """Arguments are as described in the attribute description above."""
+ self.name = name
+ self.full_name = full_name
+ self.index = index
+ self.containing_type = containing_type
+ self.fields = fields
+
+
class ServiceDescriptor(_NestedDescriptorBase):
"""Descriptor for a service.
@@ -557,20 +698,43 @@ class MethodDescriptor(DescriptorBase):
class FileDescriptor(DescriptorBase):
"""Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto.
+ Note that enum_types_by_name, extensions_by_name, and dependencies
+ fields are only set by the message_factory module, and not by the
+ generated proto code.
+
name: name of file, relative to root of source tree.
package: name of the package
serialized_pb: (str) Byte string of serialized
descriptor_pb2.FileDescriptorProto.
+ dependencies: List of other FileDescriptors this FileDescriptor depends on.
+ 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.
"""
- def __init__(self, name, package, options=None, serialized_pb=None):
+ def __init__(self, name, package, options=None, serialized_pb=None,
+ dependencies=None):
"""Constructor."""
super(FileDescriptor, self).__init__(options, 'FileOptions')
+ self.message_types_by_name = {}
self.name = name
self.package = package
self.serialized_pb = serialized_pb
+ self.enum_types_by_name = {}
+ self.extensions_by_name = {}
+ self.dependencies = (dependencies or [])
+
+ if (api_implementation.Type() == 'cpp' and
+ self.serialized_pb is not None):
+ if api_implementation.Version() == 2:
+ # pylint: disable=protected-access
+ _message.Message._BuildFile(self.serialized_pb)
+ # pylint: enable=protected-access
+ else:
+ cpp_message.BuildFile(self.serialized_pb)
+
def CopyToProto(self, proto):
"""Copies this to a descriptor_pb2.FileDescriptorProto.
@@ -588,3 +752,98 @@ def _ParseOptions(message, string):
"""
message.ParseFromString(string)
return message
+
+
+def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True):
+ """Make a protobuf Descriptor given a DescriptorProto protobuf.
+
+ Handles nested descriptors. Note that this is limited to the scope of defining
+ a message inside of another message. Composite fields can currently only be
+ resolved if the message is defined in the same scope as the field.
+
+ Args:
+ desc_proto: The descriptor_pb2.DescriptorProto protobuf message.
+ package: Optional package name for the new message Descriptor (string).
+ build_file_if_cpp: Update the C++ descriptor pool if api matches.
+ Set to False on recursion, so no duplicates are created.
+ Returns:
+ A Descriptor for protobuf messages.
+ """
+ if api_implementation.Type() == 'cpp' and build_file_if_cpp:
+ # The C++ implementation requires all descriptors to be backed by the same
+ # definition in the C++ descriptor pool. To do this, we build a
+ # FileDescriptorProto with the same definition as this descriptor and build
+ # it into the pool.
+ from google.protobuf import descriptor_pb2
+ file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
+ file_descriptor_proto.message_type.add().MergeFrom(desc_proto)
+
+ # Generate a random name for this proto file to prevent conflicts with
+ # any imported ones. We need to specify a file name so BuildFile accepts
+ # our FileDescriptorProto, but it is not important what that file name
+ # is actually set to.
+ proto_name = str(uuid.uuid4())
+
+ if package:
+ file_descriptor_proto.name = os.path.join(package.replace('.', '/'),
+ proto_name + '.proto')
+ file_descriptor_proto.package = package
+ else:
+ file_descriptor_proto.name = proto_name + '.proto'
+
+ if api_implementation.Version() == 2:
+ # pylint: disable=protected-access
+ _message.Message._BuildFile(file_descriptor_proto.SerializeToString())
+ # pylint: enable=protected-access
+ else:
+ cpp_message.BuildFile(file_descriptor_proto.SerializeToString())
+
+ full_message_name = [desc_proto.name]
+ if package: full_message_name.insert(0, package)
+
+ # Create Descriptors for enum types
+ enum_types = {}
+ for enum_proto in desc_proto.enum_type:
+ full_name = '.'.join(full_message_name + [enum_proto.name])
+ enum_desc = EnumDescriptor(
+ enum_proto.name, full_name, None, [
+ EnumValueDescriptor(enum_val.name, ii, enum_val.number)
+ for ii, enum_val in enumerate(enum_proto.value)])
+ enum_types[full_name] = enum_desc
+
+ # Create Descriptors for nested types
+ nested_types = {}
+ for nested_proto in desc_proto.nested_type:
+ full_name = '.'.join(full_message_name + [nested_proto.name])
+ # Nested types are just those defined inside of the message, not all types
+ # used by fields in the message, so no loops are possible here.
+ nested_desc = MakeDescriptor(nested_proto,
+ package='.'.join(full_message_name),
+ build_file_if_cpp=False)
+ nested_types[full_name] = nested_desc
+
+ fields = []
+ for field_proto in desc_proto.field:
+ full_name = '.'.join(full_message_name + [field_proto.name])
+ enum_desc = None
+ nested_desc = None
+ if field_proto.HasField('type_name'):
+ type_name = field_proto.type_name
+ full_type_name = '.'.join(full_message_name +
+ [type_name[type_name.rfind('.')+1:]])
+ if full_type_name in nested_types:
+ nested_desc = nested_types[full_type_name]
+ elif full_type_name in enum_types:
+ enum_desc = enum_types[full_type_name]
+ # Else type_name references a non-local type, which isn't implemented
+ field = FieldDescriptor(
+ field_proto.name, full_name, field_proto.number - 1,
+ field_proto.number, field_proto.type,
+ FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type),
+ field_proto.label, None, nested_desc, enum_desc, None, False, None,
+ has_default_value=False)
+ fields.append(field)
+
+ desc_name = '.'.join(full_message_name)
+ return Descriptor(desc_proto.name, desc_name, None, None, fields,
+ nested_types.values(), enum_types.values(), [])
diff --git a/python/google/protobuf/descriptor_database.py b/python/google/protobuf/descriptor_database.py
new file mode 100644
index 0000000..55fb8c7
--- /dev/null
+++ b/python/google/protobuf/descriptor_database.py
@@ -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.
+
+"""Provides a container for DescriptorProtos."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+
+class Error(Exception):
+ pass
+
+
+class DescriptorDatabaseConflictingDefinitionError(Error):
+ """Raised when a proto is added with the same name & different descriptor."""
+
+
+class DescriptorDatabase(object):
+ """A container accepting FileDescriptorProtos and maps DescriptorProtos."""
+
+ def __init__(self):
+ self._file_desc_protos_by_file = {}
+ self._file_desc_protos_by_symbol = {}
+
+ def Add(self, file_desc_proto):
+ """Adds the FileDescriptorProto and its types to this database.
+
+ Args:
+ file_desc_proto: The FileDescriptorProto to add.
+ Raises:
+ DescriptorDatabaseException: if an attempt is made to add a proto
+ with the same name but different definition than an exisiting
+ proto in the database.
+ """
+ proto_name = file_desc_proto.name
+ if proto_name not in self._file_desc_protos_by_file:
+ self._file_desc_protos_by_file[proto_name] = file_desc_proto
+ elif self._file_desc_protos_by_file[proto_name] != file_desc_proto:
+ raise DescriptorDatabaseConflictingDefinitionError(
+ '%s already added, but with different descriptor.' % proto_name)
+
+ package = file_desc_proto.package
+ for message in file_desc_proto.message_type:
+ self._file_desc_protos_by_symbol.update(
+ (name, file_desc_proto) for name in _ExtractSymbols(message, package))
+ for enum in file_desc_proto.enum_type:
+ self._file_desc_protos_by_symbol[
+ '.'.join((package, enum.name))] = file_desc_proto
+
+ def FindFileByName(self, name):
+ """Finds the file descriptor proto by file name.
+
+ Typically the file name is a relative path ending to a .proto file. The
+ proto with the given name will have to have been added to this database
+ using the Add method or else an error will be raised.
+
+ Args:
+ name: The file name to find.
+
+ Returns:
+ The file descriptor proto matching the name.
+
+ Raises:
+ KeyError if no file by the given name was added.
+ """
+
+ return self._file_desc_protos_by_file[name]
+
+ def FindFileContainingSymbol(self, symbol):
+ """Finds the file descriptor proto containing the specified symbol.
+
+ The symbol should be a fully qualified name including the file descriptor's
+ package and any containing messages. Some examples:
+
+ 'some.package.name.Message'
+ 'some.package.name.Message.NestedEnum'
+
+ The file descriptor proto containing the specified symbol must be added to
+ this database using the Add method or else an error will be raised.
+
+ Args:
+ symbol: The fully qualified symbol name.
+
+ Returns:
+ The file descriptor proto containing the symbol.
+
+ Raises:
+ KeyError if no file contains the specified symbol.
+ """
+
+ return self._file_desc_protos_by_symbol[symbol]
+
+
+def _ExtractSymbols(desc_proto, package):
+ """Pulls out all the symbols from a descriptor proto.
+
+ Args:
+ desc_proto: The proto to extract symbols from.
+ package: The package containing the descriptor type.
+
+ Yields:
+ The fully qualified name found in the descriptor.
+ """
+
+ message_name = '.'.join((package, desc_proto.name))
+ yield message_name
+ for nested_type in desc_proto.nested_type:
+ for symbol in _ExtractSymbols(nested_type, message_name):
+ yield symbol
+ for enum_type in desc_proto.enum_type:
+ yield '.'.join((message_name, enum_type.name))
diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py
new file mode 100644
index 0000000..cf234cf
--- /dev/null
+++ b/python/google/protobuf/descriptor_pool.py
@@ -0,0 +1,643 @@
+# 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.
+
+"""Provides DescriptorPool to use as a container for proto2 descriptors.
+
+The DescriptorPool is used in conjection with a DescriptorDatabase to maintain
+a collection of protocol buffer descriptors for use when dynamically creating
+message types at runtime.
+
+For most applications protocol buffers should be used via modules generated by
+the protocol buffer compiler tool. This should only be used when the type of
+protocol buffers used in an application or library cannot be predetermined.
+
+Below is a straightforward example on how to use this class:
+
+ pool = DescriptorPool()
+ file_descriptor_protos = [ ... ]
+ for file_descriptor_proto in file_descriptor_protos:
+ pool.Add(file_descriptor_proto)
+ my_message_descriptor = pool.FindMessageTypeByName('some.package.MessageType')
+
+The message descriptor can be used in conjunction with the message_factory
+module in order to create a protocol buffer class that can be encoded and
+decoded.
+
+If you want to get a Python class for the specified proto, use the
+helper functions inside google.protobuf.message_factory
+directly instead of this class.
+"""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+import sys
+
+from google.protobuf import descriptor
+from google.protobuf import descriptor_database
+from google.protobuf import text_encoding
+
+
+def _NormalizeFullyQualifiedName(name):
+ """Remove leading period from fully-qualified type name.
+
+ Due to b/13860351 in descriptor_database.py, types in the root namespace are
+ generated with a leading period. This function removes that prefix.
+
+ Args:
+ name: A str, the fully-qualified symbol name.
+
+ Returns:
+ A str, the normalized fully-qualified symbol name.
+ """
+ return name.lstrip('.')
+
+
+class DescriptorPool(object):
+ """A collection of protobufs dynamically constructed by descriptor protos."""
+
+ def __init__(self, descriptor_db=None):
+ """Initializes a Pool of proto buffs.
+
+ The descriptor_db argument to the constructor is provided to allow
+ specialized file descriptor proto lookup code to be triggered on demand. An
+ example would be an implementation which will read and compile a file
+ specified in a call to FindFileByName() and not require the call to Add()
+ at all. Results from this database will be cached internally here as well.
+
+ Args:
+ descriptor_db: A secondary source of file descriptors.
+ """
+
+ self._internal_db = descriptor_database.DescriptorDatabase()
+ self._descriptor_db = descriptor_db
+ self._descriptors = {}
+ self._enum_descriptors = {}
+ self._file_descriptors = {}
+
+ def Add(self, file_desc_proto):
+ """Adds the FileDescriptorProto and its types to this pool.
+
+ Args:
+ file_desc_proto: The FileDescriptorProto to add.
+ """
+
+ self._internal_db.Add(file_desc_proto)
+
+ def AddDescriptor(self, desc):
+ """Adds a Descriptor to the pool, non-recursively.
+
+ If the Descriptor contains nested messages or enums, the caller must
+ explicitly register them. This method also registers the FileDescriptor
+ associated with the message.
+
+ Args:
+ desc: A Descriptor.
+ """
+ if not isinstance(desc, descriptor.Descriptor):
+ raise TypeError('Expected instance of descriptor.Descriptor.')
+
+ self._descriptors[desc.full_name] = desc
+ self.AddFileDescriptor(desc.file)
+
+ def AddEnumDescriptor(self, enum_desc):
+ """Adds an EnumDescriptor to the pool.
+
+ This method also registers the FileDescriptor associated with the message.
+
+ Args:
+ enum_desc: An EnumDescriptor.
+ """
+
+ if not isinstance(enum_desc, descriptor.EnumDescriptor):
+ raise TypeError('Expected instance of descriptor.EnumDescriptor.')
+
+ self._enum_descriptors[enum_desc.full_name] = enum_desc
+ self.AddFileDescriptor(enum_desc.file)
+
+ def AddFileDescriptor(self, file_desc):
+ """Adds a FileDescriptor to the pool, non-recursively.
+
+ If the FileDescriptor contains messages or enums, the caller must explicitly
+ register them.
+
+ Args:
+ file_desc: A FileDescriptor.
+ """
+
+ if not isinstance(file_desc, descriptor.FileDescriptor):
+ raise TypeError('Expected instance of descriptor.FileDescriptor.')
+ self._file_descriptors[file_desc.name] = file_desc
+
+ def FindFileByName(self, file_name):
+ """Gets a FileDescriptor by file name.
+
+ Args:
+ file_name: The path to the file to get a descriptor for.
+
+ Returns:
+ A FileDescriptor for the named file.
+
+ Raises:
+ KeyError: if the file can not be found in the pool.
+ """
+
+ try:
+ return self._file_descriptors[file_name]
+ except KeyError:
+ pass
+
+ try:
+ file_proto = self._internal_db.FindFileByName(file_name)
+ except KeyError:
+ _, error, _ = sys.exc_info() #PY25 compatible for GAE.
+ if self._descriptor_db:
+ file_proto = self._descriptor_db.FindFileByName(file_name)
+ else:
+ raise error
+ if not file_proto:
+ raise KeyError('Cannot find a file named %s' % file_name)
+ return self._ConvertFileProtoToFileDescriptor(file_proto)
+
+ def FindFileContainingSymbol(self, symbol):
+ """Gets the FileDescriptor for the file containing the specified symbol.
+
+ Args:
+ symbol: The name of the symbol to search for.
+
+ Returns:
+ A FileDescriptor that contains the specified symbol.
+
+ Raises:
+ KeyError: if the file can not be found in the pool.
+ """
+
+ symbol = _NormalizeFullyQualifiedName(symbol)
+ try:
+ return self._descriptors[symbol].file
+ except KeyError:
+ pass
+
+ try:
+ return self._enum_descriptors[symbol].file
+ except KeyError:
+ pass
+
+ try:
+ file_proto = self._internal_db.FindFileContainingSymbol(symbol)
+ except KeyError:
+ _, error, _ = sys.exc_info() #PY25 compatible for GAE.
+ if self._descriptor_db:
+ file_proto = self._descriptor_db.FindFileContainingSymbol(symbol)
+ else:
+ raise error
+ if not file_proto:
+ raise KeyError('Cannot find a file containing %s' % symbol)
+ return self._ConvertFileProtoToFileDescriptor(file_proto)
+
+ def FindMessageTypeByName(self, full_name):
+ """Loads the named descriptor from the pool.
+
+ Args:
+ full_name: The full name of the descriptor to load.
+
+ Returns:
+ The descriptor for the named type.
+ """
+
+ full_name = _NormalizeFullyQualifiedName(full_name)
+ if full_name not in self._descriptors:
+ self.FindFileContainingSymbol(full_name)
+ return self._descriptors[full_name]
+
+ def FindEnumTypeByName(self, full_name):
+ """Loads the named enum descriptor from the pool.
+
+ Args:
+ full_name: The full name of the enum descriptor to load.
+
+ Returns:
+ The enum descriptor for the named type.
+ """
+
+ full_name = _NormalizeFullyQualifiedName(full_name)
+ if full_name not in self._enum_descriptors:
+ self.FindFileContainingSymbol(full_name)
+ return self._enum_descriptors[full_name]
+
+ def _ConvertFileProtoToFileDescriptor(self, file_proto):
+ """Creates a FileDescriptor from a proto or returns a cached copy.
+
+ This method also has the side effect of loading all the symbols found in
+ the file into the appropriate dictionaries in the pool.
+
+ Args:
+ file_proto: The proto to convert.
+
+ Returns:
+ A FileDescriptor matching the passed in proto.
+ """
+
+ 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]
+
+ file_descriptor = descriptor.FileDescriptor(
+ name=file_proto.name,
+ package=file_proto.package,
+ options=file_proto.options,
+ serialized_pb=file_proto.SerializeToString(),
+ dependencies=direct_deps)
+ scope = {}
+
+ # This loop extracts all the message and enum types from all the
+ # dependencoes of the file_proto. This is necessary to create the
+ # scope of available message types when defining the passed in
+ # file proto.
+ for dependency in built_deps:
+ scope.update(self._ExtractSymbols(
+ dependency.message_types_by_name.values()))
+ scope.update((_PrefixWithDot(enum.full_name), enum)
+ for enum in dependency.enum_types_by_name.values())
+
+ for message_type in file_proto.message_type:
+ message_desc = self._ConvertMessageDescriptor(
+ message_type, file_proto.package, file_descriptor, scope)
+ file_descriptor.message_types_by_name[message_desc.name] = message_desc
+
+ for enum_type in file_proto.enum_type:
+ file_descriptor.enum_types_by_name[enum_type.name] = (
+ self._ConvertEnumDescriptor(enum_type, file_proto.package,
+ file_descriptor, None, scope))
+
+ for index, extension_proto in enumerate(file_proto.extension):
+ extension_desc = self.MakeFieldDescriptor(
+ extension_proto, file_proto.package, index, is_extension=True)
+ extension_desc.containing_type = self._GetTypeFromScope(
+ file_descriptor.package, extension_proto.extendee, scope)
+ self.SetFieldType(extension_proto, extension_desc,
+ file_descriptor.package, scope)
+ file_descriptor.extensions_by_name[extension_desc.name] = extension_desc
+
+ for desc_proto in file_proto.message_type:
+ self.SetAllFieldTypes(file_proto.package, desc_proto, scope)
+
+ if file_proto.package:
+ desc_proto_prefix = _PrefixWithDot(file_proto.package)
+ else:
+ desc_proto_prefix = ''
+
+ for desc_proto in file_proto.message_type:
+ desc = self._GetTypeFromScope(desc_proto_prefix, desc_proto.name, scope)
+ file_descriptor.message_types_by_name[desc_proto.name] = desc
+ self.Add(file_proto)
+ self._file_descriptors[file_proto.name] = file_descriptor
+
+ return self._file_descriptors[file_proto.name]
+
+ def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None,
+ scope=None):
+ """Adds the proto to the pool in the specified package.
+
+ Args:
+ desc_proto: The descriptor_pb2.DescriptorProto protobuf message.
+ package: The package the proto should be located in.
+ file_desc: The file containing this message.
+ scope: Dict mapping short and full symbols to message and enum types.
+
+ Returns:
+ The added descriptor.
+ """
+
+ if package:
+ desc_name = '.'.join((package, desc_proto.name))
+ else:
+ desc_name = desc_proto.name
+
+ if file_desc is None:
+ file_name = None
+ else:
+ file_name = file_desc.name
+
+ if scope is None:
+ scope = {}
+
+ nested = [
+ self._ConvertMessageDescriptor(nested, desc_name, file_desc, scope)
+ for nested in desc_proto.nested_type]
+ enums = [
+ self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope)
+ for enum in desc_proto.enum_type]
+ fields = [self.MakeFieldDescriptor(field, desc_name, index)
+ for index, field in enumerate(desc_proto.field)]
+ extensions = [
+ self.MakeFieldDescriptor(extension, desc_name, index, is_extension=True)
+ for index, extension in enumerate(desc_proto.extension)]
+ oneofs = [
+ descriptor.OneofDescriptor(desc.name, '.'.join((desc_name, desc.name)),
+ index, None, [])
+ 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:
+ is_extendable = True
+ else:
+ is_extendable = False
+ desc = descriptor.Descriptor(
+ name=desc_proto.name,
+ full_name=desc_name,
+ filename=file_name,
+ containing_type=None,
+ fields=fields,
+ oneofs=oneofs,
+ nested_types=nested,
+ enum_types=enums,
+ extensions=extensions,
+ options=desc_proto.options,
+ is_extendable=is_extendable,
+ extension_ranges=extension_ranges,
+ file=file_desc,
+ serialized_start=None,
+ serialized_end=None)
+ for nested in desc.nested_types:
+ nested.containing_type = desc
+ for enum in desc.enum_types:
+ enum.containing_type = desc
+ for field_index, field_desc in enumerate(desc_proto.field):
+ if field_desc.HasField('oneof_index'):
+ oneof_index = field_desc.oneof_index
+ oneofs[oneof_index].fields.append(fields[field_index])
+ fields[field_index].containing_oneof = oneofs[oneof_index]
+
+ scope[_PrefixWithDot(desc_name)] = desc
+ self._descriptors[desc_name] = desc
+ return desc
+
+ def _ConvertEnumDescriptor(self, enum_proto, package=None, file_desc=None,
+ containing_type=None, scope=None):
+ """Make a protobuf EnumDescriptor given an EnumDescriptorProto protobuf.
+
+ Args:
+ enum_proto: The descriptor_pb2.EnumDescriptorProto protobuf message.
+ package: Optional package name for the new message EnumDescriptor.
+ file_desc: The file containing the enum descriptor.
+ containing_type: The type containing this enum.
+ scope: Scope containing available types.
+
+ Returns:
+ The added descriptor
+ """
+
+ if package:
+ enum_name = '.'.join((package, enum_proto.name))
+ else:
+ enum_name = enum_proto.name
+
+ if file_desc is None:
+ file_name = None
+ else:
+ file_name = file_desc.name
+
+ values = [self._MakeEnumValueDescriptor(value, index)
+ for index, value in enumerate(enum_proto.value)]
+ desc = descriptor.EnumDescriptor(name=enum_proto.name,
+ full_name=enum_name,
+ filename=file_name,
+ file=file_desc,
+ values=values,
+ containing_type=containing_type,
+ options=enum_proto.options)
+ scope['.%s' % enum_name] = desc
+ self._enum_descriptors[enum_name] = desc
+ return desc
+
+ def MakeFieldDescriptor(self, field_proto, message_name, index,
+ is_extension=False):
+ """Creates a field descriptor from a FieldDescriptorProto.
+
+ For message and enum type fields, this method will do a look up
+ in the pool for the appropriate descriptor for that type. If it
+ is unavailable, it will fall back to the _source function to
+ create it. If this type is still unavailable, construction will
+ fail.
+
+ Args:
+ field_proto: The proto describing the field.
+ message_name: The name of the containing message.
+ index: Index of the field
+ is_extension: Indication that this field is for an extension.
+
+ Returns:
+ An initialized FieldDescriptor object
+ """
+
+ if message_name:
+ full_name = '.'.join((message_name, field_proto.name))
+ else:
+ full_name = field_proto.name
+
+ return descriptor.FieldDescriptor(
+ name=field_proto.name,
+ full_name=full_name,
+ index=index,
+ number=field_proto.number,
+ type=field_proto.type,
+ cpp_type=None,
+ message_type=None,
+ enum_type=None,
+ containing_type=None,
+ label=field_proto.label,
+ has_default_value=False,
+ default_value=None,
+ is_extension=is_extension,
+ extension_scope=None,
+ options=field_proto.options)
+
+ def SetAllFieldTypes(self, package, desc_proto, scope):
+ """Sets all the descriptor's fields's types.
+
+ This method also sets the containing types on any extensions.
+
+ Args:
+ package: The current package of desc_proto.
+ desc_proto: The message descriptor to update.
+ scope: Enclosing scope of available types.
+ """
+
+ package = _PrefixWithDot(package)
+
+ main_desc = self._GetTypeFromScope(package, desc_proto.name, scope)
+
+ if package == '.':
+ nested_package = _PrefixWithDot(desc_proto.name)
+ else:
+ nested_package = '.'.join([package, desc_proto.name])
+
+ for field_proto, field_desc in zip(desc_proto.field, main_desc.fields):
+ self.SetFieldType(field_proto, field_desc, nested_package, scope)
+
+ for extension_proto, extension_desc in (
+ zip(desc_proto.extension, main_desc.extensions)):
+ extension_desc.containing_type = self._GetTypeFromScope(
+ nested_package, extension_proto.extendee, scope)
+ self.SetFieldType(extension_proto, extension_desc, nested_package, scope)
+
+ for nested_type in desc_proto.nested_type:
+ self.SetAllFieldTypes(nested_package, nested_type, scope)
+
+ def SetFieldType(self, field_proto, field_desc, package, scope):
+ """Sets the field's type, cpp_type, message_type and enum_type.
+
+ Args:
+ field_proto: Data about the field in proto format.
+ field_desc: The descriptor to modiy.
+ package: The package the field's container is in.
+ scope: Enclosing scope of available types.
+ """
+ if field_proto.type_name:
+ desc = self._GetTypeFromScope(package, field_proto.type_name, scope)
+ else:
+ desc = None
+
+ if not field_proto.HasField('type'):
+ if isinstance(desc, descriptor.Descriptor):
+ field_proto.type = descriptor.FieldDescriptor.TYPE_MESSAGE
+ else:
+ field_proto.type = descriptor.FieldDescriptor.TYPE_ENUM
+
+ field_desc.cpp_type = descriptor.FieldDescriptor.ProtoTypeToCppProtoType(
+ field_proto.type)
+
+ if (field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE
+ or field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP):
+ field_desc.message_type = desc
+
+ if field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
+ field_desc.enum_type = desc
+
+ if field_proto.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+ field_desc.has_default_value = False
+ field_desc.default_value = []
+ elif field_proto.HasField('default_value'):
+ field_desc.has_default_value = True
+ if (field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE or
+ field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT):
+ field_desc.default_value = float(field_proto.default_value)
+ elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING:
+ field_desc.default_value = field_proto.default_value
+ elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL:
+ field_desc.default_value = field_proto.default_value.lower() == 'true'
+ elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
+ field_desc.default_value = field_desc.enum_type.values_by_name[
+ field_proto.default_value].index
+ elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES:
+ field_desc.default_value = text_encoding.CUnescape(
+ field_proto.default_value)
+ else:
+ field_desc.default_value = int(field_proto.default_value)
+ else:
+ field_desc.has_default_value = False
+ field_desc.default_value = None
+
+ field_desc.type = field_proto.type
+
+ def _MakeEnumValueDescriptor(self, value_proto, index):
+ """Creates a enum value descriptor object from a enum value proto.
+
+ Args:
+ value_proto: The proto describing the enum value.
+ index: The index of the enum value.
+
+ Returns:
+ An initialized EnumValueDescriptor object.
+ """
+
+ return descriptor.EnumValueDescriptor(
+ name=value_proto.name,
+ index=index,
+ number=value_proto.number,
+ options=value_proto.options,
+ type=None)
+
+ def _ExtractSymbols(self, descriptors):
+ """Pulls out all the symbols from descriptor protos.
+
+ Args:
+ descriptors: The messages to extract descriptors from.
+ Yields:
+ A two element tuple of the type name and descriptor object.
+ """
+
+ for desc in descriptors:
+ yield (_PrefixWithDot(desc.full_name), desc)
+ for symbol in self._ExtractSymbols(desc.nested_types):
+ yield symbol
+ for enum in desc.enum_types:
+ yield (_PrefixWithDot(enum.full_name), enum)
+
+ def _GetDeps(self, dependencies):
+ """Recursively finds dependencies for file protos.
+
+ Args:
+ dependencies: The names of the files being depended on.
+
+ Yields:
+ Each direct and indirect dependency.
+ """
+
+ for dependency in dependencies:
+ dep_desc = self.FindFileByName(dependency)
+ yield dep_desc
+ for parent_dep in dep_desc.dependencies:
+ yield parent_dep
+
+ def _GetTypeFromScope(self, package, type_name, scope):
+ """Finds a given type name in the current scope.
+
+ Args:
+ package: The package the proto should be located in.
+ type_name: The name of the type to be found in the scope.
+ scope: Dict mapping short and full symbols to message and enum types.
+
+ Returns:
+ The descriptor for the requested type.
+ """
+ if type_name not in scope:
+ components = _PrefixWithDot(package).split('.')
+ while components:
+ possible_match = '.'.join(components + [type_name])
+ if possible_match in scope:
+ type_name = possible_match
+ break
+ else:
+ components.pop(-1)
+ return scope[type_name]
+
+
+def _PrefixWithDot(name):
+ return name if name.startswith('.') else '.%s' % name
diff --git a/python/google/protobuf/internal/api_implementation.cc b/python/google/protobuf/internal/api_implementation.cc
new file mode 100644
index 0000000..83db40b
--- /dev/null
+++ b/python/google/protobuf/internal/api_implementation.cc
@@ -0,0 +1,139 @@
+// 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 <Python.h>
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+// Version constant.
+// This is either 0 for python, 1 for CPP V1, 2 for CPP V2.
+//
+// 0 is default and is equivalent to
+// PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
+//
+// 1 is set with -DPYTHON_PROTO2_CPP_IMPL_V1 and is equivalent to
+// PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp
+// and
+// PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION=1
+//
+// 2 is set with -DPYTHON_PROTO2_CPP_IMPL_V2 and is equivalent to
+// PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp
+// and
+// PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION=2
+#ifdef PYTHON_PROTO2_CPP_IMPL_V1
+#if PY_MAJOR_VERSION >= 3
+#error "PYTHON_PROTO2_CPP_IMPL_V1 is not supported under Python 3."
+#endif
+static int kImplVersion = 1;
+#else
+#ifdef PYTHON_PROTO2_CPP_IMPL_V2
+static int kImplVersion = 2;
+#else
+#ifdef PYTHON_PROTO2_PYTHON_IMPL
+static int kImplVersion = 0;
+#else
+
+// The defaults are set here. Python 3 uses the fast C++ APIv2 by default.
+// Python 2 still uses the Python version by default until some compatibility
+// issues can be worked around.
+#if PY_MAJOR_VERSION >= 3
+static int kImplVersion = 2;
+#else
+static int kImplVersion = 0;
+#endif
+
+#endif // PYTHON_PROTO2_PYTHON_IMPL
+#endif // PYTHON_PROTO2_CPP_IMPL_V2
+#endif // PYTHON_PROTO2_CPP_IMPL_V1
+
+static const char* kImplVersionName = "api_version";
+
+static const char* kModuleName = "_api_implementation";
+static const char kModuleDocstring[] =
+"_api_implementation is a module that exposes compile-time constants that\n"
+"determine the default API implementation to use for Python proto2.\n"
+"\n"
+"It complements api_implementation.py by setting defaults using compile-time\n"
+"constants defined in C, such that one can set defaults at compilation\n"
+"(e.g. with blaze flag --copt=-DPYTHON_PROTO2_CPP_IMPL_V2).";
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef _module = {
+ PyModuleDef_HEAD_INIT,
+ kModuleName,
+ kModuleDocstring,
+ -1,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+#define INITFUNC PyInit__api_implementation
+#define INITFUNC_ERRORVAL NULL
+#else
+#define INITFUNC init_api_implementation
+#define INITFUNC_ERRORVAL
+#endif
+
+extern "C" {
+ PyMODINIT_FUNC INITFUNC() {
+#if PY_MAJOR_VERSION >= 3
+ PyObject *module = PyModule_Create(&_module);
+#else
+ PyObject *module = Py_InitModule3(
+ const_cast<char*>(kModuleName),
+ NULL,
+ const_cast<char*>(kModuleDocstring));
+#endif
+ if (module == NULL) {
+ return INITFUNC_ERRORVAL;
+ }
+
+ // Adds the module variable "api_version".
+ if (PyModule_AddIntConstant(
+ module,
+ const_cast<char*>(kImplVersionName),
+ kImplVersion))
+#if PY_MAJOR_VERSION < 3
+ return;
+#else
+ { Py_DECREF(module); return NULL; }
+
+ return module;
+#endif
+ }
+}
+
+} // namespace python
+} // namespace protobuf
+} // namespace google
diff --git a/python/google/protobuf/internal/api_implementation.py b/python/google/protobuf/internal/api_implementation.py
new file mode 100755
index 0000000..f7926c1
--- /dev/null
+++ b/python/google/protobuf/internal/api_implementation.py
@@ -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.
+
+"""Determine which implementation of the protobuf API is used in this process.
+"""
+
+import os
+import sys
+
+try:
+ # pylint: disable=g-import-not-at-top
+ from google.protobuf.internal import _api_implementation
+ # The compile-time constants in the _api_implementation module can be used to
+ # switch to a certain implementation of the Python API at build time.
+ _api_version = _api_implementation.api_version
+ del _api_implementation
+except ImportError:
+ _api_version = 0
+
+_default_implementation_type = (
+ 'python' if _api_version == 0 else 'cpp')
+_default_version_str = (
+ '1' if _api_version <= 1 else '2')
+
+# This environment variable can be used to switch to a certain implementation
+# of the Python API, overriding the compile-time constants in the
+# _api_implementation module. Right now only 'python' and 'cpp' are valid
+# values. Any other value will be ignored.
+_implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION',
+ _default_implementation_type)
+
+if _implementation_type != 'python':
+ _implementation_type = 'cpp'
+
+# 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 1 and 2 are valid values. Any other
+# value will be ignored.
+_implementation_version_str = os.getenv(
+ 'PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION',
+ _default_version_str)
+
+if _implementation_version_str not in ('1', '2'):
+ raise ValueError(
+ "unsupported PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION: '" +
+ _implementation_version_str + "' (supported versions: 1, 2)"
+ )
+
+_implementation_version = int(_implementation_version_str)
+
+
+# Usage of this function is discouraged. Clients shouldn't care which
+# implementation of the API is in use. Note that there is no guarantee
+# that differences between APIs will be maintained.
+# Please don't use this function if possible.
+def Type():
+ return _implementation_type
+
+
+# See comment on 'Type' above.
+def Version():
+ return _implementation_version
diff --git a/python/google/protobuf/internal/api_implementation_default_test.py b/python/google/protobuf/internal/api_implementation_default_test.py
new file mode 100644
index 0000000..78d5cf2
--- /dev/null
+++ b/python/google/protobuf/internal/api_implementation_default_test.py
@@ -0,0 +1,63 @@
+#! /usr/bin/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 that the api_implementation defaults are what we expect."""
+
+import os
+import sys
+# Clear environment implementation settings before the google3 imports.
+os.environ.pop('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION', None)
+os.environ.pop('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION', None)
+
+# pylint: disable=g-import-not-at-top
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+
+
+class ApiImplementationDefaultTest(basetest.TestCase):
+
+ if sys.version_info.major <= 2:
+
+ def testThatPythonIsTheDefault(self):
+ """If -DPYTHON_PROTO_*IMPL* was given at build time, this may fail."""
+ self.assertEqual('python', api_implementation.Type())
+
+ else:
+
+ def testThatCppApiV2IsTheDefault(self):
+ """If -DPYTHON_PROTO_*IMPL* was given at build time, this may fail."""
+ self.assertEqual('cpp', api_implementation.Type())
+ self.assertEqual(2, api_implementation.Version())
+
+
+if __name__ == '__main__':
+ basetest.main()
diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py
index 5cc7d6d..20bfa85 100755
--- a/python/google/protobuf/internal/containers.py
+++ b/python/google/protobuf/internal/containers.py
@@ -1,6 +1,6 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -72,9 +72,20 @@ class BaseContainer(object):
# The concrete classes should define __eq__.
return not self == other
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
def __repr__(self):
return repr(self._values)
+ def sort(self, *args, **kwargs):
+ # Continue to support the old sort_function keyword argument.
+ # This is expected to be a rare occurrence, so use LBYL to avoid
+ # the overhead of actually catching KeyError.
+ if 'sort_function' in kwargs:
+ kwargs['cmp'] = kwargs.pop('sort_function')
+ self._values.sort(*args, **kwargs)
+
class RepeatedScalarFieldContainer(BaseContainer):
@@ -97,15 +108,13 @@ class RepeatedScalarFieldContainer(BaseContainer):
def append(self, value):
"""Appends an item to the list. Similar to list.append()."""
- self._type_checker.CheckValue(value)
- self._values.append(value)
+ self._values.append(self._type_checker.CheckValue(value))
if not self._message_listener.dirty:
self._message_listener.Modified()
def insert(self, key, value):
"""Inserts the item at the specified position. Similar to list.insert()."""
- self._type_checker.CheckValue(value)
- self._values.insert(key, value)
+ self._values.insert(key, self._type_checker.CheckValue(value))
if not self._message_listener.dirty:
self._message_listener.Modified()
@@ -116,8 +125,7 @@ class RepeatedScalarFieldContainer(BaseContainer):
new_values = []
for elem in elem_seq:
- self._type_checker.CheckValue(elem)
- new_values.append(elem)
+ new_values.append(self._type_checker.CheckValue(elem))
self._values.extend(new_values)
self._message_listener.Modified()
@@ -135,9 +143,13 @@ class RepeatedScalarFieldContainer(BaseContainer):
def __setitem__(self, key, value):
"""Sets the item on the specified position."""
- self._type_checker.CheckValue(value)
- self._values[key] = value
- self._message_listener.Modified()
+ if isinstance(key, slice): # PY3
+ if key.step is not None:
+ raise ValueError('Extended slices not supported')
+ self.__setslice__(key.start, key.stop, value)
+ else:
+ self._values[key] = self._type_checker.CheckValue(value)
+ self._message_listener.Modified()
def __getslice__(self, start, stop):
"""Retrieves the subset of items from between the specified indices."""
@@ -147,8 +159,7 @@ class RepeatedScalarFieldContainer(BaseContainer):
"""Sets the subset of items from between the specified indices."""
new_values = []
for value in values:
- self._type_checker.CheckValue(value)
- new_values.append(value)
+ new_values.append(self._type_checker.CheckValue(value))
self._values[start:stop] = new_values
self._message_listener.Modified()
@@ -198,28 +209,42 @@ class RepeatedCompositeFieldContainer(BaseContainer):
super(RepeatedCompositeFieldContainer, self).__init__(message_listener)
self._message_descriptor = message_descriptor
- def add(self):
- new_element = self._message_descriptor._concrete_class()
+ def add(self, **kwargs):
+ """Adds a new element at the end of the list and returns it. Keyword
+ arguments may be used to initialize the element.
+ """
+ new_element = self._message_descriptor._concrete_class(**kwargs)
new_element._SetListener(self._message_listener)
self._values.append(new_element)
if not self._message_listener.dirty:
self._message_listener.Modified()
return new_element
- def MergeFrom(self, other):
- """Appends the contents of another repeated field of the same type to this
- one, copying each individual message.
+ def extend(self, elem_seq):
+ """Extends by appending the given sequence of elements of the same type
+ as this one, copying each individual message.
"""
message_class = self._message_descriptor._concrete_class
listener = self._message_listener
values = self._values
- for message in other._values:
+ for message in elem_seq:
new_element = message_class()
new_element._SetListener(listener)
new_element.MergeFrom(message)
values.append(new_element)
listener.Modified()
+ def MergeFrom(self, other):
+ """Appends the contents of another repeated field of the same type to this
+ one, copying each individual message.
+ """
+ self.extend(other._values)
+
+ def remove(self, elem):
+ """Removes an item from the list. Similar to list.remove()."""
+ self._values.remove(elem)
+ self._message_listener.Modified()
+
def __getslice__(self, start, stop):
"""Retrieves the subset of items from between the specified indices."""
return self._values[start:stop]
diff --git a/python/google/protobuf/internal/cpp_message.py b/python/google/protobuf/internal/cpp_message.py
new file mode 100755
index 0000000..0313cb0
--- /dev/null
+++ b/python/google/protobuf/internal/cpp_message.py
@@ -0,0 +1,663 @@
+# 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 helper functions used to create protocol message classes from
+Descriptor objects at runtime backed by the protocol buffer C++ API.
+"""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+import copy_reg
+import operator
+from google.protobuf.internal import _net_proto2___python
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import message
+
+
+_LABEL_REPEATED = _net_proto2___python.LABEL_REPEATED
+_LABEL_OPTIONAL = _net_proto2___python.LABEL_OPTIONAL
+_CPPTYPE_MESSAGE = _net_proto2___python.CPPTYPE_MESSAGE
+_TYPE_MESSAGE = _net_proto2___python.TYPE_MESSAGE
+
+
+def GetDescriptorPool():
+ """Creates a new DescriptorPool C++ object."""
+ return _net_proto2___python.NewCDescriptorPool()
+
+
+_pool = GetDescriptorPool()
+
+
+def GetFieldDescriptor(full_field_name):
+ """Searches for a field descriptor given a full field name."""
+ return _pool.FindFieldByName(full_field_name)
+
+
+def BuildFile(content):
+ """Registers a new proto file in the underlying C++ descriptor pool."""
+ _net_proto2___python.BuildFile(content)
+
+
+def GetExtensionDescriptor(full_extension_name):
+ """Searches for extension descriptor given a full field name."""
+ return _pool.FindExtensionByName(full_extension_name)
+
+
+def NewCMessage(full_message_name):
+ """Creates a new C++ protocol message by its name."""
+ return _net_proto2___python.NewCMessage(full_message_name)
+
+
+def ScalarProperty(cdescriptor):
+ """Returns a scalar property for the given descriptor."""
+
+ def Getter(self):
+ return self._cmsg.GetScalar(cdescriptor)
+
+ def Setter(self, value):
+ self._cmsg.SetScalar(cdescriptor, value)
+
+ return property(Getter, Setter)
+
+
+def CompositeProperty(cdescriptor, message_type):
+ """Returns a Python property the given composite field."""
+
+ def Getter(self):
+ sub_message = self._composite_fields.get(cdescriptor.name, None)
+ if sub_message is None:
+ cmessage = self._cmsg.NewSubMessage(cdescriptor)
+ sub_message = message_type._concrete_class(__cmessage=cmessage)
+ self._composite_fields[cdescriptor.name] = sub_message
+ return sub_message
+
+ return property(Getter)
+
+
+class RepeatedScalarContainer(object):
+ """Container for repeated scalar fields."""
+
+ __slots__ = ['_message', '_cfield_descriptor', '_cmsg']
+
+ def __init__(self, msg, cfield_descriptor):
+ self._message = msg
+ self._cmsg = msg._cmsg
+ self._cfield_descriptor = cfield_descriptor
+
+ def append(self, value):
+ self._cmsg.AddRepeatedScalar(
+ self._cfield_descriptor, value)
+
+ def extend(self, sequence):
+ for element in sequence:
+ self.append(element)
+
+ def insert(self, key, value):
+ values = self[slice(None, None, None)]
+ values.insert(key, value)
+ self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
+
+ def remove(self, value):
+ values = self[slice(None, None, None)]
+ values.remove(value)
+ self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
+
+ def __setitem__(self, key, value):
+ values = self[slice(None, None, None)]
+ values[key] = value
+ self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
+
+ def __getitem__(self, key):
+ return self._cmsg.GetRepeatedScalar(self._cfield_descriptor, key)
+
+ def __delitem__(self, key):
+ self._cmsg.DeleteRepeatedField(self._cfield_descriptor, key)
+
+ def __len__(self):
+ return len(self[slice(None, None, None)])
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if not operator.isSequenceType(other):
+ raise TypeError(
+ 'Can only compare repeated scalar fields against sequences.')
+ # We are presumably comparing against some other sequence type.
+ return other == self[slice(None, None, None)]
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ def sort(self, *args, **kwargs):
+ # Maintain compatibility with the previous interface.
+ if 'sort_function' in kwargs:
+ kwargs['cmp'] = kwargs.pop('sort_function')
+ self._cmsg.AssignRepeatedScalar(self._cfield_descriptor,
+ sorted(self, *args, **kwargs))
+
+
+def RepeatedScalarProperty(cdescriptor):
+ """Returns a Python property the given repeated scalar field."""
+
+ def Getter(self):
+ container = self._composite_fields.get(cdescriptor.name, None)
+ if container is None:
+ container = RepeatedScalarContainer(self, cdescriptor)
+ self._composite_fields[cdescriptor.name] = container
+ return container
+
+ def Setter(self, new_value):
+ raise AttributeError('Assignment not allowed to repeated field '
+ '"%s" in protocol message object.' % cdescriptor.name)
+
+ doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name
+ return property(Getter, Setter, doc=doc)
+
+
+class RepeatedCompositeContainer(object):
+ """Container for repeated composite fields."""
+
+ __slots__ = ['_message', '_subclass', '_cfield_descriptor', '_cmsg']
+
+ def __init__(self, msg, cfield_descriptor, subclass):
+ self._message = msg
+ self._cmsg = msg._cmsg
+ self._subclass = subclass
+ self._cfield_descriptor = cfield_descriptor
+
+ def add(self, **kwargs):
+ cmessage = self._cmsg.AddMessage(self._cfield_descriptor)
+ return self._subclass(__cmessage=cmessage, __owner=self._message, **kwargs)
+
+ def extend(self, elem_seq):
+ """Extends by appending the given sequence of elements of the same type
+ as this one, copying each individual message.
+ """
+ for message in elem_seq:
+ self.add().MergeFrom(message)
+
+ def remove(self, value):
+ # TODO(protocol-devel): This is inefficient as it needs to generate a
+ # message pointer for each message only to do index(). Move this to a C++
+ # extension function.
+ self.__delitem__(self[slice(None, None, None)].index(value))
+
+ def MergeFrom(self, other):
+ for message in other[:]:
+ self.add().MergeFrom(message)
+
+ def __getitem__(self, key):
+ cmessages = self._cmsg.GetRepeatedMessage(
+ self._cfield_descriptor, key)
+ subclass = self._subclass
+ if not isinstance(cmessages, list):
+ return subclass(__cmessage=cmessages, __owner=self._message)
+
+ return [subclass(__cmessage=m, __owner=self._message) for m in cmessages]
+
+ def __delitem__(self, key):
+ self._cmsg.DeleteRepeatedField(
+ self._cfield_descriptor, key)
+
+ def __len__(self):
+ return self._cmsg.FieldLength(self._cfield_descriptor)
+
+ def __eq__(self, other):
+ """Compares the current instance with another one."""
+ if self is other:
+ return True
+ if not isinstance(other, self.__class__):
+ raise TypeError('Can only compare repeated composite fields against '
+ 'other repeated composite fields.')
+ messages = self[slice(None, None, None)]
+ other_messages = other[slice(None, None, None)]
+ return messages == other_messages
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ def sort(self, cmp=None, key=None, reverse=False, **kwargs):
+ # Maintain compatibility with the old interface.
+ if cmp is None and 'sort_function' in kwargs:
+ cmp = kwargs.pop('sort_function')
+
+ # The cmp function, if provided, is passed the results of the key function,
+ # so we only need to wrap one of them.
+ if key is None:
+ index_key = self.__getitem__
+ else:
+ index_key = lambda i: key(self[i])
+
+ # Sort the list of current indexes by the underlying object.
+ indexes = range(len(self))
+ indexes.sort(cmp=cmp, key=index_key, reverse=reverse)
+
+ # Apply the transposition.
+ for dest, src in enumerate(indexes):
+ if dest == src:
+ continue
+ self._cmsg.SwapRepeatedFieldElements(self._cfield_descriptor, dest, src)
+ # Don't swap the same value twice.
+ indexes[src] = src
+
+
+def RepeatedCompositeProperty(cdescriptor, message_type):
+ """Returns a Python property for the given repeated composite field."""
+
+ def Getter(self):
+ container = self._composite_fields.get(cdescriptor.name, None)
+ if container is None:
+ container = RepeatedCompositeContainer(
+ self, cdescriptor, message_type._concrete_class)
+ self._composite_fields[cdescriptor.name] = container
+ return container
+
+ def Setter(self, new_value):
+ raise AttributeError('Assignment not allowed to repeated field '
+ '"%s" in protocol message object.' % cdescriptor.name)
+
+ doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name
+ return property(Getter, Setter, doc=doc)
+
+
+class ExtensionDict(object):
+ """Extension dictionary added to each protocol message."""
+
+ def __init__(self, msg):
+ self._message = msg
+ self._cmsg = msg._cmsg
+ self._values = {}
+
+ def __setitem__(self, extension, value):
+ from google.protobuf import descriptor
+ if not isinstance(extension, descriptor.FieldDescriptor):
+ raise KeyError('Bad extension %r.' % (extension,))
+ cdescriptor = extension._cdescriptor
+ if (cdescriptor.label != _LABEL_OPTIONAL or
+ cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+ raise TypeError('Extension %r is repeated and/or a composite type.' % (
+ extension.full_name,))
+ self._cmsg.SetScalar(cdescriptor, value)
+ self._values[extension] = value
+
+ def __getitem__(self, extension):
+ from google.protobuf import descriptor
+ if not isinstance(extension, descriptor.FieldDescriptor):
+ raise KeyError('Bad extension %r.' % (extension,))
+
+ cdescriptor = extension._cdescriptor
+ if (cdescriptor.label != _LABEL_REPEATED and
+ cdescriptor.cpp_type != _CPPTYPE_MESSAGE):
+ return self._cmsg.GetScalar(cdescriptor)
+
+ ext = self._values.get(extension, None)
+ if ext is not None:
+ return ext
+
+ ext = self._CreateNewHandle(extension)
+ self._values[extension] = ext
+ return ext
+
+ def ClearExtension(self, extension):
+ from google.protobuf import descriptor
+ if not isinstance(extension, descriptor.FieldDescriptor):
+ raise KeyError('Bad extension %r.' % (extension,))
+ self._cmsg.ClearFieldByDescriptor(extension._cdescriptor)
+ if extension in self._values:
+ del self._values[extension]
+
+ def HasExtension(self, extension):
+ from google.protobuf import descriptor
+ if not isinstance(extension, descriptor.FieldDescriptor):
+ raise KeyError('Bad extension %r.' % (extension,))
+ return self._cmsg.HasFieldByDescriptor(extension._cdescriptor)
+
+ def _FindExtensionByName(self, name):
+ """Tries to find a known extension with the specified name.
+
+ Args:
+ name: Extension full name.
+
+ Returns:
+ Extension field descriptor.
+ """
+ return self._message._extensions_by_name.get(name, None)
+
+ def _CreateNewHandle(self, extension):
+ cdescriptor = extension._cdescriptor
+ if (cdescriptor.label != _LABEL_REPEATED and
+ cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+ cmessage = self._cmsg.NewSubMessage(cdescriptor)
+ return extension.message_type._concrete_class(__cmessage=cmessage)
+
+ if cdescriptor.label == _LABEL_REPEATED:
+ if cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
+ return RepeatedCompositeContainer(
+ self._message, cdescriptor, extension.message_type._concrete_class)
+ else:
+ return RepeatedScalarContainer(self._message, cdescriptor)
+ # This shouldn't happen!
+ assert False
+ return None
+
+
+def NewMessage(bases, message_descriptor, dictionary):
+ """Creates a new protocol message *class*."""
+ _AddClassAttributesForNestedExtensions(message_descriptor, dictionary)
+ _AddEnumValues(message_descriptor, dictionary)
+ _AddDescriptors(message_descriptor, dictionary)
+ return bases
+
+
+def InitMessage(message_descriptor, cls):
+ """Constructs a new message instance (called before instance's __init__)."""
+ cls._extensions_by_name = {}
+ _AddInitMethod(message_descriptor, cls)
+ _AddMessageMethods(message_descriptor, cls)
+ _AddPropertiesForExtensions(message_descriptor, cls)
+ copy_reg.pickle(cls, lambda obj: (cls, (), obj.__getstate__()))
+
+
+def _AddDescriptors(message_descriptor, dictionary):
+ """Sets up a new protocol message class dictionary.
+
+ Args:
+ message_descriptor: A Descriptor instance describing this message type.
+ dictionary: Class dictionary to which we'll add a '__slots__' entry.
+ """
+ dictionary['__descriptors'] = {}
+ for field in message_descriptor.fields:
+ dictionary['__descriptors'][field.name] = GetFieldDescriptor(
+ field.full_name)
+
+ dictionary['__slots__'] = list(dictionary['__descriptors'].iterkeys()) + [
+ '_cmsg', '_owner', '_composite_fields', 'Extensions', '_HACK_REFCOUNTS']
+
+
+def _AddEnumValues(message_descriptor, dictionary):
+ """Sets class-level attributes for all enum fields defined in this message.
+
+ Args:
+ message_descriptor: Descriptor object for this message type.
+ dictionary: Class dictionary that should be populated.
+ """
+ for enum_type in message_descriptor.enum_types:
+ dictionary[enum_type.name] = enum_type_wrapper.EnumTypeWrapper(enum_type)
+ for enum_value in enum_type.values:
+ dictionary[enum_value.name] = enum_value.number
+
+
+def _AddClassAttributesForNestedExtensions(message_descriptor, dictionary):
+ """Adds class attributes for the nested extensions."""
+ extension_dict = message_descriptor.extensions_by_name
+ for extension_name, extension_field in extension_dict.iteritems():
+ assert extension_name not in dictionary
+ dictionary[extension_name] = extension_field
+
+
+def _AddInitMethod(message_descriptor, cls):
+ """Adds an __init__ method to cls."""
+
+ # Create and attach message field properties to the message class.
+ # This can be done just once per message class, since property setters and
+ # getters are passed the message instance.
+ # This makes message instantiation extremely fast, and at the same time it
+ # doesn't require the creation of property objects for each message instance,
+ # which saves a lot of memory.
+ for field in message_descriptor.fields:
+ field_cdescriptor = cls.__descriptors[field.name]
+ if field.label == _LABEL_REPEATED:
+ if field.cpp_type == _CPPTYPE_MESSAGE:
+ value = RepeatedCompositeProperty(field_cdescriptor, field.message_type)
+ else:
+ value = RepeatedScalarProperty(field_cdescriptor)
+ elif field.cpp_type == _CPPTYPE_MESSAGE:
+ value = CompositeProperty(field_cdescriptor, field.message_type)
+ else:
+ value = ScalarProperty(field_cdescriptor)
+ setattr(cls, field.name, value)
+
+ # Attach a constant with the field number.
+ constant_name = field.name.upper() + '_FIELD_NUMBER'
+ setattr(cls, constant_name, field.number)
+
+ def Init(self, **kwargs):
+ """Message constructor."""
+ cmessage = kwargs.pop('__cmessage', None)
+ if cmessage:
+ self._cmsg = cmessage
+ else:
+ self._cmsg = NewCMessage(message_descriptor.full_name)
+
+ # Keep a reference to the owner, as the owner keeps a reference to the
+ # underlying protocol buffer message.
+ owner = kwargs.pop('__owner', None)
+ if owner:
+ self._owner = owner
+
+ if message_descriptor.is_extendable:
+ self.Extensions = ExtensionDict(self)
+ else:
+ # Reference counting in the C++ code is broken and depends on
+ # the Extensions reference to keep this object alive during unit
+ # tests (see b/4856052). Remove this once b/4945904 is fixed.
+ self._HACK_REFCOUNTS = self
+ self._composite_fields = {}
+
+ for field_name, field_value in kwargs.iteritems():
+ field_cdescriptor = self.__descriptors.get(field_name, None)
+ if not field_cdescriptor:
+ raise ValueError('Protocol message has no "%s" field.' % field_name)
+ if field_cdescriptor.label == _LABEL_REPEATED:
+ if field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
+ field_name = getattr(self, field_name)
+ for val in field_value:
+ field_name.add().MergeFrom(val)
+ else:
+ getattr(self, field_name).extend(field_value)
+ elif field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
+ getattr(self, field_name).MergeFrom(field_value)
+ else:
+ setattr(self, field_name, field_value)
+
+ Init.__module__ = None
+ Init.__doc__ = None
+ cls.__init__ = Init
+
+
+def _IsMessageSetExtension(field):
+ """Checks if a field is a message set extension."""
+ return (field.is_extension and
+ field.containing_type.has_options and
+ field.containing_type.GetOptions().message_set_wire_format and
+ field.type == _TYPE_MESSAGE and
+ field.message_type == field.extension_scope and
+ field.label == _LABEL_OPTIONAL)
+
+
+def _AddMessageMethods(message_descriptor, cls):
+ """Adds the methods to a protocol message class."""
+ if message_descriptor.is_extendable:
+
+ def ClearExtension(self, extension):
+ self.Extensions.ClearExtension(extension)
+
+ def HasExtension(self, extension):
+ return self.Extensions.HasExtension(extension)
+
+ def HasField(self, field_name):
+ return self._cmsg.HasField(field_name)
+
+ def ClearField(self, field_name):
+ child_cmessage = None
+ if field_name in self._composite_fields:
+ child_field = self._composite_fields[field_name]
+ del self._composite_fields[field_name]
+
+ child_cdescriptor = self.__descriptors[field_name]
+ # TODO(anuraag): Support clearing repeated message fields as well.
+ if (child_cdescriptor.label != _LABEL_REPEATED and
+ child_cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+ child_field._owner = None
+ child_cmessage = child_field._cmsg
+
+ if child_cmessage is not None:
+ self._cmsg.ClearField(field_name, child_cmessage)
+ else:
+ self._cmsg.ClearField(field_name)
+
+ def Clear(self):
+ cmessages_to_release = []
+ for field_name, child_field in self._composite_fields.iteritems():
+ child_cdescriptor = self.__descriptors[field_name]
+ # TODO(anuraag): Support clearing repeated message fields as well.
+ if (child_cdescriptor.label != _LABEL_REPEATED and
+ child_cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+ child_field._owner = None
+ cmessages_to_release.append((child_cdescriptor, child_field._cmsg))
+ self._composite_fields.clear()
+ self._cmsg.Clear(cmessages_to_release)
+
+ def IsInitialized(self, errors=None):
+ if self._cmsg.IsInitialized():
+ return True
+ if errors is not None:
+ errors.extend(self.FindInitializationErrors());
+ return False
+
+ def SerializeToString(self):
+ if not self.IsInitialized():
+ raise message.EncodeError(
+ 'Message %s is missing required fields: %s' % (
+ self._cmsg.full_name, ','.join(self.FindInitializationErrors())))
+ return self._cmsg.SerializeToString()
+
+ def SerializePartialToString(self):
+ return self._cmsg.SerializePartialToString()
+
+ def ParseFromString(self, serialized):
+ self.Clear()
+ self.MergeFromString(serialized)
+
+ def MergeFromString(self, serialized):
+ byte_size = self._cmsg.MergeFromString(serialized)
+ if byte_size < 0:
+ raise message.DecodeError('Unable to merge from string.')
+ return byte_size
+
+ def MergeFrom(self, msg):
+ if not isinstance(msg, cls):
+ raise TypeError(
+ "Parameter to MergeFrom() must be instance of same class: "
+ "expected %s got %s." % (cls.__name__, type(msg).__name__))
+ self._cmsg.MergeFrom(msg._cmsg)
+
+ def CopyFrom(self, msg):
+ self._cmsg.CopyFrom(msg._cmsg)
+
+ def ByteSize(self):
+ return self._cmsg.ByteSize()
+
+ def SetInParent(self):
+ return self._cmsg.SetInParent()
+
+ def ListFields(self):
+ all_fields = []
+ field_list = self._cmsg.ListFields()
+ fields_by_name = cls.DESCRIPTOR.fields_by_name
+ for is_extension, field_name in field_list:
+ if is_extension:
+ extension = cls._extensions_by_name[field_name]
+ all_fields.append((extension, self.Extensions[extension]))
+ else:
+ field_descriptor = fields_by_name[field_name]
+ all_fields.append(
+ (field_descriptor, getattr(self, field_name)))
+ all_fields.sort(key=lambda item: item[0].number)
+ return all_fields
+
+ def FindInitializationErrors(self):
+ return self._cmsg.FindInitializationErrors()
+
+ def __str__(self):
+ return str(self._cmsg)
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if not isinstance(other, self.__class__):
+ return False
+ return self.ListFields() == other.ListFields()
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ def __unicode__(self):
+ # Lazy import to prevent circular import when text_format imports this file.
+ from google.protobuf import text_format
+ return text_format.MessageToString(self, as_utf8=True).decode('utf-8')
+
+ # Attach the local methods to the message class.
+ for key, value in locals().copy().iteritems():
+ if key not in ('key', 'value', '__builtins__', '__name__', '__doc__'):
+ setattr(cls, key, value)
+
+ # Static methods:
+
+ def RegisterExtension(extension_handle):
+ extension_handle.containing_type = cls.DESCRIPTOR
+ cls._extensions_by_name[extension_handle.full_name] = extension_handle
+
+ if _IsMessageSetExtension(extension_handle):
+ # MessageSet extension. Also register under type name.
+ cls._extensions_by_name[
+ extension_handle.message_type.full_name] = extension_handle
+ cls.RegisterExtension = staticmethod(RegisterExtension)
+
+ def FromString(string):
+ msg = cls()
+ msg.MergeFromString(string)
+ return msg
+ cls.FromString = staticmethod(FromString)
+
+
+
+def _AddPropertiesForExtensions(message_descriptor, cls):
+ """Adds properties for all fields in this protocol message type."""
+ extension_dict = message_descriptor.extensions_by_name
+ for extension_name, extension_field in extension_dict.iteritems():
+ constant_name = extension_name.upper() + '_FIELD_NUMBER'
+ setattr(cls, constant_name, extension_field.number)
diff --git a/python/google/protobuf/internal/decoder.py b/python/google/protobuf/internal/decoder.py
index 461a30c..a4b9060 100755
--- a/python/google/protobuf/internal/decoder.py
+++ b/python/google/protobuf/internal/decoder.py
@@ -1,6 +1,6 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -28,6 +28,10 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#PY25 compatible for GAE.
+#
+# Copyright 2009 Google Inc. All Rights Reserved.
+
"""Code for decoding protocol buffer primitives.
This code is very similar to encoder.py -- read the docs for that module first.
@@ -81,17 +85,26 @@ we repeatedly read a tag, look up the corresponding decoder, and invoke it.
__author__ = 'kenton@google.com (Kenton Varda)'
import struct
+import sys ##PY25
+_PY2 = sys.version_info[0] < 3 ##PY25
from google.protobuf.internal import encoder
from google.protobuf.internal import wire_format
from google.protobuf import message
+# This will overflow and thus become IEEE-754 "infinity". We would use
+# "float('inf')" but it doesn't work on Windows pre-Python-2.6.
+_POS_INF = 1e10000
+_NEG_INF = -_POS_INF
+_NAN = _POS_INF * 0
+
+
# This is not for optimization, but rather to avoid conflicts with local
# variables named "message".
_DecodeError = message.DecodeError
-def _VarintDecoder(mask):
+def _VarintDecoder(mask, result_type):
"""Return an encoder for a basic varint value (does not include tag).
Decoded values will be bitwise-anded with the given mask before being
@@ -102,15 +115,18 @@ def _VarintDecoder(mask):
"""
local_ord = ord
+ py2 = _PY2 ##PY25
+##!PY25 py2 = str is bytes
def DecodeVarint(buffer, pos):
result = 0
shift = 0
while 1:
- b = local_ord(buffer[pos])
+ b = local_ord(buffer[pos]) if py2 else buffer[pos]
result |= ((b & 0x7f) << shift)
pos += 1
if not (b & 0x80):
result &= mask
+ result = result_type(result)
return (result, pos)
shift += 7
if shift >= 64:
@@ -118,15 +134,17 @@ def _VarintDecoder(mask):
return DecodeVarint
-def _SignedVarintDecoder(mask):
+def _SignedVarintDecoder(mask, result_type):
"""Like _VarintDecoder() but decodes signed values."""
local_ord = ord
+ py2 = _PY2 ##PY25
+##!PY25 py2 = str is bytes
def DecodeVarint(buffer, pos):
result = 0
shift = 0
while 1:
- b = local_ord(buffer[pos])
+ b = local_ord(buffer[pos]) if py2 else buffer[pos]
result |= ((b & 0x7f) << shift)
pos += 1
if not (b & 0x80):
@@ -135,19 +153,23 @@ def _SignedVarintDecoder(mask):
result |= ~mask
else:
result &= mask
+ result = result_type(result)
return (result, pos)
shift += 7
if shift >= 64:
raise _DecodeError('Too many bytes when decoding varint.')
return DecodeVarint
+# 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.
-_DecodeVarint = _VarintDecoder((1 << 64) - 1)
-_DecodeSignedVarint = _SignedVarintDecoder((1 << 64) - 1)
+_DecodeVarint = _VarintDecoder((1 << 64) - 1, long)
+_DecodeSignedVarint = _SignedVarintDecoder((1 << 64) - 1, long)
# Use these versions for values which must be limited to 32 bits.
-_DecodeVarint32 = _VarintDecoder((1 << 32) - 1)
-_DecodeSignedVarint32 = _SignedVarintDecoder((1 << 32) - 1)
+_DecodeVarint32 = _VarintDecoder((1 << 32) - 1, int)
+_DecodeSignedVarint32 = _SignedVarintDecoder((1 << 32) - 1, int)
def ReadTag(buffer, pos):
@@ -161,8 +183,10 @@ def ReadTag(buffer, pos):
use that, but not in Python.
"""
+ py2 = _PY2 ##PY25
+##!PY25 py2 = str is bytes
start = pos
- while ord(buffer[pos]) & 0x80:
+ while (ord(buffer[pos]) if py2 else buffer[pos]) & 0x80:
pos += 1
pos += 1
return (buffer[start:pos], pos)
@@ -269,10 +293,161 @@ def _StructPackDecoder(wire_type, format):
return _SimpleDecoder(wire_type, InnerDecode)
+def _FloatDecoder():
+ """Returns a decoder for a float field.
+
+ This code works around a bug in struct.unpack for non-finite 32-bit
+ floating-point values.
+ """
+
+ local_unpack = struct.unpack
+ b = (lambda x:x) if _PY2 else lambda x:x.encode('latin1') ##PY25
+
+ def InnerDecode(buffer, pos):
+ # We expect a 32-bit value in little-endian byte order. Bit 1 is the sign
+ # bit, bits 2-9 represent the exponent, and bits 10-32 are the significand.
+ new_pos = pos + 4
+ float_bytes = buffer[pos:new_pos]
+
+ # If this value has all its exponent bits set, then it's non-finite.
+ # In Python 2.4, struct.unpack will convert it to a finite 64-bit value.
+ # To avoid that, we parse it specially.
+ if ((float_bytes[3:4] in b('\x7F\xFF')) ##PY25
+##!PY25 if ((float_bytes[3:4] in b'\x7F\xFF')
+ and (float_bytes[2:3] >= b('\x80'))): ##PY25
+##!PY25 and (float_bytes[2:3] >= b'\x80')):
+ # If at least one significand bit is set...
+ if float_bytes[0:3] != b('\x00\x00\x80'): ##PY25
+##!PY25 if float_bytes[0:3] != b'\x00\x00\x80':
+ return (_NAN, new_pos)
+ # If sign bit is set...
+ if float_bytes[3:4] == b('\xFF'): ##PY25
+##!PY25 if float_bytes[3:4] == b'\xFF':
+ return (_NEG_INF, new_pos)
+ return (_POS_INF, new_pos)
+
+ # Note that we expect someone up-stack to catch struct.error and convert
+ # it to _DecodeError -- this way we don't have to set up exception-
+ # handling blocks every time we parse one value.
+ result = local_unpack('<f', float_bytes)[0]
+ return (result, new_pos)
+ return _SimpleDecoder(wire_format.WIRETYPE_FIXED32, InnerDecode)
+
+
+def _DoubleDecoder():
+ """Returns a decoder for a double field.
+
+ This code works around a bug in struct.unpack for not-a-number.
+ """
+
+ local_unpack = struct.unpack
+ b = (lambda x:x) if _PY2 else lambda x:x.encode('latin1') ##PY25
+
+ def InnerDecode(buffer, pos):
+ # We expect a 64-bit value in little-endian byte order. Bit 1 is the sign
+ # bit, bits 2-12 represent the exponent, and bits 13-64 are the significand.
+ new_pos = pos + 8
+ double_bytes = buffer[pos:new_pos]
+
+ # If this value has all its exponent bits set and at least one significand
+ # bit set, it's not a number. In Python 2.4, struct.unpack will treat it
+ # as inf or -inf. To avoid that, we treat it specially.
+##!PY25 if ((double_bytes[7:8] in b'\x7F\xFF')
+##!PY25 and (double_bytes[6:7] >= b'\xF0')
+##!PY25 and (double_bytes[0:7] != b'\x00\x00\x00\x00\x00\x00\xF0')):
+ if ((double_bytes[7:8] in b('\x7F\xFF')) ##PY25
+ and (double_bytes[6:7] >= b('\xF0')) ##PY25
+ and (double_bytes[0:7] != b('\x00\x00\x00\x00\x00\x00\xF0'))): ##PY25
+ return (_NAN, new_pos)
+
+ # Note that we expect someone up-stack to catch struct.error and convert
+ # it to _DecodeError -- this way we don't have to set up exception-
+ # handling blocks every time we parse one value.
+ result = local_unpack('<d', double_bytes)[0]
+ return (result, new_pos)
+ return _SimpleDecoder(wire_format.WIRETYPE_FIXED64, InnerDecode)
+
+
+def EnumDecoder(field_number, is_repeated, is_packed, key, new_default):
+ enum_type = key.enum_type
+ if is_packed:
+ local_DecodeVarint = _DecodeVarint
+ def DecodePackedField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ (endpoint, pos) = local_DecodeVarint(buffer, pos)
+ endpoint += pos
+ if endpoint > end:
+ raise _DecodeError('Truncated message.')
+ while pos < endpoint:
+ value_start_pos = pos
+ (element, pos) = _DecodeSignedVarint32(buffer, pos)
+ if element in enum_type.values_by_number:
+ value.append(element)
+ else:
+ if not message._unknown_fields:
+ message._unknown_fields = []
+ tag_bytes = encoder.TagBytes(field_number,
+ wire_format.WIRETYPE_VARINT)
+ message._unknown_fields.append(
+ (tag_bytes, buffer[value_start_pos:pos]))
+ if pos > endpoint:
+ if element in enum_type.values_by_number:
+ del value[-1] # Discard corrupt value.
+ else:
+ del message._unknown_fields[-1]
+ raise _DecodeError('Packed element was truncated.')
+ return pos
+ return DecodePackedField
+ elif is_repeated:
+ tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT)
+ tag_len = len(tag_bytes)
+ def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ while 1:
+ (element, new_pos) = _DecodeSignedVarint32(buffer, pos)
+ if element in enum_type.values_by_number:
+ value.append(element)
+ else:
+ if not message._unknown_fields:
+ message._unknown_fields = []
+ message._unknown_fields.append(
+ (tag_bytes, buffer[pos:new_pos]))
+ # Predict that the next tag is another copy of the same repeated
+ # field.
+ pos = new_pos + tag_len
+ if buffer[new_pos:pos] != tag_bytes or new_pos >= end:
+ # Prediction failed. Return.
+ if new_pos > end:
+ raise _DecodeError('Truncated message.')
+ return new_pos
+ return DecodeRepeatedField
+ else:
+ def DecodeField(buffer, pos, end, message, field_dict):
+ value_start_pos = pos
+ (enum_value, pos) = _DecodeSignedVarint32(buffer, pos)
+ if pos > end:
+ raise _DecodeError('Truncated message.')
+ if enum_value in enum_type.values_by_number:
+ field_dict[key] = enum_value
+ else:
+ if not message._unknown_fields:
+ message._unknown_fields = []
+ tag_bytes = encoder.TagBytes(field_number,
+ wire_format.WIRETYPE_VARINT)
+ message._unknown_fields.append(
+ (tag_bytes, buffer[value_start_pos:pos]))
+ return pos
+ return DecodeField
+
+
# --------------------------------------------------------------------
-Int32Decoder = EnumDecoder = _SimpleDecoder(
+Int32Decoder = _SimpleDecoder(
wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32)
Int64Decoder = _SimpleDecoder(
@@ -294,8 +469,8 @@ Fixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<I')
Fixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<Q')
SFixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<i')
SFixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<q')
-FloatDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<f')
-DoubleDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<d')
+FloatDecoder = _FloatDecoder()
+DoubleDecoder = _DoubleDecoder()
BoolDecoder = _ModifiedDecoder(
wire_format.WIRETYPE_VARINT, _DecodeVarint, bool)
@@ -307,6 +482,14 @@ def StringDecoder(field_number, is_repeated, is_packed, key, new_default):
local_DecodeVarint = _DecodeVarint
local_unicode = unicode
+ def _ConvertToUnicode(byte_str):
+ try:
+ return local_unicode(byte_str, 'utf-8')
+ except UnicodeDecodeError, e:
+ # add more information to the error message and re-raise it.
+ e.reason = '%s in field: %s' % (e, key.full_name)
+ raise
+
assert not is_packed
if is_repeated:
tag_bytes = encoder.TagBytes(field_number,
@@ -321,7 +504,7 @@ def StringDecoder(field_number, is_repeated, is_packed, key, new_default):
new_pos = pos + size
if new_pos > end:
raise _DecodeError('Truncated string.')
- value.append(local_unicode(buffer[pos:new_pos], 'utf-8'))
+ value.append(_ConvertToUnicode(buffer[pos:new_pos]))
# Predict that the next tag is another copy of the same repeated field.
pos = new_pos + tag_len
if buffer[new_pos:pos] != tag_bytes or new_pos == end:
@@ -334,7 +517,7 @@ def StringDecoder(field_number, is_repeated, is_packed, key, new_default):
new_pos = pos + size
if new_pos > end:
raise _DecodeError('Truncated string.')
- field_dict[key] = local_unicode(buffer[pos:new_pos], 'utf-8')
+ field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos])
return new_pos
return DecodeField
@@ -503,6 +686,7 @@ def MessageSetItemDecoder(extensions_by_number):
local_SkipField = SkipField
def DecodeItem(buffer, pos, end, message, field_dict):
+ message_set_item_start = pos
type_id = -1
message_start = -1
message_end = -1
@@ -541,6 +725,11 @@ def MessageSetItemDecoder(extensions_by_number):
# The only reason _InternalParse would return early is if it encountered
# an end-group tag.
raise _DecodeError('Unexpected end-group tag.')
+ else:
+ if not message._unknown_fields:
+ message._unknown_fields = []
+ message._unknown_fields.append((MESSAGE_SET_ITEM_TAG,
+ buffer[message_set_item_start:pos]))
return pos
@@ -552,8 +741,10 @@ def MessageSetItemDecoder(extensions_by_number):
def _SkipVarint(buffer, pos, end):
"""Skip a varint value. Returns the new position."""
-
- while ord(buffer[pos]) & 0x80:
+ # Previously ord(buffer[pos]) raised IndexError when pos is out of range.
+ # With this code, ord(b'') raises TypeError. Both are handled in
+ # python_message.py to generate a 'Truncated message' error.
+ while ord(buffer[pos:pos+1]) & 0x80:
pos += 1
pos += 1
if pos > end:
@@ -620,7 +811,6 @@ def _FieldSkipper():
]
wiretype_mask = wire_format.TAG_TYPE_MASK
- local_ord = ord
def SkipField(buffer, pos, end, tag_bytes):
"""Skips a field with the specified tag.
@@ -633,7 +823,7 @@ def _FieldSkipper():
"""
# The wire type is always in the first byte since varints are little-endian.
- wire_type = local_ord(tag_bytes[0]) & wiretype_mask
+ wire_type = ord(tag_bytes[0:1]) & wiretype_mask
return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end)
return SkipField
diff --git a/python/google/protobuf/internal/descriptor_database_test.py b/python/google/protobuf/internal/descriptor_database_test.py
new file mode 100644
index 0000000..fc65b69
--- /dev/null
+++ b/python/google/protobuf/internal/descriptor_database_test.py
@@ -0,0 +1,63 @@
+#! /usr/bin/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.
+
+"""Tests for google.protobuf.descriptor_database."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+from google.apputils import basetest
+from google.protobuf import descriptor_pb2
+from google.protobuf.internal import factory_test2_pb2
+from google.protobuf import descriptor_database
+
+
+class DescriptorDatabaseTest(basetest.TestCase):
+
+ def testAdd(self):
+ db = descriptor_database.DescriptorDatabase()
+ file_desc_proto = descriptor_pb2.FileDescriptorProto.FromString(
+ factory_test2_pb2.DESCRIPTOR.serialized_pb)
+ db.Add(file_desc_proto)
+
+ self.assertEquals(file_desc_proto, db.FindFileByName(
+ 'google/protobuf/internal/factory_test2.proto'))
+ self.assertEquals(file_desc_proto, db.FindFileContainingSymbol(
+ 'google.protobuf.python.internal.Factory2Message'))
+ self.assertEquals(file_desc_proto, db.FindFileContainingSymbol(
+ 'google.protobuf.python.internal.Factory2Message.NestedFactory2Message'))
+ self.assertEquals(file_desc_proto, db.FindFileContainingSymbol(
+ 'google.protobuf.python.internal.Factory2Enum'))
+ self.assertEquals(file_desc_proto, db.FindFileContainingSymbol(
+ 'google.protobuf.python.internal.Factory2Message.NestedFactory2Enum'))
+
+if __name__ == '__main__':
+ basetest.main()
diff --git a/python/google/protobuf/internal/descriptor_pool_test.py b/python/google/protobuf/internal/descriptor_pool_test.py
new file mode 100644
index 0000000..d2f8557
--- /dev/null
+++ b/python/google/protobuf/internal/descriptor_pool_test.py
@@ -0,0 +1,564 @@
+#! /usr/bin/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.
+
+"""Tests for google.protobuf.descriptor_pool."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+import os
+import unittest
+
+from google.apputils import basetest
+from google.protobuf import unittest_pb2
+from google.protobuf import descriptor_pb2
+from google.protobuf.internal import api_implementation
+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 import descriptor
+from google.protobuf import descriptor_database
+from google.protobuf import descriptor_pool
+
+
+class DescriptorPoolTest(basetest.TestCase):
+
+ def setUp(self):
+ self.pool = descriptor_pool.DescriptorPool()
+ self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString(
+ factory_test1_pb2.DESCRIPTOR.serialized_pb)
+ self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString(
+ factory_test2_pb2.DESCRIPTOR.serialized_pb)
+ self.pool.Add(self.factory_test1_fd)
+ self.pool.Add(self.factory_test2_fd)
+
+ def testFindFileByName(self):
+ name1 = 'google/protobuf/internal/factory_test1.proto'
+ file_desc1 = self.pool.FindFileByName(name1)
+ self.assertIsInstance(file_desc1, descriptor.FileDescriptor)
+ self.assertEquals(name1, file_desc1.name)
+ self.assertEquals('google.protobuf.python.internal', file_desc1.package)
+ self.assertIn('Factory1Message', file_desc1.message_types_by_name)
+
+ name2 = 'google/protobuf/internal/factory_test2.proto'
+ file_desc2 = self.pool.FindFileByName(name2)
+ self.assertIsInstance(file_desc2, descriptor.FileDescriptor)
+ self.assertEquals(name2, file_desc2.name)
+ self.assertEquals('google.protobuf.python.internal', file_desc2.package)
+ self.assertIn('Factory2Message', file_desc2.message_types_by_name)
+
+ def testFindFileByNameFailure(self):
+ with self.assertRaises(KeyError):
+ self.pool.FindFileByName('Does not exist')
+
+ def testFindFileContainingSymbol(self):
+ file_desc1 = self.pool.FindFileContainingSymbol(
+ 'google.protobuf.python.internal.Factory1Message')
+ self.assertIsInstance(file_desc1, descriptor.FileDescriptor)
+ self.assertEquals('google/protobuf/internal/factory_test1.proto',
+ file_desc1.name)
+ self.assertEquals('google.protobuf.python.internal', file_desc1.package)
+ self.assertIn('Factory1Message', file_desc1.message_types_by_name)
+
+ file_desc2 = self.pool.FindFileContainingSymbol(
+ 'google.protobuf.python.internal.Factory2Message')
+ self.assertIsInstance(file_desc2, descriptor.FileDescriptor)
+ self.assertEquals('google/protobuf/internal/factory_test2.proto',
+ file_desc2.name)
+ self.assertEquals('google.protobuf.python.internal', file_desc2.package)
+ self.assertIn('Factory2Message', file_desc2.message_types_by_name)
+
+ def testFindFileContainingSymbolFailure(self):
+ with self.assertRaises(KeyError):
+ self.pool.FindFileContainingSymbol('Does not exist')
+
+ def testFindMessageTypeByName(self):
+ msg1 = self.pool.FindMessageTypeByName(
+ 'google.protobuf.python.internal.Factory1Message')
+ self.assertIsInstance(msg1, descriptor.Descriptor)
+ self.assertEquals('Factory1Message', msg1.name)
+ self.assertEquals('google.protobuf.python.internal.Factory1Message',
+ msg1.full_name)
+ self.assertEquals(None, msg1.containing_type)
+
+ nested_msg1 = msg1.nested_types[0]
+ self.assertEquals('NestedFactory1Message', nested_msg1.name)
+ self.assertEquals(msg1, nested_msg1.containing_type)
+
+ nested_enum1 = msg1.enum_types[0]
+ self.assertEquals('NestedFactory1Enum', nested_enum1.name)
+ self.assertEquals(msg1, nested_enum1.containing_type)
+
+ self.assertEquals(nested_msg1, msg1.fields_by_name[
+ 'nested_factory_1_message'].message_type)
+ self.assertEquals(nested_enum1, msg1.fields_by_name[
+ 'nested_factory_1_enum'].enum_type)
+
+ msg2 = self.pool.FindMessageTypeByName(
+ 'google.protobuf.python.internal.Factory2Message')
+ self.assertIsInstance(msg2, descriptor.Descriptor)
+ self.assertEquals('Factory2Message', msg2.name)
+ self.assertEquals('google.protobuf.python.internal.Factory2Message',
+ msg2.full_name)
+ self.assertIsNone(msg2.containing_type)
+
+ nested_msg2 = msg2.nested_types[0]
+ self.assertEquals('NestedFactory2Message', nested_msg2.name)
+ self.assertEquals(msg2, nested_msg2.containing_type)
+
+ nested_enum2 = msg2.enum_types[0]
+ self.assertEquals('NestedFactory2Enum', nested_enum2.name)
+ self.assertEquals(msg2, nested_enum2.containing_type)
+
+ self.assertEquals(nested_msg2, msg2.fields_by_name[
+ 'nested_factory_2_message'].message_type)
+ self.assertEquals(nested_enum2, msg2.fields_by_name[
+ 'nested_factory_2_enum'].enum_type)
+
+ self.assertTrue(msg2.fields_by_name['int_with_default'].has_default_value)
+ self.assertEquals(
+ 1776, msg2.fields_by_name['int_with_default'].default_value)
+
+ self.assertTrue(
+ msg2.fields_by_name['double_with_default'].has_default_value)
+ self.assertEquals(
+ 9.99, msg2.fields_by_name['double_with_default'].default_value)
+
+ self.assertTrue(
+ msg2.fields_by_name['string_with_default'].has_default_value)
+ self.assertEquals(
+ 'hello world', msg2.fields_by_name['string_with_default'].default_value)
+
+ self.assertTrue(msg2.fields_by_name['bool_with_default'].has_default_value)
+ self.assertFalse(msg2.fields_by_name['bool_with_default'].default_value)
+
+ self.assertTrue(msg2.fields_by_name['enum_with_default'].has_default_value)
+ self.assertEquals(
+ 1, msg2.fields_by_name['enum_with_default'].default_value)
+
+ msg3 = self.pool.FindMessageTypeByName(
+ 'google.protobuf.python.internal.Factory2Message.NestedFactory2Message')
+ self.assertEquals(nested_msg2, msg3)
+
+ self.assertTrue(msg2.fields_by_name['bytes_with_default'].has_default_value)
+ self.assertEquals(
+ b'a\xfb\x00c',
+ msg2.fields_by_name['bytes_with_default'].default_value)
+
+ self.assertEqual(1, len(msg2.oneofs))
+ self.assertEqual(1, len(msg2.oneofs_by_name))
+ self.assertEqual(2, len(msg2.oneofs[0].fields))
+ for name in ['oneof_int', 'oneof_string']:
+ self.assertEqual(msg2.oneofs[0],
+ msg2.fields_by_name[name].containing_oneof)
+ self.assertIn(msg2.fields_by_name[name], msg2.oneofs[0].fields)
+
+ def testFindMessageTypeByNameFailure(self):
+ with self.assertRaises(KeyError):
+ self.pool.FindMessageTypeByName('Does not exist')
+
+ def testFindEnumTypeByName(self):
+ enum1 = self.pool.FindEnumTypeByName(
+ 'google.protobuf.python.internal.Factory1Enum')
+ self.assertIsInstance(enum1, descriptor.EnumDescriptor)
+ self.assertEquals(0, enum1.values_by_name['FACTORY_1_VALUE_0'].number)
+ self.assertEquals(1, enum1.values_by_name['FACTORY_1_VALUE_1'].number)
+
+ nested_enum1 = self.pool.FindEnumTypeByName(
+ 'google.protobuf.python.internal.Factory1Message.NestedFactory1Enum')
+ self.assertIsInstance(nested_enum1, descriptor.EnumDescriptor)
+ self.assertEquals(
+ 0, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_0'].number)
+ self.assertEquals(
+ 1, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_1'].number)
+
+ enum2 = self.pool.FindEnumTypeByName(
+ 'google.protobuf.python.internal.Factory2Enum')
+ self.assertIsInstance(enum2, descriptor.EnumDescriptor)
+ self.assertEquals(0, enum2.values_by_name['FACTORY_2_VALUE_0'].number)
+ self.assertEquals(1, enum2.values_by_name['FACTORY_2_VALUE_1'].number)
+
+ nested_enum2 = self.pool.FindEnumTypeByName(
+ 'google.protobuf.python.internal.Factory2Message.NestedFactory2Enum')
+ self.assertIsInstance(nested_enum2, descriptor.EnumDescriptor)
+ self.assertEquals(
+ 0, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_0'].number)
+ self.assertEquals(
+ 1, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_1'].number)
+
+ def testFindEnumTypeByNameFailure(self):
+ with self.assertRaises(KeyError):
+ self.pool.FindEnumTypeByName('Does not exist')
+
+ def testUserDefinedDB(self):
+ db = descriptor_database.DescriptorDatabase()
+ self.pool = descriptor_pool.DescriptorPool(db)
+ db.Add(self.factory_test1_fd)
+ db.Add(self.factory_test2_fd)
+ self.testFindMessageTypeByName()
+
+ def testComplexNesting(self):
+ 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(test1_desc)
+ self.pool.Add(test2_desc)
+ TEST1_FILE.CheckFile(self, self.pool)
+ TEST2_FILE.CheckFile(self, self.pool)
+
+
+
+class ProtoFile(object):
+
+ def __init__(self, name, package, messages, dependencies=None):
+ self.name = name
+ self.package = package
+ self.messages = messages
+ self.dependencies = dependencies or []
+
+ def CheckFile(self, test, pool):
+ file_desc = pool.FindFileByName(self.name)
+ test.assertEquals(self.name, file_desc.name)
+ test.assertEquals(self.package, file_desc.package)
+ dependencies_names = [f.name for f in file_desc.dependencies]
+ test.assertEqual(self.dependencies, dependencies_names)
+ for name, msg_type in self.messages.items():
+ msg_type.CheckType(test, None, name, file_desc)
+
+
+class EnumType(object):
+
+ def __init__(self, values):
+ self.values = values
+
+ def CheckType(self, test, msg_desc, name, file_desc):
+ enum_desc = msg_desc.enum_types_by_name[name]
+ test.assertEqual(name, enum_desc.name)
+ expected_enum_full_name = '.'.join([msg_desc.full_name, name])
+ test.assertEqual(expected_enum_full_name, enum_desc.full_name)
+ test.assertEqual(msg_desc, enum_desc.containing_type)
+ test.assertEqual(file_desc, enum_desc.file)
+ for index, (value, number) in enumerate(self.values):
+ value_desc = enum_desc.values_by_name[value]
+ test.assertEqual(value, value_desc.name)
+ test.assertEqual(index, value_desc.index)
+ test.assertEqual(number, value_desc.number)
+ test.assertEqual(enum_desc, value_desc.type)
+ test.assertIn(value, msg_desc.enum_values_by_name)
+
+
+class MessageType(object):
+
+ def __init__(self, type_dict, field_list, is_extendable=False,
+ extensions=None):
+ self.type_dict = type_dict
+ self.field_list = field_list
+ self.is_extendable = is_extendable
+ self.extensions = extensions or []
+
+ def CheckType(self, test, containing_type_desc, name, file_desc):
+ if containing_type_desc is None:
+ desc = file_desc.message_types_by_name[name]
+ expected_full_name = '.'.join([file_desc.package, name])
+ else:
+ desc = containing_type_desc.nested_types_by_name[name]
+ expected_full_name = '.'.join([containing_type_desc.full_name, name])
+
+ test.assertEqual(name, desc.name)
+ test.assertEqual(expected_full_name, desc.full_name)
+ test.assertEqual(containing_type_desc, desc.containing_type)
+ test.assertEqual(desc.file, file_desc)
+ test.assertEqual(self.is_extendable, desc.is_extendable)
+ for name, subtype in self.type_dict.items():
+ subtype.CheckType(test, desc, name, file_desc)
+
+ for index, (name, field) in enumerate(self.field_list):
+ field.CheckField(test, desc, name, index)
+
+ for index, (name, field) in enumerate(self.extensions):
+ field.CheckField(test, desc, name, index)
+
+
+class EnumField(object):
+
+ def __init__(self, number, type_name, default_value):
+ self.number = number
+ self.type_name = type_name
+ self.default_value = default_value
+
+ def CheckField(self, test, msg_desc, name, index):
+ field_desc = msg_desc.fields_by_name[name]
+ enum_desc = msg_desc.enum_types_by_name[self.type_name]
+ test.assertEqual(name, field_desc.name)
+ expected_field_full_name = '.'.join([msg_desc.full_name, name])
+ test.assertEqual(expected_field_full_name, field_desc.full_name)
+ test.assertEqual(index, field_desc.index)
+ test.assertEqual(self.number, field_desc.number)
+ test.assertEqual(descriptor.FieldDescriptor.TYPE_ENUM, field_desc.type)
+ test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_ENUM,
+ field_desc.cpp_type)
+ test.assertTrue(field_desc.has_default_value)
+ test.assertEqual(enum_desc.values_by_name[self.default_value].index,
+ field_desc.default_value)
+ test.assertEqual(msg_desc, field_desc.containing_type)
+ test.assertEqual(enum_desc, field_desc.enum_type)
+
+
+class MessageField(object):
+
+ def __init__(self, number, type_name):
+ self.number = number
+ self.type_name = type_name
+
+ def CheckField(self, test, msg_desc, name, index):
+ field_desc = msg_desc.fields_by_name[name]
+ field_type_desc = msg_desc.nested_types_by_name[self.type_name]
+ test.assertEqual(name, field_desc.name)
+ expected_field_full_name = '.'.join([msg_desc.full_name, name])
+ test.assertEqual(expected_field_full_name, field_desc.full_name)
+ test.assertEqual(index, field_desc.index)
+ test.assertEqual(self.number, field_desc.number)
+ test.assertEqual(descriptor.FieldDescriptor.TYPE_MESSAGE, field_desc.type)
+ test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_MESSAGE,
+ field_desc.cpp_type)
+ test.assertFalse(field_desc.has_default_value)
+ test.assertEqual(msg_desc, field_desc.containing_type)
+ test.assertEqual(field_type_desc, field_desc.message_type)
+
+
+class StringField(object):
+
+ def __init__(self, number, default_value):
+ self.number = number
+ self.default_value = default_value
+
+ def CheckField(self, test, msg_desc, name, index):
+ field_desc = msg_desc.fields_by_name[name]
+ test.assertEqual(name, field_desc.name)
+ expected_field_full_name = '.'.join([msg_desc.full_name, name])
+ test.assertEqual(expected_field_full_name, field_desc.full_name)
+ test.assertEqual(index, field_desc.index)
+ test.assertEqual(self.number, field_desc.number)
+ test.assertEqual(descriptor.FieldDescriptor.TYPE_STRING, field_desc.type)
+ test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_STRING,
+ field_desc.cpp_type)
+ test.assertTrue(field_desc.has_default_value)
+ test.assertEqual(self.default_value, field_desc.default_value)
+
+
+class ExtensionField(object):
+
+ def __init__(self, number, extended_type):
+ self.number = number
+ self.extended_type = extended_type
+
+ def CheckField(self, test, msg_desc, name, index):
+ field_desc = msg_desc.extensions_by_name[name]
+ test.assertEqual(name, field_desc.name)
+ expected_field_full_name = '.'.join([msg_desc.full_name, name])
+ test.assertEqual(expected_field_full_name, field_desc.full_name)
+ test.assertEqual(self.number, field_desc.number)
+ test.assertEqual(index, field_desc.index)
+ test.assertEqual(descriptor.FieldDescriptor.TYPE_MESSAGE, field_desc.type)
+ test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_MESSAGE,
+ field_desc.cpp_type)
+ test.assertFalse(field_desc.has_default_value)
+ test.assertTrue(field_desc.is_extension)
+ test.assertEqual(msg_desc, field_desc.extension_scope)
+ test.assertEqual(msg_desc, field_desc.message_type)
+ test.assertEqual(self.extended_type, field_desc.containing_type.name)
+
+
+class AddDescriptorTest(basetest.TestCase):
+
+ def _TestMessage(self, prefix):
+ pool = descriptor_pool.DescriptorPool()
+ pool.AddDescriptor(unittest_pb2.TestAllTypes.DESCRIPTOR)
+ self.assertEquals(
+ 'protobuf_unittest.TestAllTypes',
+ pool.FindMessageTypeByName(
+ prefix + 'protobuf_unittest.TestAllTypes').full_name)
+
+ # AddDescriptor is not recursive.
+ with self.assertRaises(KeyError):
+ pool.FindMessageTypeByName(
+ prefix + 'protobuf_unittest.TestAllTypes.NestedMessage')
+
+ pool.AddDescriptor(unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR)
+ self.assertEquals(
+ 'protobuf_unittest.TestAllTypes.NestedMessage',
+ pool.FindMessageTypeByName(
+ prefix + 'protobuf_unittest.TestAllTypes.NestedMessage').full_name)
+
+ # Files are implicitly also indexed when messages are added.
+ self.assertEquals(
+ 'google/protobuf/unittest.proto',
+ pool.FindFileByName(
+ 'google/protobuf/unittest.proto').name)
+
+ self.assertEquals(
+ 'google/protobuf/unittest.proto',
+ pool.FindFileContainingSymbol(
+ prefix + 'protobuf_unittest.TestAllTypes.NestedMessage').name)
+
+ def testMessage(self):
+ self._TestMessage('')
+ self._TestMessage('.')
+
+ def _TestEnum(self, prefix):
+ pool = descriptor_pool.DescriptorPool()
+ pool.AddEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR)
+ self.assertEquals(
+ 'protobuf_unittest.ForeignEnum',
+ pool.FindEnumTypeByName(
+ prefix + 'protobuf_unittest.ForeignEnum').full_name)
+
+ # AddEnumDescriptor is not recursive.
+ with self.assertRaises(KeyError):
+ pool.FindEnumTypeByName(
+ prefix + 'protobuf_unittest.ForeignEnum.NestedEnum')
+
+ pool.AddEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR)
+ self.assertEquals(
+ 'protobuf_unittest.TestAllTypes.NestedEnum',
+ pool.FindEnumTypeByName(
+ prefix + 'protobuf_unittest.TestAllTypes.NestedEnum').full_name)
+
+ # Files are implicitly also indexed when enums are added.
+ self.assertEquals(
+ 'google/protobuf/unittest.proto',
+ pool.FindFileByName(
+ 'google/protobuf/unittest.proto').name)
+
+ self.assertEquals(
+ 'google/protobuf/unittest.proto',
+ pool.FindFileContainingSymbol(
+ prefix + 'protobuf_unittest.TestAllTypes.NestedEnum').name)
+
+ def testEnum(self):
+ self._TestEnum('')
+ self._TestEnum('.')
+
+ def testFile(self):
+ pool = descriptor_pool.DescriptorPool()
+ pool.AddFileDescriptor(unittest_pb2.DESCRIPTOR)
+ self.assertEquals(
+ 'google/protobuf/unittest.proto',
+ pool.FindFileByName(
+ 'google/protobuf/unittest.proto').name)
+
+ # AddFileDescriptor is not recursive; messages and enums within files must
+ # be explicitly registered.
+ with self.assertRaises(KeyError):
+ pool.FindFileContainingSymbol(
+ 'protobuf_unittest.TestAllTypes')
+
+
+TEST1_FILE = ProtoFile(
+ 'google/protobuf/internal/descriptor_pool_test1.proto',
+ 'google.protobuf.python.internal',
+ {
+ 'DescriptorPoolTest1': MessageType({
+ 'NestedEnum': EnumType([('ALPHA', 1), ('BETA', 2)]),
+ 'NestedMessage': MessageType({
+ 'NestedEnum': EnumType([('EPSILON', 5), ('ZETA', 6)]),
+ 'DeepNestedMessage': MessageType({
+ 'NestedEnum': EnumType([('ETA', 7), ('THETA', 8)]),
+ }, [
+ ('nested_enum', EnumField(1, 'NestedEnum', 'ETA')),
+ ('nested_field', StringField(2, 'theta')),
+ ]),
+ }, [
+ ('nested_enum', EnumField(1, 'NestedEnum', 'ZETA')),
+ ('nested_field', StringField(2, 'beta')),
+ ('deep_nested_message', MessageField(3, 'DeepNestedMessage')),
+ ])
+ }, [
+ ('nested_enum', EnumField(1, 'NestedEnum', 'BETA')),
+ ('nested_message', MessageField(2, 'NestedMessage')),
+ ], is_extendable=True),
+
+ 'DescriptorPoolTest2': MessageType({
+ 'NestedEnum': EnumType([('GAMMA', 3), ('DELTA', 4)]),
+ 'NestedMessage': MessageType({
+ 'NestedEnum': EnumType([('IOTA', 9), ('KAPPA', 10)]),
+ 'DeepNestedMessage': MessageType({
+ 'NestedEnum': EnumType([('LAMBDA', 11), ('MU', 12)]),
+ }, [
+ ('nested_enum', EnumField(1, 'NestedEnum', 'MU')),
+ ('nested_field', StringField(2, 'lambda')),
+ ]),
+ }, [
+ ('nested_enum', EnumField(1, 'NestedEnum', 'IOTA')),
+ ('nested_field', StringField(2, 'delta')),
+ ('deep_nested_message', MessageField(3, 'DeepNestedMessage')),
+ ])
+ }, [
+ ('nested_enum', EnumField(1, 'NestedEnum', 'GAMMA')),
+ ('nested_message', MessageField(2, 'NestedMessage')),
+ ]),
+ })
+
+
+TEST2_FILE = ProtoFile(
+ 'google/protobuf/internal/descriptor_pool_test2.proto',
+ 'google.protobuf.python.internal',
+ {
+ 'DescriptorPoolTest3': MessageType({
+ 'NestedEnum': EnumType([('NU', 13), ('XI', 14)]),
+ 'NestedMessage': MessageType({
+ 'NestedEnum': EnumType([('OMICRON', 15), ('PI', 16)]),
+ 'DeepNestedMessage': MessageType({
+ 'NestedEnum': EnumType([('RHO', 17), ('SIGMA', 18)]),
+ }, [
+ ('nested_enum', EnumField(1, 'NestedEnum', 'RHO')),
+ ('nested_field', StringField(2, 'sigma')),
+ ]),
+ }, [
+ ('nested_enum', EnumField(1, 'NestedEnum', 'PI')),
+ ('nested_field', StringField(2, 'nu')),
+ ('deep_nested_message', MessageField(3, 'DeepNestedMessage')),
+ ])
+ }, [
+ ('nested_enum', EnumField(1, 'NestedEnum', 'XI')),
+ ('nested_message', MessageField(2, 'NestedMessage')),
+ ], extensions=[
+ ('descriptor_pool_test',
+ ExtensionField(1001, 'DescriptorPoolTest1')),
+ ]),
+ },
+ dependencies=['google/protobuf/internal/descriptor_pool_test1.proto'])
+
+
+if __name__ == '__main__':
+ basetest.main()
diff --git a/python/google/protobuf/internal/descriptor_pool_test1.proto b/python/google/protobuf/internal/descriptor_pool_test1.proto
new file mode 100644
index 0000000..6dfe4ef
--- /dev/null
+++ b/python/google/protobuf/internal/descriptor_pool_test1.proto
@@ -0,0 +1,94 @@
+// 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 google.protobuf.python.internal;
+
+
+message DescriptorPoolTest1 {
+ extensions 1000 to max;
+
+ enum NestedEnum {
+ ALPHA = 1;
+ BETA = 2;
+ }
+
+ optional NestedEnum nested_enum = 1 [default = BETA];
+
+ message NestedMessage {
+ enum NestedEnum {
+ EPSILON = 5;
+ ZETA = 6;
+ }
+ optional NestedEnum nested_enum = 1 [default = ZETA];
+ optional string nested_field = 2 [default = "beta"];
+ optional DeepNestedMessage deep_nested_message = 3;
+
+ message DeepNestedMessage {
+ enum NestedEnum {
+ ETA = 7;
+ THETA = 8;
+ }
+ optional NestedEnum nested_enum = 1 [default = ETA];
+ optional string nested_field = 2 [default = "theta"];
+ }
+ }
+
+ optional NestedMessage nested_message = 2;
+}
+
+message DescriptorPoolTest2 {
+ enum NestedEnum {
+ GAMMA = 3;
+ DELTA = 4;
+ }
+
+ optional NestedEnum nested_enum = 1 [default = GAMMA];
+
+ message NestedMessage {
+ enum NestedEnum {
+ IOTA = 9;
+ KAPPA = 10;
+ }
+ optional NestedEnum nested_enum = 1 [default = IOTA];
+ optional string nested_field = 2 [default = "delta"];
+ optional DeepNestedMessage deep_nested_message = 3;
+
+ message DeepNestedMessage {
+ enum NestedEnum {
+ LAMBDA = 11;
+ MU = 12;
+ }
+ optional NestedEnum nested_enum = 1 [default = MU];
+ optional string nested_field = 2 [default = "lambda"];
+ }
+ }
+
+ optional NestedMessage nested_message = 2;
+}
diff --git a/python/google/protobuf/internal/descriptor_pool_test2.proto b/python/google/protobuf/internal/descriptor_pool_test2.proto
new file mode 100644
index 0000000..fbc8438
--- /dev/null
+++ b/python/google/protobuf/internal/descriptor_pool_test2.proto
@@ -0,0 +1,70 @@
+// 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 google.protobuf.python.internal;
+
+import "google/protobuf/internal/descriptor_pool_test1.proto";
+
+
+message DescriptorPoolTest3 {
+
+ extend DescriptorPoolTest1 {
+ optional DescriptorPoolTest3 descriptor_pool_test = 1001;
+ }
+
+ enum NestedEnum {
+ NU = 13;
+ XI = 14;
+ }
+
+ optional NestedEnum nested_enum = 1 [default = XI];
+
+ message NestedMessage {
+ enum NestedEnum {
+ OMICRON = 15;
+ PI = 16;
+ }
+ optional NestedEnum nested_enum = 1 [default = PI];
+ optional string nested_field = 2 [default = "nu"];
+ optional DeepNestedMessage deep_nested_message = 3;
+
+ message DeepNestedMessage {
+ enum NestedEnum {
+ RHO = 17;
+ SIGMA = 18;
+ }
+ optional NestedEnum nested_enum = 1 [default = RHO];
+ optional string nested_field = 2 [default = "sigma"];
+ }
+ }
+
+ optional NestedMessage nested_message = 2;
+}
+
diff --git a/gtest/scons/SConstruct b/python/google/protobuf/internal/descriptor_python_test.py
index 1f2f37f..5471ae0 100644
--- a/gtest/scons/SConstruct
+++ b/python/google/protobuf/internal/descriptor_python_test.py
@@ -1,5 +1,8 @@
-# -*- Python -*-
-# Copyright 2008 Google Inc. All Rights Reserved.
+#! /usr/bin/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
@@ -26,36 +29,26 @@
# 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: joi@google.com (Joi Sigurdsson)
-# Author: vladl@google.com (Vlad Losev)
-#
-# Base build file for Google Test Tests.
-#
-# Usage:
-# cd to the directory with this file, then
-# ./scons.py [OPTIONS]
-#
-# where frequently used command-line options include:
-# -h print usage help.
-# BUILD=all build all build types.
-# BUILD=win-opt build the given build type.
-EnsurePythonVersion(2, 3)
+"""Unittest for descriptor.py for the pure Python implementation."""
-sconstruct_helper = SConscript('SConstruct.common')
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'
-sconstruct_helper.Initialize(build_root_path='..',
- support_multiple_win_builds=False)
+# We must set the implementation version above before the google3 imports.
+# pylint: disable=g-import-not-at-top
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+# Run all tests from the original module by putting them in our namespace.
+# pylint: disable=wildcard-import
+from google.protobuf.internal.descriptor_test import *
-win_base = sconstruct_helper.MakeWinBaseEnvironment()
-if win_base.get('MSVS_VERSION', None) == '7.1':
- sconstruct_helper.AllowVc71StlWithoutExceptions(win_base)
+class ConfirmPurePythonTest(basetest.TestCase):
-sconstruct_helper.MakeWinDebugEnvironment(win_base, 'win-dbg')
-sconstruct_helper.MakeWinOptimizedEnvironment(win_base, 'win-opt')
+ def testImplementationSetting(self):
+ self.assertEqual('python', api_implementation.Type())
-sconstruct_helper.ConfigureGccEnvironments()
-sconstruct_helper.BuildSelectedEnvironments()
+if __name__ == '__main__':
+ basetest.main()
diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py
index 05c2745..b3777e3 100755
--- a/python/google/protobuf/internal/descriptor_test.py
+++ b/python/google/protobuf/internal/descriptor_test.py
@@ -2,7 +2,7 @@
#
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -34,7 +34,8 @@
__author__ = 'robinson@google.com (Will Robinson)'
-import unittest
+from google.apputils import basetest
+from google.protobuf import unittest_custom_options_pb2
from google.protobuf import unittest_import_pb2
from google.protobuf import unittest_pb2
from google.protobuf import descriptor_pb2
@@ -47,7 +48,7 @@ name: 'TestEmptyMessage'
"""
-class DescriptorTest(unittest.TestCase):
+class DescriptorTest(basetest.TestCase):
def setUp(self):
self.my_file = descriptor.FileDescriptor(
@@ -101,6 +102,15 @@ class DescriptorTest(unittest.TestCase):
self.my_method
])
+ def testEnumValueName(self):
+ self.assertEqual(self.my_message.EnumValueName('ForeignEnum', 4),
+ 'FOREIGN_FOO')
+
+ self.assertEqual(
+ self.my_message.enum_types_by_name[
+ 'ForeignEnum'].values_by_number[4].name,
+ self.my_message.EnumValueName('ForeignEnum', 4))
+
def testEnumFixups(self):
self.assertEqual(self.my_enum, self.my_enum.values[0].type)
@@ -125,6 +135,257 @@ class DescriptorTest(unittest.TestCase):
self.assertEqual(self.my_service.GetOptions(),
descriptor_pb2.ServiceOptions())
+ def testSimpleCustomOptions(self):
+ 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"]
+ enum_value_descriptor =\
+ message_descriptor.enum_values_by_name["ANENUM_VAL2"]
+ service_descriptor =\
+ unittest_custom_options_pb2.TestServiceWithCustomOptions.DESCRIPTOR
+ method_descriptor = service_descriptor.FindMethodByName("Foo")
+
+ file_options = file_descriptor.GetOptions()
+ file_opt1 = unittest_custom_options_pb2.file_opt1
+ self.assertEqual(9876543210, file_options.Extensions[file_opt1])
+ message_options = message_descriptor.GetOptions()
+ message_opt1 = unittest_custom_options_pb2.message_opt1
+ self.assertEqual(-56, message_options.Extensions[message_opt1])
+ field_options = field_descriptor.GetOptions()
+ field_opt1 = unittest_custom_options_pb2.field_opt1
+ self.assertEqual(8765432109, field_options.Extensions[field_opt1])
+ field_opt2 = unittest_custom_options_pb2.field_opt2
+ self.assertEqual(42, field_options.Extensions[field_opt2])
+ enum_options = enum_descriptor.GetOptions()
+ enum_opt1 = unittest_custom_options_pb2.enum_opt1
+ self.assertEqual(-789, enum_options.Extensions[enum_opt1])
+ enum_value_options = enum_value_descriptor.GetOptions()
+ enum_value_opt1 = unittest_custom_options_pb2.enum_value_opt1
+ self.assertEqual(123, enum_value_options.Extensions[enum_value_opt1])
+
+ service_options = service_descriptor.GetOptions()
+ service_opt1 = unittest_custom_options_pb2.service_opt1
+ self.assertEqual(-9876543210, service_options.Extensions[service_opt1])
+ method_options = method_descriptor.GetOptions()
+ method_opt1 = unittest_custom_options_pb2.method_opt1
+ self.assertEqual(unittest_custom_options_pb2.METHODOPT1_VAL2,
+ method_options.Extensions[method_opt1])
+
+ def testDifferentCustomOptionTypes(self):
+ kint32min = -2**31
+ kint64min = -2**63
+ kint32max = 2**31 - 1
+ kint64max = 2**63 - 1
+ kuint32max = 2**32 - 1
+ kuint64max = 2**64 - 1
+
+ message_descriptor =\
+ unittest_custom_options_pb2.CustomOptionMinIntegerValues.DESCRIPTOR
+ message_options = message_descriptor.GetOptions()
+ self.assertEqual(False, message_options.Extensions[
+ unittest_custom_options_pb2.bool_opt])
+ self.assertEqual(kint32min, message_options.Extensions[
+ unittest_custom_options_pb2.int32_opt])
+ self.assertEqual(kint64min, message_options.Extensions[
+ unittest_custom_options_pb2.int64_opt])
+ self.assertEqual(0, message_options.Extensions[
+ unittest_custom_options_pb2.uint32_opt])
+ self.assertEqual(0, message_options.Extensions[
+ unittest_custom_options_pb2.uint64_opt])
+ self.assertEqual(kint32min, message_options.Extensions[
+ unittest_custom_options_pb2.sint32_opt])
+ self.assertEqual(kint64min, message_options.Extensions[
+ unittest_custom_options_pb2.sint64_opt])
+ self.assertEqual(0, message_options.Extensions[
+ unittest_custom_options_pb2.fixed32_opt])
+ self.assertEqual(0, message_options.Extensions[
+ unittest_custom_options_pb2.fixed64_opt])
+ self.assertEqual(kint32min, message_options.Extensions[
+ unittest_custom_options_pb2.sfixed32_opt])
+ self.assertEqual(kint64min, message_options.Extensions[
+ unittest_custom_options_pb2.sfixed64_opt])
+
+ message_descriptor =\
+ unittest_custom_options_pb2.CustomOptionMaxIntegerValues.DESCRIPTOR
+ message_options = message_descriptor.GetOptions()
+ self.assertEqual(True, message_options.Extensions[
+ unittest_custom_options_pb2.bool_opt])
+ self.assertEqual(kint32max, message_options.Extensions[
+ unittest_custom_options_pb2.int32_opt])
+ self.assertEqual(kint64max, message_options.Extensions[
+ unittest_custom_options_pb2.int64_opt])
+ self.assertEqual(kuint32max, message_options.Extensions[
+ unittest_custom_options_pb2.uint32_opt])
+ self.assertEqual(kuint64max, message_options.Extensions[
+ unittest_custom_options_pb2.uint64_opt])
+ self.assertEqual(kint32max, message_options.Extensions[
+ unittest_custom_options_pb2.sint32_opt])
+ self.assertEqual(kint64max, message_options.Extensions[
+ unittest_custom_options_pb2.sint64_opt])
+ self.assertEqual(kuint32max, message_options.Extensions[
+ unittest_custom_options_pb2.fixed32_opt])
+ self.assertEqual(kuint64max, message_options.Extensions[
+ unittest_custom_options_pb2.fixed64_opt])
+ self.assertEqual(kint32max, message_options.Extensions[
+ unittest_custom_options_pb2.sfixed32_opt])
+ self.assertEqual(kint64max, message_options.Extensions[
+ unittest_custom_options_pb2.sfixed64_opt])
+
+ message_descriptor =\
+ unittest_custom_options_pb2.CustomOptionOtherValues.DESCRIPTOR
+ message_options = message_descriptor.GetOptions()
+ self.assertEqual(-100, message_options.Extensions[
+ unittest_custom_options_pb2.int32_opt])
+ self.assertAlmostEqual(12.3456789, message_options.Extensions[
+ unittest_custom_options_pb2.float_opt], 6)
+ self.assertAlmostEqual(1.234567890123456789, message_options.Extensions[
+ unittest_custom_options_pb2.double_opt])
+ self.assertEqual("Hello, \"World\"", message_options.Extensions[
+ unittest_custom_options_pb2.string_opt])
+ self.assertEqual(b"Hello\0World", message_options.Extensions[
+ unittest_custom_options_pb2.bytes_opt])
+ dummy_enum = unittest_custom_options_pb2.DummyMessageContainingEnum
+ self.assertEqual(
+ dummy_enum.TEST_OPTION_ENUM_TYPE2,
+ message_options.Extensions[unittest_custom_options_pb2.enum_opt])
+
+ message_descriptor =\
+ unittest_custom_options_pb2.SettingRealsFromPositiveInts.DESCRIPTOR
+ message_options = message_descriptor.GetOptions()
+ self.assertAlmostEqual(12, message_options.Extensions[
+ unittest_custom_options_pb2.float_opt], 6)
+ self.assertAlmostEqual(154, message_options.Extensions[
+ unittest_custom_options_pb2.double_opt])
+
+ message_descriptor =\
+ unittest_custom_options_pb2.SettingRealsFromNegativeInts.DESCRIPTOR
+ message_options = message_descriptor.GetOptions()
+ self.assertAlmostEqual(-12, message_options.Extensions[
+ unittest_custom_options_pb2.float_opt], 6)
+ self.assertAlmostEqual(-154, message_options.Extensions[
+ unittest_custom_options_pb2.double_opt])
+
+ def testComplexExtensionOptions(self):
+ descriptor =\
+ unittest_custom_options_pb2.VariousComplexOptions.DESCRIPTOR
+ options = descriptor.GetOptions()
+ self.assertEqual(42, options.Extensions[
+ unittest_custom_options_pb2.complex_opt1].foo)
+ self.assertEqual(324, options.Extensions[
+ unittest_custom_options_pb2.complex_opt1].Extensions[
+ unittest_custom_options_pb2.quux])
+ self.assertEqual(876, options.Extensions[
+ unittest_custom_options_pb2.complex_opt1].Extensions[
+ unittest_custom_options_pb2.corge].qux)
+ self.assertEqual(987, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].baz)
+ self.assertEqual(654, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].Extensions[
+ unittest_custom_options_pb2.grault])
+ self.assertEqual(743, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].bar.foo)
+ self.assertEqual(1999, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].bar.Extensions[
+ unittest_custom_options_pb2.quux])
+ self.assertEqual(2008, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].bar.Extensions[
+ unittest_custom_options_pb2.corge].qux)
+ self.assertEqual(741, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].Extensions[
+ unittest_custom_options_pb2.garply].foo)
+ self.assertEqual(1998, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].Extensions[
+ unittest_custom_options_pb2.garply].Extensions[
+ unittest_custom_options_pb2.quux])
+ self.assertEqual(2121, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].Extensions[
+ unittest_custom_options_pb2.garply].Extensions[
+ unittest_custom_options_pb2.corge].qux)
+ self.assertEqual(1971, options.Extensions[
+ unittest_custom_options_pb2.ComplexOptionType2
+ .ComplexOptionType4.complex_opt4].waldo)
+ self.assertEqual(321, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].fred.waldo)
+ self.assertEqual(9, options.Extensions[
+ unittest_custom_options_pb2.complex_opt3].qux)
+ self.assertEqual(22, options.Extensions[
+ unittest_custom_options_pb2.complex_opt3].complexoptiontype5.plugh)
+ self.assertEqual(24, options.Extensions[
+ unittest_custom_options_pb2.complexopt6].xyzzy)
+
+ # Check that aggregate options were parsed and saved correctly in
+ # the appropriate descriptors.
+ def testAggregateOptions(self):
+ file_descriptor = unittest_custom_options_pb2.DESCRIPTOR
+ message_descriptor =\
+ unittest_custom_options_pb2.AggregateMessage.DESCRIPTOR
+ field_descriptor = message_descriptor.fields_by_name["fieldname"]
+ enum_descriptor = unittest_custom_options_pb2.AggregateEnum.DESCRIPTOR
+ enum_value_descriptor = enum_descriptor.values_by_name["VALUE"]
+ service_descriptor =\
+ unittest_custom_options_pb2.AggregateService.DESCRIPTOR
+ method_descriptor = service_descriptor.FindMethodByName("Method")
+
+ # Tests for the different types of data embedded in fileopt
+ file_options = file_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.fileopt]
+ self.assertEqual(100, file_options.i)
+ self.assertEqual("FileAnnotation", file_options.s)
+ self.assertEqual("NestedFileAnnotation", file_options.sub.s)
+ self.assertEqual("FileExtensionAnnotation", file_options.file.Extensions[
+ unittest_custom_options_pb2.fileopt].s)
+ self.assertEqual("EmbeddedMessageSetElement", file_options.mset.Extensions[
+ unittest_custom_options_pb2.AggregateMessageSetElement
+ .message_set_extension].s)
+
+ # Simple tests for all the other types of annotations
+ self.assertEqual(
+ "MessageAnnotation",
+ message_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.msgopt].s)
+ self.assertEqual(
+ "FieldAnnotation",
+ field_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.fieldopt].s)
+ self.assertEqual(
+ "EnumAnnotation",
+ enum_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.enumopt].s)
+ self.assertEqual(
+ "EnumValueAnnotation",
+ enum_value_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.enumvalopt].s)
+ self.assertEqual(
+ "ServiceAnnotation",
+ service_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.serviceopt].s)
+ self.assertEqual(
+ "MethodAnnotation",
+ method_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.methodopt].s)
+
+ def testNestedOptions(self):
+ nested_message =\
+ unittest_custom_options_pb2.NestedOptionType.NestedMessage.DESCRIPTOR
+ self.assertEqual(1001, nested_message.GetOptions().Extensions[
+ unittest_custom_options_pb2.message_opt1])
+ nested_field = nested_message.fields_by_name["nested_field"]
+ self.assertEqual(1002, nested_field.GetOptions().Extensions[
+ unittest_custom_options_pb2.field_opt1])
+ outer_message =\
+ unittest_custom_options_pb2.NestedOptionType.DESCRIPTOR
+ nested_enum = outer_message.enum_types_by_name["NestedEnum"]
+ self.assertEqual(1003, nested_enum.GetOptions().Extensions[
+ unittest_custom_options_pb2.enum_opt1])
+ nested_enum_value = outer_message.enum_values_by_name["NESTED_ENUM_VALUE"]
+ self.assertEqual(1004, nested_enum_value.GetOptions().Extensions[
+ unittest_custom_options_pb2.enum_value_opt1])
+ nested_extension = outer_message.extensions_by_name["nested_extension"]
+ self.assertEqual(1005, nested_extension.GetOptions().Extensions[
+ unittest_custom_options_pb2.field_opt2])
+
def testFileDescriptorReferences(self):
self.assertEqual(self.my_enum.file, self.my_file)
self.assertEqual(self.my_message.file, self.my_file)
@@ -134,7 +395,7 @@ class DescriptorTest(unittest.TestCase):
self.assertEqual(self.my_file.package, 'protobuf_unittest')
-class DescriptorCopyToProtoTest(unittest.TestCase):
+class DescriptorCopyToProtoTest(basetest.TestCase):
"""Tests for CopyTo functions of Descriptor."""
def _AssertProtoEqual(self, actual_proto, expected_class, expected_ascii):
@@ -269,45 +530,49 @@ class DescriptorCopyToProtoTest(unittest.TestCase):
descriptor_pb2.DescriptorProto,
TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII)
- def testCopyToProto_FileDescriptor(self):
- UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII = ("""
- name: 'google/protobuf/unittest_import.proto'
- package: 'protobuf_unittest_import'
- message_type: <
- name: 'ImportMessage'
- field: <
- name: 'd'
- number: 1
- label: 1 # Optional
- type: 5 # TYPE_INT32
- >
- >
- """ +
- """enum_type: <
- name: 'ImportEnum'
- value: <
- name: 'IMPORT_FOO'
- number: 7
- >
- value: <
- name: 'IMPORT_BAR'
- number: 8
- >
- value: <
- name: 'IMPORT_BAZ'
- number: 9
- >
- >
- options: <
- java_package: 'com.google.protobuf.test'
- optimize_for: 1 # SPEED
- >
- """)
-
- self._InternalTestCopyToProto(
- unittest_import_pb2.DESCRIPTOR,
- descriptor_pb2.FileDescriptorProto,
- UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII)
+ # Disable this test so we can make changes to the proto file.
+ # TODO(xiaofeng): Enable this test after cl/55530659 is submitted.
+ #
+ # def testCopyToProto_FileDescriptor(self):
+ # UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII = ("""
+ # name: 'google/protobuf/unittest_import.proto'
+ # package: 'protobuf_unittest_import'
+ # dependency: 'google/protobuf/unittest_import_public.proto'
+ # message_type: <
+ # name: 'ImportMessage'
+ # field: <
+ # name: 'd'
+ # number: 1
+ # label: 1 # Optional
+ # type: 5 # TYPE_INT32
+ # >
+ # >
+ # """ +
+ # """enum_type: <
+ # name: 'ImportEnum'
+ # value: <
+ # name: 'IMPORT_FOO'
+ # number: 7
+ # >
+ # value: <
+ # name: 'IMPORT_BAR'
+ # number: 8
+ # >
+ # value: <
+ # name: 'IMPORT_BAZ'
+ # number: 9
+ # >
+ # >
+ # options: <
+ # java_package: 'com.google.protobuf.test'
+ # optimize_for: 1 # SPEED
+ # >
+ # public_dependency: 0
+ # """)
+ # self._InternalTestCopyToProto(
+ # unittest_import_pb2.DESCRIPTOR,
+ # descriptor_pb2.FileDescriptorProto,
+ # UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII)
def testCopyToProto_ServiceDescriptor(self):
TEST_SERVICE_ASCII = """
@@ -323,12 +588,82 @@ class DescriptorCopyToProtoTest(unittest.TestCase):
output_type: '.protobuf_unittest.BarResponse'
>
"""
-
self._InternalTestCopyToProto(
unittest_pb2.TestService.DESCRIPTOR,
descriptor_pb2.ServiceDescriptorProto,
TEST_SERVICE_ASCII)
+class MakeDescriptorTest(basetest.TestCase):
+
+ def testMakeDescriptorWithNestedFields(self):
+ file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
+ file_descriptor_proto.name = 'Foo2'
+ message_type = file_descriptor_proto.message_type.add()
+ message_type.name = file_descriptor_proto.name
+ nested_type = message_type.nested_type.add()
+ nested_type.name = 'Sub'
+ enum_type = nested_type.enum_type.add()
+ enum_type.name = 'FOO'
+ enum_type_val = enum_type.value.add()
+ enum_type_val.name = 'BAR'
+ enum_type_val.number = 3
+ field = message_type.field.add()
+ field.number = 1
+ field.name = 'uint64_field'
+ field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+ field.type = descriptor.FieldDescriptor.TYPE_UINT64
+ field = message_type.field.add()
+ field.number = 2
+ field.name = 'nested_message_field'
+ field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+ field.type = descriptor.FieldDescriptor.TYPE_MESSAGE
+ field.type_name = 'Sub'
+ enum_field = nested_type.field.add()
+ enum_field.number = 2
+ enum_field.name = 'bar_field'
+ enum_field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+ enum_field.type = descriptor.FieldDescriptor.TYPE_ENUM
+ enum_field.type_name = 'Foo2.Sub.FOO'
+
+ result = descriptor.MakeDescriptor(message_type)
+ self.assertEqual(result.fields[0].cpp_type,
+ descriptor.FieldDescriptor.CPPTYPE_UINT64)
+ self.assertEqual(result.fields[1].cpp_type,
+ descriptor.FieldDescriptor.CPPTYPE_MESSAGE)
+ self.assertEqual(result.fields[1].message_type.containing_type,
+ result)
+ self.assertEqual(result.nested_types[0].fields[0].full_name,
+ 'Foo2.Sub.bar_field')
+ self.assertEqual(result.nested_types[0].fields[0].enum_type,
+ result.nested_types[0].enum_types[0])
+
+ def testMakeDescriptorWithUnsignedIntField(self):
+ file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
+ file_descriptor_proto.name = 'Foo'
+ message_type = file_descriptor_proto.message_type.add()
+ message_type.name = file_descriptor_proto.name
+ enum_type = message_type.enum_type.add()
+ enum_type.name = 'FOO'
+ enum_type_val = enum_type.value.add()
+ enum_type_val.name = 'BAR'
+ enum_type_val.number = 3
+ field = message_type.field.add()
+ field.number = 1
+ field.name = 'uint64_field'
+ field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+ field.type = descriptor.FieldDescriptor.TYPE_UINT64
+ enum_field = message_type.field.add()
+ enum_field.number = 2
+ enum_field.name = 'bar_field'
+ enum_field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+ enum_field.type = descriptor.FieldDescriptor.TYPE_ENUM
+ enum_field.type_name = 'Foo.FOO'
+
+ result = descriptor.MakeDescriptor(message_type)
+ self.assertEqual(result.fields[0].cpp_type,
+ descriptor.FieldDescriptor.CPPTYPE_UINT64)
+
+
if __name__ == '__main__':
- unittest.main()
+ basetest.main()
diff --git a/python/google/protobuf/internal/encoder.py b/python/google/protobuf/internal/encoder.py
index aa05d5b..38a5138 100755
--- a/python/google/protobuf/internal/encoder.py
+++ b/python/google/protobuf/internal/encoder.py
@@ -1,6 +1,6 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -28,6 +28,10 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#PY25 compatible for GAE.
+#
+# Copyright 2009 Google Inc. All Rights Reserved.
+
"""Code for encoding protocol message primitives.
Contains the logic for encoding every logical protocol field type
@@ -67,9 +71,17 @@ sizer rather than when calling them. In particular:
__author__ = 'kenton@google.com (Kenton Varda)'
import struct
+import sys ##PY25
+_PY2 = sys.version_info[0] < 3 ##PY25
from google.protobuf.internal import wire_format
+# This will overflow and thus become IEEE-754 "infinity". We would use
+# "float('inf')" but it doesn't work on Windows pre-Python-2.6.
+_POS_INF = 1e10000
+_NEG_INF = -_POS_INF
+
+
def _VarintSize(value):
"""Compute the size of a varint value."""
if value <= 0x7f: return 1
@@ -334,7 +346,8 @@ def MessageSetItemSizer(field_number):
def _VarintEncoder():
"""Return an encoder for a basic varint value (does not include tag)."""
- local_chr = chr
+ local_chr = _PY2 and chr or (lambda x: bytes((x,))) ##PY25
+##!PY25 local_chr = chr if bytes is str else lambda x: bytes((x,))
def EncodeVarint(write, value):
bits = value & 0x7f
value >>= 7
@@ -351,7 +364,8 @@ def _SignedVarintEncoder():
"""Return an encoder for a basic signed varint value (does not include
tag)."""
- local_chr = chr
+ local_chr = _PY2 and chr or (lambda x: bytes((x,))) ##PY25
+##!PY25 local_chr = chr if bytes is str else lambda x: bytes((x,))
def EncodeSignedVarint(write, value):
if value < 0:
value += (1 << 64)
@@ -376,7 +390,8 @@ def _VarintBytes(value):
pieces = []
_EncodeVarint(pieces.append, value)
- return "".join(pieces)
+ return "".encode("latin1").join(pieces) ##PY25
+##!PY25 return b"".join(pieces)
def TagBytes(field_number, wire_type):
@@ -502,6 +517,90 @@ def _StructPackEncoder(wire_type, format):
return SpecificEncoder
+def _FloatingPointEncoder(wire_type, format):
+ """Return a constructor for an encoder for float fields.
+
+ This is like StructPackEncoder, but catches errors that may be due to
+ passing non-finite floating-point values to struct.pack, and makes a
+ second attempt to encode those values.
+
+ Args:
+ wire_type: The field's wire type, for encoding tags.
+ format: The format string to pass to struct.pack().
+ """
+
+ b = _PY2 and (lambda x:x) or (lambda x:x.encode('latin1')) ##PY25
+ value_size = struct.calcsize(format)
+ if value_size == 4:
+ def EncodeNonFiniteOrRaise(write, value):
+ # Remember that the serialized form uses little-endian byte order.
+ if value == _POS_INF:
+ write(b('\x00\x00\x80\x7F')) ##PY25
+##!PY25 write(b'\x00\x00\x80\x7F')
+ elif value == _NEG_INF:
+ write(b('\x00\x00\x80\xFF')) ##PY25
+##!PY25 write(b'\x00\x00\x80\xFF')
+ elif value != value: # NaN
+ write(b('\x00\x00\xC0\x7F')) ##PY25
+##!PY25 write(b'\x00\x00\xC0\x7F')
+ else:
+ raise
+ elif value_size == 8:
+ def EncodeNonFiniteOrRaise(write, value):
+ if value == _POS_INF:
+ write(b('\x00\x00\x00\x00\x00\x00\xF0\x7F')) ##PY25
+##!PY25 write(b'\x00\x00\x00\x00\x00\x00\xF0\x7F')
+ elif value == _NEG_INF:
+ write(b('\x00\x00\x00\x00\x00\x00\xF0\xFF')) ##PY25
+##!PY25 write(b'\x00\x00\x00\x00\x00\x00\xF0\xFF')
+ elif value != value: # NaN
+ write(b('\x00\x00\x00\x00\x00\x00\xF8\x7F')) ##PY25
+##!PY25 write(b'\x00\x00\x00\x00\x00\x00\xF8\x7F')
+ else:
+ raise
+ else:
+ raise ValueError('Can\'t encode floating-point values that are '
+ '%d bytes long (only 4 or 8)' % value_size)
+
+ def SpecificEncoder(field_number, is_repeated, is_packed):
+ local_struct_pack = struct.pack
+ if is_packed:
+ tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ local_EncodeVarint = _EncodeVarint
+ def EncodePackedField(write, value):
+ write(tag_bytes)
+ local_EncodeVarint(write, len(value) * value_size)
+ for element in value:
+ # This try/except block is going to be faster than any code that
+ # we could write to check whether element is finite.
+ try:
+ write(local_struct_pack(format, element))
+ except SystemError:
+ EncodeNonFiniteOrRaise(write, element)
+ return EncodePackedField
+ elif is_repeated:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ write(tag_bytes)
+ try:
+ write(local_struct_pack(format, element))
+ except SystemError:
+ EncodeNonFiniteOrRaise(write, element)
+ return EncodeRepeatedField
+ else:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeField(write, value):
+ write(tag_bytes)
+ try:
+ write(local_struct_pack(format, value))
+ except SystemError:
+ EncodeNonFiniteOrRaise(write, value)
+ return EncodeField
+
+ return SpecificEncoder
+
+
# ====================================================================
# Here we declare an encoder constructor for each field type. These work
# very similarly to sizer constructors, described earlier.
@@ -525,15 +624,17 @@ Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<I')
Fixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<Q')
SFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<i')
SFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<q')
-FloatEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<f')
-DoubleEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<d')
+FloatEncoder = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED32, '<f')
+DoubleEncoder = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED64, '<d')
def BoolEncoder(field_number, is_repeated, is_packed):
"""Returns an encoder for a boolean field."""
- false_byte = chr(0)
- true_byte = chr(1)
+##!PY25 false_byte = b'\x00'
+##!PY25 true_byte = b'\x01'
+ false_byte = '\x00'.encode('latin1') ##PY25
+ true_byte = '\x01'.encode('latin1') ##PY25
if is_packed:
tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
local_EncodeVarint = _EncodeVarint
@@ -669,7 +770,8 @@ def MessageSetItemEncoder(field_number):
}
}
"""
- start_bytes = "".join([
+ start_bytes = "".encode("latin1").join([ ##PY25
+##!PY25 start_bytes = b"".join([
TagBytes(1, wire_format.WIRETYPE_START_GROUP),
TagBytes(2, wire_format.WIRETYPE_VARINT),
_VarintBytes(field_number),
diff --git a/python/google/protobuf/internal/enum_type_wrapper.py b/python/google/protobuf/internal/enum_type_wrapper.py
new file mode 100644
index 0000000..1cffe35
--- /dev/null
+++ b/python/google/protobuf/internal/enum_type_wrapper.py
@@ -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.
+
+"""A simple wrapper around enum types to expose utility functions.
+
+Instances are created as properties with the same name as the enum they wrap
+on proto classes. For usage, see:
+ reflection_test.py
+"""
+
+__author__ = 'rabsatt@google.com (Kevin Rabsatt)'
+
+
+class EnumTypeWrapper(object):
+ """A utility for finding the names of enum values."""
+
+ DESCRIPTOR = None
+
+ def __init__(self, enum_type):
+ """Inits EnumTypeWrapper with an EnumDescriptor."""
+ self._enum_type = enum_type
+ self.DESCRIPTOR = enum_type;
+
+ def Name(self, number):
+ """Returns a string containing the name of an enum value."""
+ if number in self._enum_type.values_by_number:
+ return self._enum_type.values_by_number[number].name
+ raise ValueError('Enum %s has no name defined for value %d' % (
+ self._enum_type.name, number))
+
+ def Value(self, name):
+ """Returns the value coresponding to the given enum name."""
+ if name in self._enum_type.values_by_name:
+ return self._enum_type.values_by_name[name].number
+ raise ValueError('Enum %s has no value defined for name %s' % (
+ self._enum_type.name, name))
+
+ def keys(self):
+ """Return a list of the string names in the enum.
+
+ These are returned in the order they were defined in the .proto file.
+ """
+
+ return [value_descriptor.name
+ for value_descriptor in self._enum_type.values]
+
+ def values(self):
+ """Return a list of the integer values in the enum.
+
+ These are returned in the order they were defined in the .proto file.
+ """
+
+ return [value_descriptor.number
+ for value_descriptor in self._enum_type.values]
+
+ def items(self):
+ """Return a list of the (name, value) pairs of the enum.
+
+ These are returned in the order they were defined in the .proto file.
+ """
+ return [(value_descriptor.name, value_descriptor.number)
+ for value_descriptor in self._enum_type.values]
diff --git a/python/google/protobuf/internal/factory_test1.proto b/python/google/protobuf/internal/factory_test1.proto
new file mode 100644
index 0000000..9f5a391
--- /dev/null
+++ b/python/google/protobuf/internal/factory_test1.proto
@@ -0,0 +1,57 @@
+// 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: matthewtoia@google.com (Matt Toia)
+
+
+package google.protobuf.python.internal;
+
+
+enum Factory1Enum {
+ FACTORY_1_VALUE_0 = 0;
+ FACTORY_1_VALUE_1 = 1;
+}
+
+message Factory1Message {
+ optional Factory1Enum factory_1_enum = 1;
+ enum NestedFactory1Enum {
+ NESTED_FACTORY_1_VALUE_0 = 0;
+ NESTED_FACTORY_1_VALUE_1 = 1;
+ }
+ optional NestedFactory1Enum nested_factory_1_enum = 2;
+ message NestedFactory1Message {
+ optional string value = 1;
+ }
+ optional NestedFactory1Message nested_factory_1_message = 3;
+ optional int32 scalar_value = 4;
+ repeated string list_value = 5;
+
+ extensions 1000 to max;
+}
diff --git a/python/google/protobuf/internal/factory_test2.proto b/python/google/protobuf/internal/factory_test2.proto
new file mode 100644
index 0000000..27feb6c
--- /dev/null
+++ b/python/google/protobuf/internal/factory_test2.proto
@@ -0,0 +1,92 @@
+// 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: matthewtoia@google.com (Matt Toia)
+
+
+package google.protobuf.python.internal;
+
+import "google/protobuf/internal/factory_test1.proto";
+
+
+enum Factory2Enum {
+ FACTORY_2_VALUE_0 = 0;
+ FACTORY_2_VALUE_1 = 1;
+}
+
+message Factory2Message {
+ required int32 mandatory = 1;
+ optional Factory2Enum factory_2_enum = 2;
+ enum NestedFactory2Enum {
+ NESTED_FACTORY_2_VALUE_0 = 0;
+ NESTED_FACTORY_2_VALUE_1 = 1;
+ }
+ optional NestedFactory2Enum nested_factory_2_enum = 3;
+ message NestedFactory2Message {
+ optional string value = 1;
+ }
+ optional NestedFactory2Message nested_factory_2_message = 4;
+ optional Factory1Message factory_1_message = 5;
+ optional Factory1Enum factory_1_enum = 6;
+ optional Factory1Message.NestedFactory1Enum nested_factory_1_enum = 7;
+ optional Factory1Message.NestedFactory1Message nested_factory_1_message = 8;
+ optional Factory2Message circular_message = 9;
+ optional string scalar_value = 10;
+ repeated string list_value = 11;
+ repeated group Grouped = 12 {
+ optional string part_1 = 13;
+ optional string part_2 = 14;
+ }
+ optional LoopMessage loop = 15;
+ optional int32 int_with_default = 16 [default = 1776];
+ optional double double_with_default = 17 [default = 9.99];
+ optional string string_with_default = 18 [default = "hello world"];
+ optional bool bool_with_default = 19 [default = false];
+ optional Factory2Enum enum_with_default = 20 [default = FACTORY_2_VALUE_1];
+ optional bytes bytes_with_default = 21 [default = "a\373\000c"];
+
+
+ extend Factory1Message {
+ optional string one_more_field = 1001;
+ }
+
+ oneof oneof_field {
+ int32 oneof_int = 22;
+ string oneof_string = 23;
+ }
+}
+
+message LoopMessage {
+ optional Factory2Message loop = 1;
+}
+
+extend Factory1Message {
+ optional string another_field = 1002;
+}
diff --git a/python/google/protobuf/internal/generator_test.py b/python/google/protobuf/internal/generator_test.py
index 78360b5..422fa9a 100755
--- a/python/google/protobuf/internal/generator_test.py
+++ b/python/google/protobuf/internal/generator_test.py
@@ -2,7 +2,7 @@
#
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -41,17 +41,21 @@ further ensures that we can use Python protocol message objects as we expect.
__author__ = 'robinson@google.com (Will Robinson)'
-import unittest
+from google.apputils import basetest
+from google.protobuf.internal import test_bad_identifiers_pb2
+from google.protobuf import unittest_custom_options_pb2
from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_import_public_pb2
from google.protobuf import unittest_mset_pb2
-from google.protobuf import unittest_pb2
from google.protobuf import unittest_no_generic_services_pb2
-
+from google.protobuf import unittest_pb2
+from google.protobuf import service
+from google.protobuf import symbol_database
MAX_EXTENSION = 536870912
-class GeneratorTest(unittest.TestCase):
+class GeneratorTest(basetest.TestCase):
def testNestedMessageDescriptor(self):
field_name = 'optional_nested_message'
@@ -99,6 +103,7 @@ class GeneratorTest(unittest.TestCase):
self.assertTrue(isinf(message.neg_inf_float))
self.assertTrue(message.neg_inf_float < 0)
self.assertTrue(isnan(message.nan_float))
+ self.assertEqual("? ? ?? ?? ??? ??/ ??-", message.cpp_trigraph)
def testHasDefaultValues(self):
desc = unittest_pb2.TestAllTypes.DESCRIPTOR
@@ -140,6 +145,13 @@ class GeneratorTest(unittest.TestCase):
proto = unittest_mset_pb2.TestMessageSet()
self.assertTrue(proto.DESCRIPTOR.GetOptions().message_set_wire_format)
+ def testMessageWithCustomOptions(self):
+ proto = unittest_custom_options_pb2.TestMessageWithCustomOptions()
+ enum_options = proto.DESCRIPTOR.enum_types_by_name['AnEnum'].GetOptions()
+ self.assertTrue(enum_options is not None)
+ # TODO(gps): We really should test for the presense of the enum_opt1
+ # extension and for its value to be set to -789.
+
def testNestedTypes(self):
self.assertEquals(
set(unittest_pb2.TestAllTypes.DESCRIPTOR.nested_types),
@@ -206,15 +218,126 @@ class GeneratorTest(unittest.TestCase):
'google/protobuf/unittest.proto')
self.assertEqual(unittest_pb2.DESCRIPTOR.package, 'protobuf_unittest')
self.assertFalse(unittest_pb2.DESCRIPTOR.serialized_pb is None)
+ self.assertEqual(unittest_pb2.DESCRIPTOR.dependencies,
+ [unittest_import_pb2.DESCRIPTOR])
+ self.assertEqual(unittest_import_pb2.DESCRIPTOR.dependencies,
+ [unittest_import_public_pb2.DESCRIPTOR])
def testNoGenericServices(self):
- # unittest_no_generic_services.proto should contain defs for everything
- # except services.
self.assertTrue(hasattr(unittest_no_generic_services_pb2, "TestMessage"))
self.assertTrue(hasattr(unittest_no_generic_services_pb2, "FOO"))
self.assertTrue(hasattr(unittest_no_generic_services_pb2, "test_extension"))
- self.assertFalse(hasattr(unittest_no_generic_services_pb2, "TestService"))
+ # Make sure unittest_no_generic_services_pb2 has no services subclassing
+ # Proto2 Service class.
+ if hasattr(unittest_no_generic_services_pb2, "TestService"):
+ self.assertFalse(issubclass(unittest_no_generic_services_pb2.TestService,
+ service.Service))
+
+ def testMessageTypesByName(self):
+ file_type = unittest_pb2.DESCRIPTOR
+ self.assertEqual(
+ unittest_pb2._TESTALLTYPES,
+ file_type.message_types_by_name[unittest_pb2._TESTALLTYPES.name])
+
+ # Nested messages shouldn't be included in the message_types_by_name
+ # dictionary (like in the C++ API).
+ self.assertFalse(
+ unittest_pb2._TESTALLTYPES_NESTEDMESSAGE.name in
+ file_type.message_types_by_name)
+
+ def testEnumTypesByName(self):
+ file_type = unittest_pb2.DESCRIPTOR
+ self.assertEqual(
+ unittest_pb2._FOREIGNENUM,
+ file_type.enum_types_by_name[unittest_pb2._FOREIGNENUM.name])
+
+ def testExtensionsByName(self):
+ file_type = unittest_pb2.DESCRIPTOR
+ self.assertEqual(
+ unittest_pb2.my_extension_string,
+ file_type.extensions_by_name[unittest_pb2.my_extension_string.name])
+
+ def testPublicImports(self):
+ # Test public imports as embedded message.
+ all_type_proto = unittest_pb2.TestAllTypes()
+ self.assertEqual(0, all_type_proto.optional_public_import_message.e)
+
+ # PublicImportMessage is actually defined in unittest_import_public_pb2
+ # module, and is public imported by unittest_import_pb2 module.
+ public_import_proto = unittest_import_pb2.PublicImportMessage()
+ self.assertEqual(0, public_import_proto.e)
+ self.assertTrue(unittest_import_public_pb2.PublicImportMessage is
+ unittest_import_pb2.PublicImportMessage)
+
+ def testBadIdentifiers(self):
+ # We're just testing that the code was imported without problems.
+ message = test_bad_identifiers_pb2.TestBadIdentifiers()
+ self.assertEqual(message.Extensions[test_bad_identifiers_pb2.message],
+ "foo")
+ self.assertEqual(message.Extensions[test_bad_identifiers_pb2.descriptor],
+ "bar")
+ self.assertEqual(message.Extensions[test_bad_identifiers_pb2.reflection],
+ "baz")
+ self.assertEqual(message.Extensions[test_bad_identifiers_pb2.service],
+ "qux")
+
+ def testOneof(self):
+ desc = unittest_pb2.TestAllTypes.DESCRIPTOR
+ self.assertEqual(1, len(desc.oneofs))
+ self.assertEqual('oneof_field', desc.oneofs[0].name)
+ self.assertEqual(0, desc.oneofs[0].index)
+ self.assertIs(desc, desc.oneofs[0].containing_type)
+ self.assertIs(desc.oneofs[0], desc.oneofs_by_name['oneof_field'])
+ nested_names = set(['oneof_uint32', 'oneof_nested_message',
+ 'oneof_string', 'oneof_bytes'])
+ self.assertSameElements(
+ nested_names,
+ [field.name for field in desc.oneofs[0].fields])
+ for field_name, field_desc in desc.fields_by_name.iteritems():
+ if field_name in nested_names:
+ self.assertIs(desc.oneofs[0], field_desc.containing_oneof)
+ else:
+ self.assertIsNone(field_desc.containing_oneof)
+
+
+class SymbolDatabaseRegistrationTest(basetest.TestCase):
+ """Checks that messages, enums and files are correctly registered."""
+
+ def testGetSymbol(self):
+ self.assertEquals(
+ unittest_pb2.TestAllTypes, symbol_database.Default().GetSymbol(
+ 'protobuf_unittest.TestAllTypes'))
+ self.assertEquals(
+ unittest_pb2.TestAllTypes.NestedMessage,
+ symbol_database.Default().GetSymbol(
+ 'protobuf_unittest.TestAllTypes.NestedMessage'))
+ with self.assertRaises(KeyError):
+ symbol_database.Default().GetSymbol('protobuf_unittest.NestedMessage')
+ self.assertEquals(
+ unittest_pb2.TestAllTypes.OptionalGroup,
+ symbol_database.Default().GetSymbol(
+ 'protobuf_unittest.TestAllTypes.OptionalGroup'))
+ self.assertEquals(
+ unittest_pb2.TestAllTypes.RepeatedGroup,
+ symbol_database.Default().GetSymbol(
+ 'protobuf_unittest.TestAllTypes.RepeatedGroup'))
+
+ def testEnums(self):
+ self.assertEquals(
+ 'protobuf_unittest.ForeignEnum',
+ symbol_database.Default().pool.FindEnumTypeByName(
+ 'protobuf_unittest.ForeignEnum').full_name)
+ self.assertEquals(
+ 'protobuf_unittest.TestAllTypes.NestedEnum',
+ symbol_database.Default().pool.FindEnumTypeByName(
+ 'protobuf_unittest.TestAllTypes.NestedEnum').full_name)
+
+ def testFindFileByName(self):
+ self.assertEquals(
+ 'google/protobuf/unittest.proto',
+ symbol_database.Default().pool.FindFileByName(
+ 'google/protobuf/unittest.proto').name)
if __name__ == '__main__':
- unittest.main()
+ basetest.main()
diff --git a/python/google/protobuf/internal/message_factory_python_test.py b/python/google/protobuf/internal/message_factory_python_test.py
new file mode 100644
index 0000000..85e02b2
--- /dev/null
+++ b/python/google/protobuf/internal/message_factory_python_test.py
@@ -0,0 +1,54 @@
+#! /usr/bin/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.
+
+"""Tests for ..public.message_factory for the pure Python implementation."""
+
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'
+
+# We must set the implementation version above before the google3 imports.
+# pylint: disable=g-import-not-at-top
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+# Run all tests from the original module by putting them in our namespace.
+# pylint: disable=wildcard-import
+from google.protobuf.internal.message_factory_test import *
+
+
+class ConfirmPurePythonTest(basetest.TestCase):
+
+ def testImplementationSetting(self):
+ self.assertEqual('python', api_implementation.Type())
+
+
+if __name__ == '__main__':
+ basetest.main()
diff --git a/python/google/protobuf/internal/message_factory_test.py b/python/google/protobuf/internal/message_factory_test.py
new file mode 100644
index 0000000..fcf1341
--- /dev/null
+++ b/python/google/protobuf/internal/message_factory_test.py
@@ -0,0 +1,131 @@
+#! /usr/bin/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.
+
+"""Tests for google.protobuf.message_factory."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+from google.apputils import basetest
+from google.protobuf import descriptor_pb2
+from google.protobuf.internal import factory_test1_pb2
+from google.protobuf.internal import factory_test2_pb2
+from google.protobuf import descriptor_database
+from google.protobuf import descriptor_pool
+from google.protobuf import message_factory
+
+
+class MessageFactoryTest(basetest.TestCase):
+
+ def setUp(self):
+ self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString(
+ factory_test1_pb2.DESCRIPTOR.serialized_pb)
+ self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString(
+ factory_test2_pb2.DESCRIPTOR.serialized_pb)
+
+ def _ExerciseDynamicClass(self, cls):
+ msg = cls()
+ msg.mandatory = 42
+ msg.nested_factory_2_enum = 0
+ msg.nested_factory_2_message.value = 'nested message value'
+ msg.factory_1_message.factory_1_enum = 1
+ msg.factory_1_message.nested_factory_1_enum = 0
+ msg.factory_1_message.nested_factory_1_message.value = (
+ 'nested message value')
+ msg.factory_1_message.scalar_value = 22
+ msg.factory_1_message.list_value.extend([u'one', u'two', u'three'])
+ msg.factory_1_message.list_value.append(u'four')
+ msg.factory_1_enum = 1
+ msg.nested_factory_1_enum = 0
+ msg.nested_factory_1_message.value = 'nested message value'
+ msg.circular_message.mandatory = 1
+ msg.circular_message.circular_message.mandatory = 2
+ msg.circular_message.scalar_value = 'one deep'
+ msg.scalar_value = 'zero deep'
+ msg.list_value.extend([u'four', u'three', u'two'])
+ msg.list_value.append(u'one')
+ msg.grouped.add()
+ msg.grouped[0].part_1 = 'hello'
+ msg.grouped[0].part_2 = 'world'
+ msg.grouped.add(part_1='testing', part_2='123')
+ msg.loop.loop.mandatory = 2
+ msg.loop.loop.loop.loop.mandatory = 4
+ serialized = msg.SerializeToString()
+ converted = factory_test2_pb2.Factory2Message.FromString(serialized)
+ reserialized = converted.SerializeToString()
+ self.assertEquals(serialized, reserialized)
+ result = cls.FromString(reserialized)
+ self.assertEquals(msg, result)
+
+ def testGetPrototype(self):
+ db = descriptor_database.DescriptorDatabase()
+ pool = descriptor_pool.DescriptorPool(db)
+ db.Add(self.factory_test1_fd)
+ db.Add(self.factory_test2_fd)
+ factory = message_factory.MessageFactory()
+ cls = factory.GetPrototype(pool.FindMessageTypeByName(
+ 'google.protobuf.python.internal.Factory2Message'))
+ self.assertIsNot(cls, factory_test2_pb2.Factory2Message)
+ self._ExerciseDynamicClass(cls)
+ cls2 = factory.GetPrototype(pool.FindMessageTypeByName(
+ 'google.protobuf.python.internal.Factory2Message'))
+ self.assertIs(cls, cls2)
+
+ 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])
+ self.assertContainsSubset(
+ ['google.protobuf.python.internal.Factory2Message',
+ 'google.protobuf.python.internal.Factory1Message'],
+ messages.keys())
+ self._ExerciseDynamicClass(
+ messages['google.protobuf.python.internal.Factory2Message'])
+ self.assertContainsSubset(
+ ['google.protobuf.python.internal.Factory2Message.one_more_field',
+ 'google.protobuf.python.internal.another_field'],
+ (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']()
+ ext1 = factory_msg1._extensions_by_name[
+ 'google.protobuf.python.internal.Factory2Message.one_more_field']
+ ext2 = factory_msg1._extensions_by_name[
+ 'google.protobuf.python.internal.another_field']
+ msg1.Extensions[ext1] = 'test1'
+ msg1.Extensions[ext2] = 'test2'
+ self.assertEquals('test1', msg1.Extensions[ext1])
+ self.assertEquals('test2', msg1.Extensions[ext2])
+
+
+if __name__ == '__main__':
+ basetest.main()
diff --git a/python/google/protobuf/internal/message_listener.py b/python/google/protobuf/internal/message_listener.py
index 1080234..0fc255a 100755
--- a/python/google/protobuf/internal/message_listener.py
+++ b/python/google/protobuf/internal/message_listener.py
@@ -1,6 +1,6 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
diff --git a/python/google/protobuf/internal/message_python_test.py b/python/google/protobuf/internal/message_python_test.py
new file mode 100644
index 0000000..c40623a
--- /dev/null
+++ b/python/google/protobuf/internal/message_python_test.py
@@ -0,0 +1,54 @@
+#! /usr/bin/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.
+
+"""Tests for ..public.message for the pure Python implementation."""
+
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'
+
+# We must set the implementation version above before the google3 imports.
+# pylint: disable=g-import-not-at-top
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+# Run all tests from the original module by putting them in our namespace.
+# pylint: disable=wildcard-import
+from google.protobuf.internal.message_test import *
+
+
+class ConfirmPurePythonTest(basetest.TestCase):
+
+ def testImplementationSetting(self):
+ self.assertEqual('python', api_implementation.Type())
+
+
+if __name__ == '__main__':
+ basetest.main()
diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py
index 73a9a3a..48b7ffd 100755
--- a/python/google/protobuf/internal/message_test.py
+++ b/python/google/protobuf/internal/message_test.py
@@ -2,7 +2,7 @@
#
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -43,47 +43,639 @@ abstract interface.
__author__ = 'gps@google.com (Gregory P. Smith)'
-import unittest
-from google.protobuf import unittest_import_pb2
+import copy
+import math
+import operator
+import pickle
+import sys
+
+from google.apputils import basetest
from google.protobuf import unittest_pb2
+from google.protobuf.internal import api_implementation
from google.protobuf.internal import test_util
+from google.protobuf import message
+
+# Python pre-2.6 does not have isinf() or isnan() functions, so we have
+# to provide our own.
+def isnan(val):
+ # NaN is never equal to itself.
+ return val != val
+def isinf(val):
+ # Infinity times zero equals NaN.
+ return not isnan(val) and isnan(val * 0)
+def IsPosInf(val):
+ return isinf(val) and (val > 0)
+def IsNegInf(val):
+ return isinf(val) and (val < 0)
-class MessageTest(unittest.TestCase):
+class MessageTest(basetest.TestCase):
+
+ def testBadUtf8String(self):
+ if api_implementation.Type() != 'python':
+ self.skipTest("Skipping testBadUtf8String, currently only the python "
+ "api implementation raises UnicodeDecodeError when a "
+ "string field contains bad utf-8.")
+ bad_utf8_data = test_util.GoldenFileData('bad_utf8_string')
+ with self.assertRaises(UnicodeDecodeError) as context:
+ unittest_pb2.TestAllTypes.FromString(bad_utf8_data)
+ self.assertIn('field: protobuf_unittest.TestAllTypes.optional_string',
+ str(context.exception))
def testGoldenMessage(self):
- golden_data = test_util.GoldenFile('golden_message').read()
+ golden_data = test_util.GoldenFileData(
+ 'golden_message_oneof_implemented')
golden_message = unittest_pb2.TestAllTypes()
golden_message.ParseFromString(golden_data)
test_util.ExpectAllFieldsSet(self, golden_message)
- self.assertTrue(golden_message.SerializeToString() == golden_data)
+ self.assertEqual(golden_data, golden_message.SerializeToString())
+ golden_copy = copy.deepcopy(golden_message)
+ self.assertEqual(golden_data, golden_copy.SerializeToString())
def testGoldenExtensions(self):
- golden_data = test_util.GoldenFile('golden_message').read()
+ golden_data = test_util.GoldenFileData('golden_message')
golden_message = unittest_pb2.TestAllExtensions()
golden_message.ParseFromString(golden_data)
all_set = unittest_pb2.TestAllExtensions()
test_util.SetAllExtensions(all_set)
self.assertEquals(all_set, golden_message)
- self.assertTrue(golden_message.SerializeToString() == golden_data)
+ self.assertEqual(golden_data, golden_message.SerializeToString())
+ golden_copy = copy.deepcopy(golden_message)
+ self.assertEqual(golden_data, golden_copy.SerializeToString())
def testGoldenPackedMessage(self):
- golden_data = test_util.GoldenFile('golden_packed_fields_message').read()
+ golden_data = test_util.GoldenFileData('golden_packed_fields_message')
golden_message = unittest_pb2.TestPackedTypes()
golden_message.ParseFromString(golden_data)
all_set = unittest_pb2.TestPackedTypes()
test_util.SetAllPackedFields(all_set)
self.assertEquals(all_set, golden_message)
- self.assertTrue(all_set.SerializeToString() == golden_data)
+ self.assertEqual(golden_data, all_set.SerializeToString())
+ golden_copy = copy.deepcopy(golden_message)
+ self.assertEqual(golden_data, golden_copy.SerializeToString())
def testGoldenPackedExtensions(self):
- golden_data = test_util.GoldenFile('golden_packed_fields_message').read()
+ golden_data = test_util.GoldenFileData('golden_packed_fields_message')
golden_message = unittest_pb2.TestPackedExtensions()
golden_message.ParseFromString(golden_data)
all_set = unittest_pb2.TestPackedExtensions()
test_util.SetAllPackedExtensions(all_set)
self.assertEquals(all_set, golden_message)
- self.assertTrue(all_set.SerializeToString() == golden_data)
+ self.assertEqual(golden_data, all_set.SerializeToString())
+ golden_copy = copy.deepcopy(golden_message)
+ self.assertEqual(golden_data, golden_copy.SerializeToString())
+
+ def testPickleSupport(self):
+ golden_data = test_util.GoldenFileData('golden_message')
+ golden_message = unittest_pb2.TestAllTypes()
+ golden_message.ParseFromString(golden_data)
+ pickled_message = pickle.dumps(golden_message)
+
+ unpickled_message = pickle.loads(pickled_message)
+ self.assertEquals(unpickled_message, golden_message)
+
+
+ def testPickleIncompleteProto(self):
+ golden_message = unittest_pb2.TestRequired(a=1)
+ pickled_message = pickle.dumps(golden_message)
+
+ unpickled_message = pickle.loads(pickled_message)
+ self.assertEquals(unpickled_message, golden_message)
+ self.assertEquals(unpickled_message.a, 1)
+ # This is still an incomplete proto - so serializing should fail
+ self.assertRaises(message.EncodeError, unpickled_message.SerializeToString)
+
+ def testPositiveInfinity(self):
+ golden_data = (b'\x5D\x00\x00\x80\x7F'
+ b'\x61\x00\x00\x00\x00\x00\x00\xF0\x7F'
+ b'\xCD\x02\x00\x00\x80\x7F'
+ b'\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\x7F')
+ golden_message = unittest_pb2.TestAllTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(IsPosInf(golden_message.optional_float))
+ self.assertTrue(IsPosInf(golden_message.optional_double))
+ self.assertTrue(IsPosInf(golden_message.repeated_float[0]))
+ self.assertTrue(IsPosInf(golden_message.repeated_double[0]))
+ self.assertEqual(golden_data, golden_message.SerializeToString())
+
+ def testNegativeInfinity(self):
+ golden_data = (b'\x5D\x00\x00\x80\xFF'
+ b'\x61\x00\x00\x00\x00\x00\x00\xF0\xFF'
+ b'\xCD\x02\x00\x00\x80\xFF'
+ b'\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\xFF')
+ golden_message = unittest_pb2.TestAllTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(IsNegInf(golden_message.optional_float))
+ self.assertTrue(IsNegInf(golden_message.optional_double))
+ self.assertTrue(IsNegInf(golden_message.repeated_float[0]))
+ self.assertTrue(IsNegInf(golden_message.repeated_double[0]))
+ self.assertEqual(golden_data, golden_message.SerializeToString())
+
+ def testNotANumber(self):
+ golden_data = (b'\x5D\x00\x00\xC0\x7F'
+ b'\x61\x00\x00\x00\x00\x00\x00\xF8\x7F'
+ b'\xCD\x02\x00\x00\xC0\x7F'
+ b'\xD1\x02\x00\x00\x00\x00\x00\x00\xF8\x7F')
+ golden_message = unittest_pb2.TestAllTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(isnan(golden_message.optional_float))
+ self.assertTrue(isnan(golden_message.optional_double))
+ self.assertTrue(isnan(golden_message.repeated_float[0]))
+ self.assertTrue(isnan(golden_message.repeated_double[0]))
+
+ # The protocol buffer may serialize to any one of multiple different
+ # representations of a NaN. Rather than verify a specific representation,
+ # verify the serialized string can be converted into a correctly
+ # behaving protocol buffer.
+ serialized = golden_message.SerializeToString()
+ message = unittest_pb2.TestAllTypes()
+ message.ParseFromString(serialized)
+ self.assertTrue(isnan(message.optional_float))
+ self.assertTrue(isnan(message.optional_double))
+ self.assertTrue(isnan(message.repeated_float[0]))
+ self.assertTrue(isnan(message.repeated_double[0]))
+
+ def testPositiveInfinityPacked(self):
+ golden_data = (b'\xA2\x06\x04\x00\x00\x80\x7F'
+ b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\x7F')
+ golden_message = unittest_pb2.TestPackedTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(IsPosInf(golden_message.packed_float[0]))
+ self.assertTrue(IsPosInf(golden_message.packed_double[0]))
+ self.assertEqual(golden_data, golden_message.SerializeToString())
+
+ def testNegativeInfinityPacked(self):
+ golden_data = (b'\xA2\x06\x04\x00\x00\x80\xFF'
+ b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\xFF')
+ golden_message = unittest_pb2.TestPackedTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(IsNegInf(golden_message.packed_float[0]))
+ self.assertTrue(IsNegInf(golden_message.packed_double[0]))
+ self.assertEqual(golden_data, golden_message.SerializeToString())
+
+ def testNotANumberPacked(self):
+ golden_data = (b'\xA2\x06\x04\x00\x00\xC0\x7F'
+ b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF8\x7F')
+ golden_message = unittest_pb2.TestPackedTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(isnan(golden_message.packed_float[0]))
+ self.assertTrue(isnan(golden_message.packed_double[0]))
+
+ serialized = golden_message.SerializeToString()
+ message = unittest_pb2.TestPackedTypes()
+ message.ParseFromString(serialized)
+ self.assertTrue(isnan(message.packed_float[0]))
+ self.assertTrue(isnan(message.packed_double[0]))
+
+ def testExtremeFloatValues(self):
+ message = unittest_pb2.TestAllTypes()
+
+ # Most positive exponent, no significand bits set.
+ kMostPosExponentNoSigBits = math.pow(2, 127)
+ message.optional_float = kMostPosExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == kMostPosExponentNoSigBits)
+
+ # Most positive exponent, one significand bit set.
+ kMostPosExponentOneSigBit = 1.5 * math.pow(2, 127)
+ message.optional_float = kMostPosExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == kMostPosExponentOneSigBit)
+
+ # Repeat last two cases with values of same magnitude, but negative.
+ message.optional_float = -kMostPosExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == -kMostPosExponentNoSigBits)
+
+ message.optional_float = -kMostPosExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == -kMostPosExponentOneSigBit)
+
+ # Most negative exponent, no significand bits set.
+ kMostNegExponentNoSigBits = math.pow(2, -127)
+ message.optional_float = kMostNegExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == kMostNegExponentNoSigBits)
+
+ # Most negative exponent, one significand bit set.
+ kMostNegExponentOneSigBit = 1.5 * math.pow(2, -127)
+ message.optional_float = kMostNegExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == kMostNegExponentOneSigBit)
+
+ # Repeat last two cases with values of the same magnitude, but negative.
+ message.optional_float = -kMostNegExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == -kMostNegExponentNoSigBits)
+
+ message.optional_float = -kMostNegExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == -kMostNegExponentOneSigBit)
+
+ def testExtremeDoubleValues(self):
+ message = unittest_pb2.TestAllTypes()
+
+ # Most positive exponent, no significand bits set.
+ kMostPosExponentNoSigBits = math.pow(2, 1023)
+ message.optional_double = kMostPosExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == kMostPosExponentNoSigBits)
+
+ # Most positive exponent, one significand bit set.
+ kMostPosExponentOneSigBit = 1.5 * math.pow(2, 1023)
+ message.optional_double = kMostPosExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == kMostPosExponentOneSigBit)
+
+ # Repeat last two cases with values of same magnitude, but negative.
+ message.optional_double = -kMostPosExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == -kMostPosExponentNoSigBits)
+
+ message.optional_double = -kMostPosExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == -kMostPosExponentOneSigBit)
+
+ # Most negative exponent, no significand bits set.
+ kMostNegExponentNoSigBits = math.pow(2, -1023)
+ message.optional_double = kMostNegExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == kMostNegExponentNoSigBits)
+
+ # Most negative exponent, one significand bit set.
+ kMostNegExponentOneSigBit = 1.5 * math.pow(2, -1023)
+ message.optional_double = kMostNegExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == kMostNegExponentOneSigBit)
+
+ # Repeat last two cases with values of the same magnitude, but negative.
+ message.optional_double = -kMostNegExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == -kMostNegExponentNoSigBits)
+
+ message.optional_double = -kMostNegExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == -kMostNegExponentOneSigBit)
+
+ def testFloatPrinting(self):
+ message = unittest_pb2.TestAllTypes()
+ message.optional_float = 2.0
+ self.assertEqual(str(message), 'optional_float: 2.0\n')
+
+ def testHighPrecisionFloatPrinting(self):
+ message = unittest_pb2.TestAllTypes()
+ message.optional_double = 0.12345678912345678
+ if sys.version_info.major >= 3:
+ self.assertEqual(str(message), 'optional_double: 0.12345678912345678\n')
+ else:
+ self.assertEqual(str(message), 'optional_double: 0.123456789123\n')
+
+ def testUnknownFieldPrinting(self):
+ populated = unittest_pb2.TestAllTypes()
+ test_util.SetAllNonLazyFields(populated)
+ empty = unittest_pb2.TestEmptyMessage()
+ empty.ParseFromString(populated.SerializeToString())
+ self.assertEqual(str(empty), '')
+
+ def testSortingRepeatedScalarFieldsDefaultComparator(self):
+ """Check some different types with the default comparator."""
+ message = unittest_pb2.TestAllTypes()
+
+ # TODO(mattp): would testing more scalar types strengthen test?
+ message.repeated_int32.append(1)
+ message.repeated_int32.append(3)
+ message.repeated_int32.append(2)
+ message.repeated_int32.sort()
+ self.assertEqual(message.repeated_int32[0], 1)
+ self.assertEqual(message.repeated_int32[1], 2)
+ self.assertEqual(message.repeated_int32[2], 3)
+
+ message.repeated_float.append(1.1)
+ message.repeated_float.append(1.3)
+ message.repeated_float.append(1.2)
+ message.repeated_float.sort()
+ self.assertAlmostEqual(message.repeated_float[0], 1.1)
+ self.assertAlmostEqual(message.repeated_float[1], 1.2)
+ self.assertAlmostEqual(message.repeated_float[2], 1.3)
+
+ message.repeated_string.append('a')
+ message.repeated_string.append('c')
+ message.repeated_string.append('b')
+ message.repeated_string.sort()
+ self.assertEqual(message.repeated_string[0], 'a')
+ self.assertEqual(message.repeated_string[1], 'b')
+ self.assertEqual(message.repeated_string[2], 'c')
+
+ message.repeated_bytes.append(b'a')
+ message.repeated_bytes.append(b'c')
+ message.repeated_bytes.append(b'b')
+ message.repeated_bytes.sort()
+ self.assertEqual(message.repeated_bytes[0], b'a')
+ self.assertEqual(message.repeated_bytes[1], b'b')
+ self.assertEqual(message.repeated_bytes[2], b'c')
+
+ def testSortingRepeatedScalarFieldsCustomComparator(self):
+ """Check some different types with custom comparator."""
+ message = unittest_pb2.TestAllTypes()
+
+ message.repeated_int32.append(-3)
+ message.repeated_int32.append(-2)
+ message.repeated_int32.append(-1)
+ message.repeated_int32.sort(key=abs)
+ self.assertEqual(message.repeated_int32[0], -1)
+ self.assertEqual(message.repeated_int32[1], -2)
+ self.assertEqual(message.repeated_int32[2], -3)
+
+ message.repeated_string.append('aaa')
+ message.repeated_string.append('bb')
+ message.repeated_string.append('c')
+ message.repeated_string.sort(key=len)
+ self.assertEqual(message.repeated_string[0], 'c')
+ self.assertEqual(message.repeated_string[1], 'bb')
+ self.assertEqual(message.repeated_string[2], 'aaa')
+
+ def testSortingRepeatedCompositeFieldsCustomComparator(self):
+ """Check passing a custom comparator to sort a repeated composite field."""
+ message = unittest_pb2.TestAllTypes()
+
+ message.repeated_nested_message.add().bb = 1
+ message.repeated_nested_message.add().bb = 3
+ message.repeated_nested_message.add().bb = 2
+ message.repeated_nested_message.add().bb = 6
+ message.repeated_nested_message.add().bb = 5
+ message.repeated_nested_message.add().bb = 4
+ message.repeated_nested_message.sort(key=operator.attrgetter('bb'))
+ self.assertEqual(message.repeated_nested_message[0].bb, 1)
+ self.assertEqual(message.repeated_nested_message[1].bb, 2)
+ self.assertEqual(message.repeated_nested_message[2].bb, 3)
+ self.assertEqual(message.repeated_nested_message[3].bb, 4)
+ self.assertEqual(message.repeated_nested_message[4].bb, 5)
+ self.assertEqual(message.repeated_nested_message[5].bb, 6)
+
+ def testRepeatedCompositeFieldSortArguments(self):
+ """Check sorting a repeated composite field using list.sort() arguments."""
+ message = unittest_pb2.TestAllTypes()
+
+ get_bb = operator.attrgetter('bb')
+ cmp_bb = lambda a, b: cmp(a.bb, b.bb)
+ message.repeated_nested_message.add().bb = 1
+ message.repeated_nested_message.add().bb = 3
+ message.repeated_nested_message.add().bb = 2
+ message.repeated_nested_message.add().bb = 6
+ message.repeated_nested_message.add().bb = 5
+ message.repeated_nested_message.add().bb = 4
+ message.repeated_nested_message.sort(key=get_bb)
+ self.assertEqual([k.bb for k in message.repeated_nested_message],
+ [1, 2, 3, 4, 5, 6])
+ message.repeated_nested_message.sort(key=get_bb, reverse=True)
+ self.assertEqual([k.bb for k in message.repeated_nested_message],
+ [6, 5, 4, 3, 2, 1])
+ if sys.version_info.major >= 3: return # No cmp sorting in PY3.
+ message.repeated_nested_message.sort(sort_function=cmp_bb)
+ self.assertEqual([k.bb for k in message.repeated_nested_message],
+ [1, 2, 3, 4, 5, 6])
+ message.repeated_nested_message.sort(cmp=cmp_bb, reverse=True)
+ self.assertEqual([k.bb for k in message.repeated_nested_message],
+ [6, 5, 4, 3, 2, 1])
+
+ def testRepeatedScalarFieldSortArguments(self):
+ """Check sorting a scalar field using list.sort() arguments."""
+ message = unittest_pb2.TestAllTypes()
+
+ message.repeated_int32.append(-3)
+ message.repeated_int32.append(-2)
+ message.repeated_int32.append(-1)
+ message.repeated_int32.sort(key=abs)
+ self.assertEqual(list(message.repeated_int32), [-1, -2, -3])
+ message.repeated_int32.sort(key=abs, reverse=True)
+ self.assertEqual(list(message.repeated_int32), [-3, -2, -1])
+ if sys.version_info.major < 3: # No cmp sorting in PY3.
+ abs_cmp = lambda a, b: cmp(abs(a), abs(b))
+ message.repeated_int32.sort(sort_function=abs_cmp)
+ self.assertEqual(list(message.repeated_int32), [-1, -2, -3])
+ message.repeated_int32.sort(cmp=abs_cmp, reverse=True)
+ self.assertEqual(list(message.repeated_int32), [-3, -2, -1])
+
+ message.repeated_string.append('aaa')
+ message.repeated_string.append('bb')
+ message.repeated_string.append('c')
+ message.repeated_string.sort(key=len)
+ self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa'])
+ message.repeated_string.sort(key=len, reverse=True)
+ self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c'])
+ if sys.version_info.major < 3: # No cmp sorting in PY3.
+ len_cmp = lambda a, b: cmp(len(a), len(b))
+ message.repeated_string.sort(sort_function=len_cmp)
+ self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa'])
+ message.repeated_string.sort(cmp=len_cmp, reverse=True)
+ self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c'])
+
+ def testRepeatedFieldsComparable(self):
+ m1 = unittest_pb2.TestAllTypes()
+ m2 = unittest_pb2.TestAllTypes()
+ m1.repeated_int32.append(0)
+ m1.repeated_int32.append(1)
+ m1.repeated_int32.append(2)
+ m2.repeated_int32.append(0)
+ m2.repeated_int32.append(1)
+ m2.repeated_int32.append(2)
+ m1.repeated_nested_message.add().bb = 1
+ m1.repeated_nested_message.add().bb = 2
+ m1.repeated_nested_message.add().bb = 3
+ m2.repeated_nested_message.add().bb = 1
+ m2.repeated_nested_message.add().bb = 2
+ m2.repeated_nested_message.add().bb = 3
+
+ if sys.version_info.major >= 3: return # No cmp() in PY3.
+
+ # These comparisons should not raise errors.
+ _ = m1 < m2
+ _ = m1.repeated_nested_message < m2.repeated_nested_message
+
+ # Make sure cmp always works. If it wasn't defined, these would be
+ # id() comparisons and would all fail.
+ self.assertEqual(cmp(m1, m2), 0)
+ self.assertEqual(cmp(m1.repeated_int32, m2.repeated_int32), 0)
+ self.assertEqual(cmp(m1.repeated_int32, [0, 1, 2]), 0)
+ self.assertEqual(cmp(m1.repeated_nested_message,
+ m2.repeated_nested_message), 0)
+ with self.assertRaises(TypeError):
+ # Can't compare repeated composite containers to lists.
+ cmp(m1.repeated_nested_message, m2.repeated_nested_message[:])
+
+ # TODO(anuraag): Implement extensiondict comparison in C++ and then add test
+
+ def testParsingMerge(self):
+ """Check the merge behavior when a required or optional field appears
+ multiple times in the input."""
+ messages = [
+ unittest_pb2.TestAllTypes(),
+ unittest_pb2.TestAllTypes(),
+ unittest_pb2.TestAllTypes() ]
+ messages[0].optional_int32 = 1
+ messages[1].optional_int64 = 2
+ messages[2].optional_int32 = 3
+ messages[2].optional_string = 'hello'
+
+ merged_message = unittest_pb2.TestAllTypes()
+ merged_message.optional_int32 = 3
+ merged_message.optional_int64 = 2
+ merged_message.optional_string = 'hello'
+
+ generator = unittest_pb2.TestParsingMerge.RepeatedFieldsGenerator()
+ generator.field1.extend(messages)
+ generator.field2.extend(messages)
+ generator.field3.extend(messages)
+ generator.ext1.extend(messages)
+ generator.ext2.extend(messages)
+ generator.group1.add().field1.MergeFrom(messages[0])
+ generator.group1.add().field1.MergeFrom(messages[1])
+ generator.group1.add().field1.MergeFrom(messages[2])
+ generator.group2.add().field1.MergeFrom(messages[0])
+ generator.group2.add().field1.MergeFrom(messages[1])
+ generator.group2.add().field1.MergeFrom(messages[2])
+
+ data = generator.SerializeToString()
+ parsing_merge = unittest_pb2.TestParsingMerge()
+ parsing_merge.ParseFromString(data)
+
+ # Required and optional fields should be merged.
+ self.assertEqual(parsing_merge.required_all_types, merged_message)
+ self.assertEqual(parsing_merge.optional_all_types, merged_message)
+ self.assertEqual(parsing_merge.optionalgroup.optional_group_all_types,
+ merged_message)
+ self.assertEqual(parsing_merge.Extensions[
+ unittest_pb2.TestParsingMerge.optional_ext],
+ merged_message)
+
+ # Repeated fields should not be merged.
+ self.assertEqual(len(parsing_merge.repeated_all_types), 3)
+ self.assertEqual(len(parsing_merge.repeatedgroup), 3)
+ self.assertEqual(len(parsing_merge.Extensions[
+ unittest_pb2.TestParsingMerge.repeated_ext]), 3)
+
+ def ensureNestedMessageExists(self, msg, attribute):
+ """Make sure that a nested message object exists.
+
+ As soon as a nested message attribute is accessed, it will be present in the
+ _fields dict, without being marked as actually being set.
+ """
+ getattr(msg, attribute)
+ self.assertFalse(msg.HasField(attribute))
+
+ def testOneofGetCaseNonexistingField(self):
+ m = unittest_pb2.TestAllTypes()
+ self.assertRaises(ValueError, m.WhichOneof, 'no_such_oneof_field')
+
+ def testOneofSemantics(self):
+ m = unittest_pb2.TestAllTypes()
+ self.assertIs(None, m.WhichOneof('oneof_field'))
+
+ m.oneof_uint32 = 11
+ self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
+ self.assertTrue(m.HasField('oneof_uint32'))
+
+ m.oneof_string = u'foo'
+ self.assertEqual('oneof_string', m.WhichOneof('oneof_field'))
+ self.assertFalse(m.HasField('oneof_uint32'))
+ self.assertTrue(m.HasField('oneof_string'))
+
+ m.oneof_nested_message.bb = 11
+ self.assertEqual('oneof_nested_message', m.WhichOneof('oneof_field'))
+ self.assertFalse(m.HasField('oneof_string'))
+ self.assertTrue(m.HasField('oneof_nested_message'))
+
+ m.oneof_bytes = b'bb'
+ self.assertEqual('oneof_bytes', m.WhichOneof('oneof_field'))
+ self.assertFalse(m.HasField('oneof_nested_message'))
+ self.assertTrue(m.HasField('oneof_bytes'))
+
+ def testOneofCompositeFieldReadAccess(self):
+ m = unittest_pb2.TestAllTypes()
+ m.oneof_uint32 = 11
+
+ self.ensureNestedMessageExists(m, 'oneof_nested_message')
+ self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
+ self.assertEqual(11, m.oneof_uint32)
+
+ def testOneofHasField(self):
+ m = unittest_pb2.TestAllTypes()
+ self.assertFalse(m.HasField('oneof_field'))
+ m.oneof_uint32 = 11
+ self.assertTrue(m.HasField('oneof_field'))
+ m.oneof_bytes = b'bb'
+ self.assertTrue(m.HasField('oneof_field'))
+ m.ClearField('oneof_bytes')
+ self.assertFalse(m.HasField('oneof_field'))
+
+ def testOneofClearField(self):
+ m = unittest_pb2.TestAllTypes()
+ m.oneof_uint32 = 11
+ m.ClearField('oneof_field')
+ self.assertFalse(m.HasField('oneof_field'))
+ self.assertFalse(m.HasField('oneof_uint32'))
+ self.assertIs(None, m.WhichOneof('oneof_field'))
+
+ def testOneofClearSetField(self):
+ m = unittest_pb2.TestAllTypes()
+ m.oneof_uint32 = 11
+ m.ClearField('oneof_uint32')
+ self.assertFalse(m.HasField('oneof_field'))
+ self.assertFalse(m.HasField('oneof_uint32'))
+ self.assertIs(None, m.WhichOneof('oneof_field'))
+
+ def testOneofClearUnsetField(self):
+ m = unittest_pb2.TestAllTypes()
+ m.oneof_uint32 = 11
+ self.ensureNestedMessageExists(m, 'oneof_nested_message')
+ m.ClearField('oneof_nested_message')
+ self.assertEqual(11, m.oneof_uint32)
+ self.assertTrue(m.HasField('oneof_field'))
+ self.assertTrue(m.HasField('oneof_uint32'))
+ self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
+
+ def testOneofDeserialize(self):
+ m = unittest_pb2.TestAllTypes()
+ m.oneof_uint32 = 11
+ m2 = unittest_pb2.TestAllTypes()
+ m2.ParseFromString(m.SerializeToString())
+ self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
+
+ def testSortEmptyRepeatedCompositeContainer(self):
+ """Exercise a scenario that has led to segfaults in the past.
+ """
+ m = unittest_pb2.TestAllTypes()
+ m.repeated_nested_message.sort()
+
+ def testHasFieldOnRepeatedField(self):
+ """Using HasField on a repeated field should raise an exception.
+ """
+ m = unittest_pb2.TestAllTypes()
+ with self.assertRaises(ValueError) as _:
+ m.HasField('repeated_int32')
+
+
+class ValidTypeNamesTest(basetest.TestCase):
+
+ def assertImportFromName(self, msg, base_name):
+ # Parse <type 'module.class_name'> to extra 'some.name' as a string.
+ tp_name = str(type(msg)).split("'")[1]
+ valid_names = ('Repeated%sContainer' % base_name,
+ 'Repeated%sFieldContainer' % base_name)
+ self.assertTrue(any(tp_name.endswith(v) for v in valid_names),
+ '%r does end with any of %r' % (tp_name, valid_names))
+
+ parts = tp_name.split('.')
+ class_name = parts[-1]
+ module_name = '.'.join(parts[:-1])
+ __import__(module_name, fromlist=[class_name])
+
+ def testTypeNamesCanBeImported(self):
+ # If import doesn't work, pickling won't work either.
+ pb = unittest_pb2.TestAllTypes()
+ self.assertImportFromName(pb.repeated_int32, 'Scalar')
+ self.assertImportFromName(pb.repeated_nested_message, 'Composite')
+
if __name__ == '__main__':
- unittest.main()
+ basetest.main()
diff --git a/python/google/protobuf/internal/missing_enum_values.proto b/python/google/protobuf/internal/missing_enum_values.proto
new file mode 100644
index 0000000..e90f0cd
--- /dev/null
+++ b/python/google/protobuf/internal/missing_enum_values.proto
@@ -0,0 +1,50 @@
+// 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 google.protobuf.python.internal;
+
+message TestEnumValues {
+ enum NestedEnum {
+ ZERO = 0;
+ ONE = 1;
+ }
+ optional NestedEnum optional_nested_enum = 1;
+ repeated NestedEnum repeated_nested_enum = 2;
+ repeated NestedEnum packed_nested_enum = 3 [packed = true];
+}
+
+message TestMissingEnumValues {
+ enum NestedEnum {
+ TWO = 2;
+ }
+ optional NestedEnum optional_nested_enum = 1;
+ repeated NestedEnum repeated_nested_enum = 2;
+ repeated NestedEnum packed_nested_enum = 3 [packed = true];
+}
diff --git a/python/google/protobuf/internal/more_extensions.proto b/python/google/protobuf/internal/more_extensions.proto
index e2d9701..c04e597 100644
--- a/python/google/protobuf/internal/more_extensions.proto
+++ b/python/google/protobuf/internal/more_extensions.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/python/google/protobuf/internal/more_extensions_dynamic.proto b/python/google/protobuf/internal/more_extensions_dynamic.proto
new file mode 100644
index 0000000..88bd9c1
--- /dev/null
+++ b/python/google/protobuf/internal/more_extensions_dynamic.proto
@@ -0,0 +1,49 @@
+// 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: jasonh@google.com (Jason Hsueh)
+//
+// This file is used to test a corner case in the CPP implementation where the
+// generated C++ type is available for the extendee, but the extension is
+// defined in a file whose C++ type is not in the binary.
+
+
+import "google/protobuf/internal/more_extensions.proto";
+
+package google.protobuf.internal;
+
+message DynamicMessageType {
+ optional int32 a = 1;
+}
+
+extend ExtendedMessage {
+ optional int32 dynamic_int32_extension = 100;
+ optional DynamicMessageType dynamic_message_extension = 101;
+}
diff --git a/python/google/protobuf/internal/more_messages.proto b/python/google/protobuf/internal/more_messages.proto
index c701b44..61db66c 100644
--- a/python/google/protobuf/internal/more_messages.proto
+++ b/python/google/protobuf/internal/more_messages.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py
new file mode 100755
index 0000000..a5c26f4
--- /dev/null
+++ b/python/google/protobuf/internal/python_message.py
@@ -0,0 +1,1251 @@
+# 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.
+
+# Keep it Python2.5 compatible for GAE.
+#
+# Copyright 2007 Google Inc. All Rights Reserved.
+#
+# This code is meant to work on Python 2.4 and above only.
+#
+# TODO(robinson): Helpers for verbose, common checks like seeing if a
+# descriptor's cpp_type is CPPTYPE_MESSAGE.
+
+"""Contains a metaclass and helper functions used to create
+protocol message classes from Descriptor objects at runtime.
+
+Recall that a metaclass is the "type" of a class.
+(A class is to a metaclass what an instance is to a class.)
+
+In this case, we use the GeneratedProtocolMessageType metaclass
+to inject all the useful functionality into the classes
+output by the protocol compiler at compile-time.
+
+The upshot of all this is that the real implementation
+details for ALL pure-Python protocol buffers are *here in
+this file*.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import sys
+if sys.version_info[0] < 3:
+ try:
+ from cStringIO import StringIO as BytesIO
+ except ImportError:
+ from StringIO import StringIO as BytesIO
+ import copy_reg as copyreg
+else:
+ from io import BytesIO
+ import copyreg
+import struct
+import weakref
+
+# We use "as" to avoid name collisions with variables.
+from google.protobuf.internal import containers
+from google.protobuf.internal import decoder
+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 wire_format
+from google.protobuf import descriptor as descriptor_mod
+from google.protobuf import message as message_mod
+from google.protobuf import text_format
+
+_FieldDescriptor = descriptor_mod.FieldDescriptor
+
+
+def NewMessage(bases, descriptor, dictionary):
+ _AddClassAttributesForNestedExtensions(descriptor, dictionary)
+ _AddSlots(descriptor, dictionary)
+ return bases
+
+
+def InitMessage(descriptor, cls):
+ cls._decoders_by_tag = {}
+ cls._extensions_by_name = {}
+ cls._extensions_by_number = {}
+ if (descriptor.has_options and
+ descriptor.GetOptions().message_set_wire_format):
+ cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = (
+ decoder.MessageSetItemDecoder(cls._extensions_by_number), None)
+
+ # Attach stuff to each FieldDescriptor for quick lookup later on.
+ for field in descriptor.fields:
+ _AttachFieldHelpers(cls, field)
+
+ _AddEnumValues(descriptor, cls)
+ _AddInitMethod(descriptor, cls)
+ _AddPropertiesForFields(descriptor, cls)
+ _AddPropertiesForExtensions(descriptor, cls)
+ _AddStaticMethods(cls)
+ _AddMessageMethods(descriptor, cls)
+ _AddPrivateHelperMethods(descriptor, cls)
+ copyreg.pickle(cls, lambda obj: (cls, (), obj.__getstate__()))
+
+
+# Stateless helpers for GeneratedProtocolMessageType below.
+# Outside clients should not access these directly.
+#
+# I opted not to make any of these methods on the metaclass, to make it more
+# clear that I'm not really using any state there and to keep clients from
+# thinking that they have direct access to these construction helpers.
+
+
+def _PropertyName(proto_field_name):
+ """Returns the name of the public property attribute which
+ clients can use to get and (in some cases) set the value
+ of a protocol message field.
+
+ Args:
+ proto_field_name: The protocol message field name, exactly
+ as it appears (or would appear) in a .proto file.
+ """
+ # TODO(robinson): Escape Python keywords (e.g., yield), and test this support.
+ # nnorwitz makes my day by writing:
+ # """
+ # FYI. See the keyword module in the stdlib. This could be as simple as:
+ #
+ # if keyword.iskeyword(proto_field_name):
+ # return proto_field_name + "_"
+ # return proto_field_name
+ # """
+ # Kenton says: The above is a BAD IDEA. People rely on being able to use
+ # getattr() and setattr() to reflectively manipulate field values. If we
+ # rename the properties, then every such user has to also make sure to apply
+ # the same transformation. Note that currently if you name a field "yield",
+ # you can still access it just fine using getattr/setattr -- it's not even
+ # that cumbersome to do so.
+ # TODO(kenton): Remove this method entirely if/when everyone agrees with my
+ # position.
+ return proto_field_name
+
+
+def _VerifyExtensionHandle(message, extension_handle):
+ """Verify that the given extension handle is valid."""
+
+ if not isinstance(extension_handle, _FieldDescriptor):
+ raise KeyError('HasExtension() expects an extension handle, got: %s' %
+ extension_handle)
+
+ if not extension_handle.is_extension:
+ raise KeyError('"%s" is not an extension.' % extension_handle.full_name)
+
+ if not extension_handle.containing_type:
+ raise KeyError('"%s" is missing a containing_type.'
+ % extension_handle.full_name)
+
+ if extension_handle.containing_type is not message.DESCRIPTOR:
+ raise KeyError('Extension "%s" extends message type "%s", but this '
+ 'message is of type "%s".' %
+ (extension_handle.full_name,
+ extension_handle.containing_type.full_name,
+ message.DESCRIPTOR.full_name))
+
+
+def _AddSlots(message_descriptor, dictionary):
+ """Adds a __slots__ entry to dictionary, containing the names of all valid
+ attributes for this message type.
+
+ Args:
+ message_descriptor: A Descriptor instance describing this message type.
+ dictionary: Class dictionary to which we'll add a '__slots__' entry.
+ """
+ dictionary['__slots__'] = ['_cached_byte_size',
+ '_cached_byte_size_dirty',
+ '_fields',
+ '_unknown_fields',
+ '_is_present_in_parent',
+ '_listener',
+ '_listener_for_children',
+ '__weakref__',
+ '_oneofs']
+
+
+def _IsMessageSetExtension(field):
+ return (field.is_extension and
+ 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)
+
+
+def _AttachFieldHelpers(cls, field_descriptor):
+ is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED)
+ is_packed = (field_descriptor.has_options and
+ field_descriptor.GetOptions().packed)
+
+ if _IsMessageSetExtension(field_descriptor):
+ field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number)
+ sizer = encoder.MessageSetItemSizer(field_descriptor.number)
+ else:
+ field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type](
+ field_descriptor.number, is_repeated, is_packed)
+ sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type](
+ field_descriptor.number, is_repeated, is_packed)
+
+ field_descriptor._encoder = field_encoder
+ field_descriptor._sizer = sizer
+ field_descriptor._default_constructor = _DefaultValueConstructorForField(
+ field_descriptor)
+
+ def AddDecoder(wiretype, is_packed):
+ tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype)
+ cls._decoders_by_tag[tag_bytes] = (
+ type_checkers.TYPE_TO_DECODER[field_descriptor.type](
+ field_descriptor.number, is_repeated, is_packed,
+ field_descriptor, field_descriptor._default_constructor),
+ field_descriptor if field_descriptor.containing_oneof is not None
+ else None)
+
+ AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type],
+ False)
+
+ if is_repeated and wire_format.IsTypePackable(field_descriptor.type):
+ # To support wire compatibility of adding packed = true, add a decoder for
+ # packed values regardless of the field's options.
+ AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True)
+
+
+def _AddClassAttributesForNestedExtensions(descriptor, dictionary):
+ extension_dict = descriptor.extensions_by_name
+ for extension_name, extension_field in extension_dict.iteritems():
+ assert extension_name not in dictionary
+ dictionary[extension_name] = extension_field
+
+
+def _AddEnumValues(descriptor, cls):
+ """Sets class-level attributes for all enum fields defined in this message.
+
+ Also exporting a class-level object that can name enum values.
+
+ Args:
+ descriptor: Descriptor object for this message type.
+ cls: Class we're constructing for this message type.
+ """
+ for enum_type in descriptor.enum_types:
+ setattr(cls, enum_type.name, enum_type_wrapper.EnumTypeWrapper(enum_type))
+ for enum_value in enum_type.values:
+ setattr(cls, enum_value.name, enum_value.number)
+
+
+def _DefaultValueConstructorForField(field):
+ """Returns a function which returns a default value for a field.
+
+ Args:
+ field: FieldDescriptor object for this field.
+
+ The returned function has one argument:
+ message: Message instance containing this field, or a weakref proxy
+ of same.
+
+ That function in turn returns a default value for this field. The default
+ value may refer back to |message| via a weak reference.
+ """
+
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ if field.has_default_value and field.default_value != []:
+ raise ValueError('Repeated field default value not empty list: %s' % (
+ field.default_value))
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ # We can't look at _concrete_class yet since it might not have
+ # been set. (Depends on order in which we initialize the classes).
+ message_type = field.message_type
+ def MakeRepeatedMessageDefault(message):
+ return containers.RepeatedCompositeFieldContainer(
+ message._listener_for_children, field.message_type)
+ return MakeRepeatedMessageDefault
+ else:
+ type_checker = type_checkers.GetTypeChecker(field)
+ def MakeRepeatedScalarDefault(message):
+ return containers.RepeatedScalarFieldContainer(
+ message._listener_for_children, type_checker)
+ return MakeRepeatedScalarDefault
+
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ # _concrete_class may not yet be initialized.
+ message_type = field.message_type
+ def MakeSubMessageDefault(message):
+ result = message_type._concrete_class()
+ result._SetListener(message._listener_for_children)
+ return result
+ return MakeSubMessageDefault
+
+ def MakeScalarDefault(message):
+ # TODO(protobuf-team): This may be broken since there may not be
+ # default_value. Combine with has_default_value somehow.
+ return field.default_value
+ return MakeScalarDefault
+
+
+def _AddInitMethod(message_descriptor, cls):
+ """Adds an __init__ method to cls."""
+ fields = message_descriptor.fields
+ def init(self, **kwargs):
+ self._cached_byte_size = 0
+ self._cached_byte_size_dirty = len(kwargs) > 0
+ self._fields = {}
+ # Contains a mapping from oneof field descriptors to the descriptor
+ # of the currently set field in that oneof field.
+ self._oneofs = {}
+
+ # _unknown_fields is () when empty for efficiency, and will be turned into
+ # a list if fields are added.
+ self._unknown_fields = ()
+ self._is_present_in_parent = False
+ self._listener = message_listener_mod.NullMessageListener()
+ self._listener_for_children = _Listener(self)
+ for field_name, field_value in kwargs.iteritems():
+ field = _GetFieldByName(message_descriptor, field_name)
+ if field is None:
+ raise TypeError("%s() got an unexpected keyword argument '%s'" %
+ (message_descriptor.name, field_name))
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ copy = field._default_constructor(self)
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite
+ for val in field_value:
+ copy.add().MergeFrom(val)
+ else: # Scalar
+ copy.extend(field_value)
+ self._fields[field] = copy
+ elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ copy = field._default_constructor(self)
+ copy.MergeFrom(field_value)
+ self._fields[field] = copy
+ else:
+ setattr(self, field_name, field_value)
+
+ init.__module__ = None
+ init.__doc__ = None
+ cls.__init__ = init
+
+
+def _GetFieldByName(message_descriptor, field_name):
+ """Returns a field descriptor by field name.
+
+ Args:
+ message_descriptor: A Descriptor describing all fields in message.
+ field_name: The name of the field to retrieve.
+ Returns:
+ The field descriptor associated with the field name.
+ """
+ try:
+ return message_descriptor.fields_by_name[field_name]
+ except KeyError:
+ raise ValueError('Protocol message has no "%s" field.' % field_name)
+
+
+def _AddPropertiesForFields(descriptor, cls):
+ """Adds properties for all fields in this protocol message type."""
+ for field in descriptor.fields:
+ _AddPropertiesForField(field, cls)
+
+ if descriptor.is_extendable:
+ # _ExtensionDict is just an adaptor with no state so we allocate a new one
+ # every time it is accessed.
+ cls.Extensions = property(lambda self: _ExtensionDict(self))
+
+
+def _AddPropertiesForField(field, cls):
+ """Adds a public property for a protocol message field.
+ Clients can use this property to get and (in the case
+ of non-repeated scalar fields) directly set the value
+ of a protocol message field.
+
+ Args:
+ field: A FieldDescriptor for this field.
+ cls: The class we're constructing.
+ """
+ # Catch it if we add other types that we should
+ # handle specially here.
+ assert _FieldDescriptor.MAX_CPPTYPE == 10
+
+ constant_name = field.name.upper() + "_FIELD_NUMBER"
+ setattr(cls, constant_name, field.number)
+
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ _AddPropertiesForRepeatedField(field, cls)
+ elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ _AddPropertiesForNonRepeatedCompositeField(field, cls)
+ else:
+ _AddPropertiesForNonRepeatedScalarField(field, cls)
+
+
+def _AddPropertiesForRepeatedField(field, cls):
+ """Adds a public property for a "repeated" protocol message field. Clients
+ can use this property to get the value of the field, which will be either a
+ _RepeatedScalarFieldContainer or _RepeatedCompositeFieldContainer (see
+ below).
+
+ Note that when clients add values to these containers, we perform
+ type-checking in the case of repeated scalar fields, and we also set any
+ necessary "has" bits as a side-effect.
+
+ Args:
+ field: A FieldDescriptor for this field.
+ cls: The class we're constructing.
+ """
+ proto_field_name = field.name
+ property_name = _PropertyName(proto_field_name)
+
+ def getter(self):
+ field_value = self._fields.get(field)
+ if field_value is None:
+ # Construct a new object to represent this field.
+ field_value = field._default_constructor(self)
+
+ # Atomically check if another thread has preempted us and, if not, swap
+ # in the new object we just created. If someone has preempted us, we
+ # take that object and discard ours.
+ # WARNING: We are relying on setdefault() being atomic. This is true
+ # in CPython but we haven't investigated others. This warning appears
+ # in several other locations in this file.
+ field_value = self._fields.setdefault(field, field_value)
+ return field_value
+ getter.__module__ = None
+ getter.__doc__ = 'Getter for %s.' % proto_field_name
+
+ # We define a setter just so we can throw an exception with a more
+ # helpful error message.
+ def setter(self, new_value):
+ raise AttributeError('Assignment not allowed to repeated field '
+ '"%s" in protocol message object.' % proto_field_name)
+
+ doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
+ setattr(cls, property_name, property(getter, setter, doc=doc))
+
+
+def _AddPropertiesForNonRepeatedScalarField(field, cls):
+ """Adds a public property for a nonrepeated, scalar protocol message field.
+ Clients can use this property to get and directly set the value of the field.
+ Note that when the client sets the value of a field by using this property,
+ all necessary "has" bits are set as a side-effect, and we also perform
+ type-checking.
+
+ Args:
+ field: A FieldDescriptor for this field.
+ cls: The class we're constructing.
+ """
+ proto_field_name = field.name
+ property_name = _PropertyName(proto_field_name)
+ type_checker = type_checkers.GetTypeChecker(field)
+ default_value = field.default_value
+ valid_values = set()
+
+ def getter(self):
+ # TODO(protobuf-team): This may be broken since there may not be
+ # default_value. Combine with has_default_value somehow.
+ return self._fields.get(field, default_value)
+ getter.__module__ = None
+ getter.__doc__ = 'Getter for %s.' % proto_field_name
+ def field_setter(self, new_value):
+ # pylint: disable=protected-access
+ self._fields[field] = type_checker.CheckValue(new_value)
+ # Check _cached_byte_size_dirty inline to improve performance, since scalar
+ # setters are called frequently.
+ if not self._cached_byte_size_dirty:
+ self._Modified()
+
+ if field.containing_oneof is not None:
+ def setter(self, new_value):
+ field_setter(self, new_value)
+ self._UpdateOneofState(field)
+ else:
+ setter = field_setter
+
+ setter.__module__ = None
+ setter.__doc__ = 'Setter for %s.' % proto_field_name
+
+ # Add a property to encapsulate the getter/setter.
+ doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
+ setattr(cls, property_name, property(getter, setter, doc=doc))
+
+
+def _AddPropertiesForNonRepeatedCompositeField(field, cls):
+ """Adds a public property for a nonrepeated, composite protocol message field.
+ A composite field is a "group" or "message" field.
+
+ Clients can use this property to get the value of the field, but cannot
+ assign to the property directly.
+
+ Args:
+ field: A FieldDescriptor for this field.
+ cls: The class we're constructing.
+ """
+ # TODO(robinson): Remove duplication with similar method
+ # for non-repeated scalars.
+ proto_field_name = field.name
+ property_name = _PropertyName(proto_field_name)
+
+ # TODO(komarek): Can anyone explain to me why we cache the message_type this
+ # way, instead of referring to field.message_type inside of getter(self)?
+ # What if someone sets message_type later on (which makes for simpler
+ # dyanmic proto descriptor and class creation code).
+ message_type = field.message_type
+
+ def getter(self):
+ field_value = self._fields.get(field)
+ if field_value is None:
+ # Construct a new object to represent this field.
+ field_value = message_type._concrete_class() # use field.message_type?
+ field_value._SetListener(
+ _OneofListener(self, field)
+ if field.containing_oneof is not None
+ else self._listener_for_children)
+
+ # Atomically check if another thread has preempted us and, if not, swap
+ # in the new object we just created. If someone has preempted us, we
+ # take that object and discard ours.
+ # WARNING: We are relying on setdefault() being atomic. This is true
+ # in CPython but we haven't investigated others. This warning appears
+ # in several other locations in this file.
+ field_value = self._fields.setdefault(field, field_value)
+ return field_value
+ getter.__module__ = None
+ getter.__doc__ = 'Getter for %s.' % proto_field_name
+
+ # We define a setter just so we can throw an exception with a more
+ # helpful error message.
+ def setter(self, new_value):
+ raise AttributeError('Assignment not allowed to composite field '
+ '"%s" in protocol message object.' % proto_field_name)
+
+ # Add a property to encapsulate the getter.
+ doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
+ setattr(cls, property_name, property(getter, setter, doc=doc))
+
+
+def _AddPropertiesForExtensions(descriptor, cls):
+ """Adds properties for all fields in this protocol message type."""
+ extension_dict = descriptor.extensions_by_name
+ for extension_name, extension_field in extension_dict.iteritems():
+ constant_name = extension_name.upper() + "_FIELD_NUMBER"
+ setattr(cls, constant_name, extension_field.number)
+
+
+def _AddStaticMethods(cls):
+ # TODO(robinson): This probably needs to be thread-safe(?)
+ def RegisterExtension(extension_handle):
+ extension_handle.containing_type = cls.DESCRIPTOR
+ _AttachFieldHelpers(cls, extension_handle)
+
+ # Try to insert our extension, failing if an extension with the same number
+ # already exists.
+ actual_handle = cls._extensions_by_number.setdefault(
+ extension_handle.number, extension_handle)
+ if actual_handle is not extension_handle:
+ raise AssertionError(
+ 'Extensions "%s" and "%s" both try to extend message type "%s" with '
+ 'field number %d.' %
+ (extension_handle.full_name, actual_handle.full_name,
+ cls.DESCRIPTOR.full_name, extension_handle.number))
+
+ cls._extensions_by_name[extension_handle.full_name] = extension_handle
+
+ handle = extension_handle # avoid line wrapping
+ if _IsMessageSetExtension(handle):
+ # MessageSet extension. Also register under type name.
+ cls._extensions_by_name[
+ extension_handle.message_type.full_name] = extension_handle
+
+ cls.RegisterExtension = staticmethod(RegisterExtension)
+
+ def FromString(s):
+ message = cls()
+ message.MergeFromString(s)
+ return message
+ cls.FromString = staticmethod(FromString)
+
+
+def _IsPresent(item):
+ """Given a (FieldDescriptor, value) tuple from _fields, return true if the
+ value should be included in the list returned by ListFields()."""
+
+ if item[0].label == _FieldDescriptor.LABEL_REPEATED:
+ return bool(item[1])
+ elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ return item[1]._is_present_in_parent
+ else:
+ return True
+
+
+def _AddListFieldsMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def ListFields(self):
+ all_fields = [item for item in self._fields.iteritems() if _IsPresent(item)]
+ all_fields.sort(key = lambda item: item[0].number)
+ return all_fields
+
+ cls.ListFields = ListFields
+
+
+def _AddHasFieldMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ singular_fields = {}
+ for field in message_descriptor.fields:
+ if field.label != _FieldDescriptor.LABEL_REPEATED:
+ singular_fields[field.name] = field
+ # Fields inside oneofs are never repeated (enforced by the compiler).
+ for field in message_descriptor.oneofs:
+ singular_fields[field.name] = field
+
+ def HasField(self, field_name):
+ try:
+ field = singular_fields[field_name]
+ except KeyError:
+ raise ValueError(
+ 'Protocol message has no singular "%s" field.' % field_name)
+
+ if isinstance(field, descriptor_mod.OneofDescriptor):
+ try:
+ return HasField(self, self._oneofs[field].name)
+ except KeyError:
+ return False
+ else:
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ value = self._fields.get(field)
+ return value is not None and value._is_present_in_parent
+ else:
+ return field in self._fields
+
+ cls.HasField = HasField
+
+
+def _AddClearFieldMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def ClearField(self, field_name):
+ try:
+ field = message_descriptor.fields_by_name[field_name]
+ except KeyError:
+ try:
+ field = message_descriptor.oneofs_by_name[field_name]
+ if field in self._oneofs:
+ field = self._oneofs[field]
+ else:
+ return
+ except KeyError:
+ raise ValueError('Protocol message has no "%s" field.' % field_name)
+
+ if field in self._fields:
+ # 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.
+ del self._fields[field]
+
+ if self._oneofs.get(field.containing_oneof, None) is field:
+ del self._oneofs[field.containing_oneof]
+
+ # Always call _Modified() -- even if nothing was changed, this is
+ # a mutating method, and thus calling it should cause the field to become
+ # present in the parent message.
+ self._Modified()
+
+ cls.ClearField = ClearField
+
+
+def _AddClearExtensionMethod(cls):
+ """Helper for _AddMessageMethods()."""
+ def ClearExtension(self, extension_handle):
+ _VerifyExtensionHandle(self, extension_handle)
+
+ # Similar to ClearField(), above.
+ if extension_handle in self._fields:
+ del self._fields[extension_handle]
+ self._Modified()
+ cls.ClearExtension = ClearExtension
+
+
+def _AddClearMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def Clear(self):
+ # Clear fields.
+ self._fields = {}
+ self._unknown_fields = ()
+ self._Modified()
+ cls.Clear = Clear
+
+
+def _AddHasExtensionMethod(cls):
+ """Helper for _AddMessageMethods()."""
+ def HasExtension(self, extension_handle):
+ _VerifyExtensionHandle(self, extension_handle)
+ if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
+ raise KeyError('"%s" is repeated.' % extension_handle.full_name)
+
+ if extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ value = self._fields.get(extension_handle)
+ return value is not None and value._is_present_in_parent
+ else:
+ return extension_handle in self._fields
+ cls.HasExtension = HasExtension
+
+
+def _AddEqualsMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def __eq__(self, other):
+ if (not isinstance(other, message_mod.Message) or
+ other.DESCRIPTOR != self.DESCRIPTOR):
+ return False
+
+ if self is other:
+ return True
+
+ if not self.ListFields() == other.ListFields():
+ return False
+
+ # Sort unknown fields because their order shouldn't affect equality test.
+ unknown_fields = list(self._unknown_fields)
+ unknown_fields.sort()
+ other_unknown_fields = list(other._unknown_fields)
+ other_unknown_fields.sort()
+
+ return unknown_fields == other_unknown_fields
+
+ cls.__eq__ = __eq__
+
+
+def _AddStrMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def __str__(self):
+ return text_format.MessageToString(self)
+ cls.__str__ = __str__
+
+
+def _AddUnicodeMethod(unused_message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def __unicode__(self):
+ return text_format.MessageToString(self, as_utf8=True).decode('utf-8')
+ 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
+ other additional space associated with serializing value.
+
+ Args:
+ value: Value we're serializing.
+ field_number: Field number of this value. (Since the field number
+ is stored as part of a varint-encoded tag, this has an impact
+ on the total bytes required to serialize the value).
+ field_type: The type of the field. One of the TYPE_* constants
+ within FieldDescriptor.
+ """
+ try:
+ fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type]
+ return fn(field_number, value)
+ except KeyError:
+ raise message_mod.EncodeError('Unrecognized field type: %d' % field_type)
+
+
+def _AddByteSizeMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def ByteSize(self):
+ if not self._cached_byte_size_dirty:
+ return self._cached_byte_size
+
+ size = 0
+ for field_descriptor, field_value in self.ListFields():
+ size += field_descriptor._sizer(field_value)
+
+ for tag_bytes, value_bytes in self._unknown_fields:
+ size += len(tag_bytes) + len(value_bytes)
+
+ self._cached_byte_size = size
+ self._cached_byte_size_dirty = False
+ self._listener_for_children.dirty = False
+ return size
+
+ cls.ByteSize = ByteSize
+
+
+def _AddSerializeToStringMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def SerializeToString(self):
+ # Check if the message has all of its required fields set.
+ errors = []
+ if not self.IsInitialized():
+ raise message_mod.EncodeError(
+ 'Message %s is missing required fields: %s' % (
+ self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
+ return self.SerializePartialToString()
+ cls.SerializeToString = SerializeToString
+
+
+def _AddSerializePartialToStringMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def SerializePartialToString(self):
+ out = BytesIO()
+ self._InternalSerialize(out.write)
+ return out.getvalue()
+ cls.SerializePartialToString = SerializePartialToString
+
+ def InternalSerialize(self, write_bytes):
+ for field_descriptor, field_value in self.ListFields():
+ field_descriptor._encoder(write_bytes, field_value)
+ for tag_bytes, value_bytes in self._unknown_fields:
+ write_bytes(tag_bytes)
+ write_bytes(value_bytes)
+ cls._InternalSerialize = InternalSerialize
+
+
+def _AddMergeFromStringMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def MergeFromString(self, serialized):
+ length = len(serialized)
+ try:
+ if self._InternalParse(serialized, 0, length) != length:
+ # The only reason _InternalParse would return early is if it
+ # encountered an end-group tag.
+ raise message_mod.DecodeError('Unexpected end-group tag.')
+ except (IndexError, TypeError):
+ # Now ord(buf[p:p+1]) == ord('') gets TypeError.
+ raise message_mod.DecodeError('Truncated message.')
+ except struct.error, e:
+ raise message_mod.DecodeError(e)
+ return length # Return this for legacy reasons.
+ cls.MergeFromString = MergeFromString
+
+ local_ReadTag = decoder.ReadTag
+ local_SkipField = decoder.SkipField
+ decoders_by_tag = cls._decoders_by_tag
+
+ def InternalParse(self, buffer, pos, end):
+ self._Modified()
+ field_dict = self._fields
+ unknown_field_list = self._unknown_fields
+ while pos != end:
+ (tag_bytes, new_pos) = local_ReadTag(buffer, pos)
+ field_decoder, field_desc = decoders_by_tag.get(tag_bytes, (None, None))
+ if field_decoder is None:
+ value_start_pos = new_pos
+ new_pos = local_SkipField(buffer, new_pos, end, tag_bytes)
+ if new_pos == -1:
+ return pos
+ if not unknown_field_list:
+ unknown_field_list = self._unknown_fields = []
+ unknown_field_list.append((tag_bytes, buffer[value_start_pos:new_pos]))
+ pos = new_pos
+ else:
+ pos = field_decoder(buffer, new_pos, end, self, field_dict)
+ if field_desc:
+ self._UpdateOneofState(field_desc)
+ return pos
+ cls._InternalParse = InternalParse
+
+
+def _AddIsInitializedMethod(message_descriptor, cls):
+ """Adds the IsInitialized and FindInitializationError methods to the
+ protocol message class."""
+
+ required_fields = [field for field in message_descriptor.fields
+ if field.label == _FieldDescriptor.LABEL_REQUIRED]
+
+ def IsInitialized(self, errors=None):
+ """Checks if all required fields of a message are set.
+
+ Args:
+ errors: A list which, if provided, will be populated with the field
+ paths of all missing required fields.
+
+ Returns:
+ True iff the specified message has all required fields set.
+ """
+
+ # Performance is critical so we avoid HasField() and ListFields().
+
+ for field in required_fields:
+ if (field not in self._fields or
+ (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
+ not self._fields[field]._is_present_in_parent)):
+ if errors is not None:
+ errors.extend(self.FindInitializationErrors())
+ return False
+
+ for field, value in list(self._fields.items()): # dict can change size!
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ for element in value:
+ if not element.IsInitialized():
+ if errors is not None:
+ errors.extend(self.FindInitializationErrors())
+ return False
+ elif value._is_present_in_parent and not value.IsInitialized():
+ if errors is not None:
+ errors.extend(self.FindInitializationErrors())
+ return False
+
+ return True
+
+ cls.IsInitialized = IsInitialized
+
+ def FindInitializationErrors(self):
+ """Finds required fields which are not initialized.
+
+ Returns:
+ A list of strings. Each string is a path to an uninitialized field from
+ the top-level message, e.g. "foo.bar[5].baz".
+ """
+
+ errors = [] # simplify things
+
+ for field in required_fields:
+ if not self.HasField(field.name):
+ errors.append(field.name)
+
+ for field, value in self.ListFields():
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ if field.is_extension:
+ name = "(%s)" % field.full_name
+ else:
+ name = field.name
+
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ for i in xrange(len(value)):
+ element = value[i]
+ prefix = "%s[%d]." % (name, i)
+ sub_errors = element.FindInitializationErrors()
+ errors += [ prefix + error for error in sub_errors ]
+ else:
+ prefix = name + "."
+ sub_errors = value.FindInitializationErrors()
+ errors += [ prefix + error for error in sub_errors ]
+
+ return errors
+
+ cls.FindInitializationErrors = FindInitializationErrors
+
+
+def _AddMergeFromMethod(cls):
+ LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED
+ CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE
+
+ def MergeFrom(self, msg):
+ if not isinstance(msg, cls):
+ raise TypeError(
+ "Parameter to MergeFrom() must be instance of same class: "
+ "expected %s got %s." % (cls.__name__, type(msg).__name__))
+
+ assert msg is not self
+ self._Modified()
+
+ fields = self._fields
+
+ for field, value in msg._fields.iteritems():
+ if field.label == LABEL_REPEATED:
+ field_value = fields.get(field)
+ if field_value is None:
+ # Construct a new object to represent this field.
+ field_value = field._default_constructor(self)
+ fields[field] = field_value
+ field_value.MergeFrom(value)
+ elif field.cpp_type == CPPTYPE_MESSAGE:
+ if value._is_present_in_parent:
+ field_value = fields.get(field)
+ if field_value is None:
+ # Construct a new object to represent this field.
+ field_value = field._default_constructor(self)
+ fields[field] = field_value
+ field_value.MergeFrom(value)
+ else:
+ self._fields[field] = value
+
+ if msg._unknown_fields:
+ if not self._unknown_fields:
+ self._unknown_fields = []
+ self._unknown_fields.extend(msg._unknown_fields)
+
+ cls.MergeFrom = MergeFrom
+
+
+def _AddWhichOneofMethod(message_descriptor, cls):
+ def WhichOneof(self, oneof_name):
+ """Returns the name of the currently set field inside a oneof, or None."""
+ try:
+ field = message_descriptor.oneofs_by_name[oneof_name]
+ except KeyError:
+ raise ValueError(
+ 'Protocol message has no oneof "%s" field.' % oneof_name)
+
+ nested_field = self._oneofs.get(field, None)
+ if nested_field is not None and self.HasField(nested_field.name):
+ return nested_field.name
+ else:
+ return None
+
+ cls.WhichOneof = WhichOneof
+
+
+def _AddMessageMethods(message_descriptor, cls):
+ """Adds implementations of all Message methods to cls."""
+ _AddListFieldsMethod(message_descriptor, cls)
+ _AddHasFieldMethod(message_descriptor, cls)
+ _AddClearFieldMethod(message_descriptor, cls)
+ if message_descriptor.is_extendable:
+ _AddClearExtensionMethod(cls)
+ _AddHasExtensionMethod(cls)
+ _AddClearMethod(message_descriptor, cls)
+ _AddEqualsMethod(message_descriptor, cls)
+ _AddStrMethod(message_descriptor, cls)
+ _AddUnicodeMethod(message_descriptor, cls)
+ _AddSetListenerMethod(cls)
+ _AddByteSizeMethod(message_descriptor, cls)
+ _AddSerializeToStringMethod(message_descriptor, cls)
+ _AddSerializePartialToStringMethod(message_descriptor, cls)
+ _AddMergeFromStringMethod(message_descriptor, cls)
+ _AddIsInitializedMethod(message_descriptor, cls)
+ _AddMergeFromMethod(cls)
+ _AddWhichOneofMethod(message_descriptor, cls)
+
+def _AddPrivateHelperMethods(message_descriptor, cls):
+ """Adds implementation of private helper methods to cls."""
+
+ def Modified(self):
+ """Sets the _cached_byte_size_dirty bit to true,
+ and propagates this to our listener iff this was a state change.
+ """
+
+ # Note: Some callers check _cached_byte_size_dirty before calling
+ # _Modified() as an extra optimization. So, if this method is ever
+ # changed such that it does stuff even when _cached_byte_size_dirty is
+ # already true, the callers need to be updated.
+ if not self._cached_byte_size_dirty:
+ self._cached_byte_size_dirty = True
+ self._listener_for_children.dirty = True
+ self._is_present_in_parent = True
+ self._listener.Modified()
+
+ def _UpdateOneofState(self, field):
+ """Sets field as the active field in its containing oneof.
+
+ Will also delete currently active field in the oneof, if it is different
+ from the argument. Does not mark the message as modified.
+ """
+ other_field = self._oneofs.setdefault(field.containing_oneof, field)
+ if other_field is not field:
+ del self._fields[other_field]
+ self._oneofs[field.containing_oneof] = field
+
+ cls._Modified = Modified
+ cls.SetInParent = Modified
+ cls._UpdateOneofState = _UpdateOneofState
+
+
+class _Listener(object):
+
+ """MessageListener implementation that a parent message registers with its
+ child message.
+
+ In order to support semantics like:
+
+ foo.bar.baz.qux = 23
+ assert foo.HasField('bar')
+
+ ...child objects must have back references to their parents.
+ This helper class is at the heart of this support.
+ """
+
+ def __init__(self, parent_message):
+ """Args:
+ parent_message: The message whose _Modified() method we should call when
+ we receive Modified() messages.
+ """
+ # This listener establishes a back reference from a child (contained) object
+ # to its parent (containing) object. We make this a weak reference to avoid
+ # creating cyclic garbage when the client finishes with the 'parent' object
+ # in the tree.
+ if isinstance(parent_message, weakref.ProxyType):
+ self._parent_message_weakref = parent_message
+ else:
+ self._parent_message_weakref = weakref.proxy(parent_message)
+
+ # As an optimization, we also indicate directly on the listener whether
+ # or not the parent message is dirty. This way we can avoid traversing
+ # up the tree in the common case.
+ self.dirty = False
+
+ def Modified(self):
+ if self.dirty:
+ return
+ try:
+ # Propagate the signal to our parents iff this is the first field set.
+ self._parent_message_weakref._Modified()
+ except ReferenceError:
+ # We can get here if a client has kept a reference to a child object,
+ # and is now setting a field on it, but the child's parent has been
+ # garbage-collected. This is not an error.
+ pass
+
+
+class _OneofListener(_Listener):
+ """Special listener implementation for setting composite oneof fields."""
+
+ def __init__(self, parent_message, field):
+ """Args:
+ parent_message: The message whose _Modified() method we should call when
+ we receive Modified() messages.
+ field: The descriptor of the field being set in the parent message.
+ """
+ super(_OneofListener, self).__init__(parent_message)
+ self._field = field
+
+ def Modified(self):
+ """Also updates the state of the containing oneof in the parent message."""
+ try:
+ self._parent_message_weakref._UpdateOneofState(self._field)
+ super(_OneofListener, self).Modified()
+ except ReferenceError:
+ pass
+
+
+# TODO(robinson): Move elsewhere? This file is getting pretty ridiculous...
+# TODO(robinson): Unify error handling of "unknown extension" crap.
+# TODO(robinson): Support iteritems()-style iteration over all
+# extensions with the "has" bits turned on?
+class _ExtensionDict(object):
+
+ """Dict-like container for supporting an indexable "Extensions"
+ field on proto instances.
+
+ Note that in all cases we expect extension handles to be
+ FieldDescriptors.
+ """
+
+ def __init__(self, extended_message):
+ """extended_message: Message instance for which we are the Extensions dict.
+ """
+
+ self._extended_message = extended_message
+
+ def __getitem__(self, extension_handle):
+ """Returns the current value of the given extension handle."""
+
+ _VerifyExtensionHandle(self._extended_message, extension_handle)
+
+ result = self._extended_message._fields.get(extension_handle)
+ if result is not None:
+ return result
+
+ if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
+ result = extension_handle._default_constructor(self._extended_message)
+ elif extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ result = extension_handle.message_type._concrete_class()
+ try:
+ result._SetListener(self._extended_message._listener_for_children)
+ except ReferenceError:
+ pass
+ else:
+ # Singular scalar -- just return the default without inserting into the
+ # dict.
+ return extension_handle.default_value
+
+ # Atomically check if another thread has preempted us and, if not, swap
+ # in the new object we just created. If someone has preempted us, we
+ # take that object and discard ours.
+ # WARNING: We are relying on setdefault() being atomic. This is true
+ # in CPython but we haven't investigated others. This warning appears
+ # in several other locations in this file.
+ result = self._extended_message._fields.setdefault(
+ extension_handle, result)
+
+ return result
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return False
+
+ my_fields = self._extended_message.ListFields()
+ other_fields = other._extended_message.ListFields()
+
+ # Get rid of non-extension fields.
+ my_fields = [ field for field in my_fields if field.is_extension ]
+ other_fields = [ field for field in other_fields if field.is_extension ]
+
+ return my_fields == other_fields
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ # Note that this is only meaningful for non-repeated, scalar extension
+ # fields. Note also that we may have to call _Modified() when we do
+ # successfully set a field this way, to set any necssary "has" bits in the
+ # ancestors of the extended message.
+ def __setitem__(self, extension_handle, value):
+ """If extension_handle specifies a non-repeated, scalar extension
+ field, sets the value of that field.
+ """
+
+ _VerifyExtensionHandle(self._extended_message, extension_handle)
+
+ if (extension_handle.label == _FieldDescriptor.LABEL_REPEATED or
+ extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE):
+ raise TypeError(
+ 'Cannot assign to extension "%s" because it is a repeated or '
+ 'composite type.' % extension_handle.full_name)
+
+ # It's slightly wasteful to lookup the type checker each time,
+ # but we expect this to be a vanishingly uncommon case anyway.
+ type_checker = type_checkers.GetTypeChecker(
+ extension_handle)
+ # pylint: disable=protected-access
+ self._extended_message._fields[extension_handle] = (
+ type_checker.CheckValue(value))
+ self._extended_message._Modified()
+
+ def _FindExtensionByName(self, name):
+ """Tries to find a known extension with the specified name.
+
+ Args:
+ name: Extension full name.
+
+ Returns:
+ Extension field descriptor.
+ """
+ return self._extended_message._extensions_by_name.get(name, None)
diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py
index 2c9fa30..d59815d 100755
--- a/python/google/protobuf/internal/reflection_test.py
+++ b/python/google/protobuf/internal/reflection_test.py
@@ -3,7 +3,7 @@
#
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -37,12 +37,12 @@ pure-Python protocol compiler.
__author__ = 'robinson@google.com (Will Robinson)'
+import copy
+import gc
import operator
import struct
-import unittest
-# TODO(robinson): When we split this test in two, only some of these imports
-# will be necessary in each test.
+from google.apputils import basetest
from google.protobuf import unittest_import_pb2
from google.protobuf import unittest_mset_pb2
from google.protobuf import unittest_pb2
@@ -50,6 +50,8 @@ from google.protobuf import descriptor_pb2
from google.protobuf import descriptor
from google.protobuf import message
from google.protobuf import reflection
+from google.protobuf import text_format
+from google.protobuf.internal import api_implementation
from google.protobuf.internal import more_extensions_pb2
from google.protobuf.internal import more_messages_pb2
from google.protobuf.internal import wire_format
@@ -102,12 +104,12 @@ class _MiniDecoder(object):
return self._pos == len(self._bytes)
-class ReflectionTest(unittest.TestCase):
+class ReflectionTest(basetest.TestCase):
- def assertIs(self, values, others):
+ def assertListsEqual(self, values, others):
self.assertEqual(len(values), len(others))
for i in range(len(values)):
- self.assertTrue(values[i] is others[i])
+ self.assertEqual(values[i], others[i])
def testScalarConstructor(self):
# Constructor with only scalar types should succeed.
@@ -200,6 +202,41 @@ class ReflectionTest(unittest.TestCase):
unittest_pb2.ForeignMessage(c=12)],
list(proto.repeated_foreign_message))
+ def testConstructorTypeError(self):
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, optional_int32="foo")
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, optional_string=1234)
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, optional_nested_message=1234)
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, repeated_int32=1234)
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, repeated_int32=["foo"])
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, repeated_string=1234)
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, repeated_string=[1234])
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=1234)
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=[1234])
+
+ def testConstructorInvalidatesCachedByteSize(self):
+ message = unittest_pb2.TestAllTypes(optional_int32 = 12)
+ self.assertEquals(2, message.ByteSize())
+
+ message = unittest_pb2.TestAllTypes(
+ optional_nested_message = unittest_pb2.TestAllTypes.NestedMessage())
+ self.assertEquals(3, message.ByteSize())
+
+ message = unittest_pb2.TestAllTypes(repeated_int32 = [12])
+ self.assertEquals(3, message.ByteSize())
+
+ message = unittest_pb2.TestAllTypes(
+ repeated_nested_message = [unittest_pb2.TestAllTypes.NestedMessage()])
+ self.assertEquals(3, message.ByteSize())
+
def testSimpleHasBits(self):
# Test a scalar.
proto = unittest_pb2.TestAllTypes()
@@ -284,12 +321,6 @@ class ReflectionTest(unittest.TestCase):
# ...and ensure that the scalar field has returned to its default.
self.assertEqual(0, getattr(composite_field, scalar_field_name))
- # Finally, ensure that modifications to the old composite field object
- # don't have any effect on the parent.
- #
- # (NOTE that when we clear the composite field in the parent, we actually
- # don't recursively clear down the tree. Instead, we just disconnect the
- # cleared composite from the tree.)
self.assertTrue(old_composite_field is not composite_field)
setattr(old_composite_field, scalar_field_name, new_val)
self.assertTrue(not composite_field.HasField(scalar_field_name))
@@ -319,6 +350,64 @@ class ReflectionTest(unittest.TestCase):
self.assertTrue(not proto.HasField('optional_nested_message'))
self.assertEqual(0, proto.optional_nested_message.bb)
+ def testGetDefaultMessageAfterDisconnectingDefaultMessage(self):
+ proto = unittest_pb2.TestAllTypes()
+ nested = proto.optional_nested_message
+ proto.ClearField('optional_nested_message')
+ del proto
+ del nested
+ # Force a garbage collect so that the underlying CMessages are freed along
+ # with the Messages they point to. This is to make sure we're not deleting
+ # default message instances.
+ gc.collect()
+ proto = unittest_pb2.TestAllTypes()
+ nested = proto.optional_nested_message
+
+ def testDisconnectingNestedMessageAfterSettingField(self):
+ proto = unittest_pb2.TestAllTypes()
+ nested = proto.optional_nested_message
+ nested.bb = 5
+ self.assertTrue(proto.HasField('optional_nested_message'))
+ proto.ClearField('optional_nested_message') # Should disconnect from parent
+ self.assertEqual(5, nested.bb)
+ self.assertEqual(0, proto.optional_nested_message.bb)
+ self.assertTrue(nested is not proto.optional_nested_message)
+ nested.bb = 23
+ self.assertTrue(not proto.HasField('optional_nested_message'))
+ self.assertEqual(0, proto.optional_nested_message.bb)
+
+ def testDisconnectingNestedMessageBeforeGettingField(self):
+ proto = unittest_pb2.TestAllTypes()
+ self.assertTrue(not proto.HasField('optional_nested_message'))
+ proto.ClearField('optional_nested_message')
+ self.assertTrue(not proto.HasField('optional_nested_message'))
+
+ def testDisconnectingNestedMessageAfterMerge(self):
+ # This test exercises the code path that does not use ReleaseMessage().
+ # The underlying fear is that if we use ReleaseMessage() incorrectly,
+ # we will have memory leaks. It's hard to check that that doesn't happen,
+ # but at least we can exercise that code path to make sure it works.
+ proto1 = unittest_pb2.TestAllTypes()
+ proto2 = unittest_pb2.TestAllTypes()
+ proto2.optional_nested_message.bb = 5
+ proto1.MergeFrom(proto2)
+ self.assertTrue(proto1.HasField('optional_nested_message'))
+ proto1.ClearField('optional_nested_message')
+ self.assertTrue(not proto1.HasField('optional_nested_message'))
+
+ def testDisconnectingLazyNestedMessage(self):
+ # This test exercises releasing a nested message that is lazy. This test
+ # only exercises real code in the C++ implementation as Python does not
+ # support lazy parsing, but the current C++ implementation results in
+ # memory corruption and a crash.
+ if api_implementation.Type() != 'python':
+ return
+ proto = unittest_pb2.TestAllTypes()
+ proto.optional_lazy_message.bb = 5
+ proto.ClearField('optional_lazy_message')
+ del proto
+ gc.collect()
+
def testHasBitsWhenModifyingRepeatedFields(self):
# Test nesting when we add an element to a repeated field in a submessage.
proto = unittest_pb2.TestNestedMessageHasBits()
@@ -446,7 +535,7 @@ class ReflectionTest(unittest.TestCase):
self.assertEqual(0.0, proto.optional_double)
self.assertEqual(False, proto.optional_bool)
self.assertEqual('', proto.optional_string)
- self.assertEqual('', proto.optional_bytes)
+ self.assertEqual(b'', proto.optional_bytes)
self.assertEqual(41, proto.default_int32)
self.assertEqual(42, proto.default_int64)
@@ -462,7 +551,7 @@ class ReflectionTest(unittest.TestCase):
self.assertEqual(52e3, proto.default_double)
self.assertEqual(True, proto.default_bool)
self.assertEqual('hello', proto.default_string)
- self.assertEqual('world', proto.default_bytes)
+ self.assertEqual(b'world', proto.default_bytes)
self.assertEqual(unittest_pb2.TestAllTypes.BAR, proto.default_nested_enum)
self.assertEqual(unittest_pb2.FOREIGN_BAR, proto.default_foreign_enum)
self.assertEqual(unittest_import_pb2.IMPORT_BAR,
@@ -479,6 +568,17 @@ class ReflectionTest(unittest.TestCase):
proto = unittest_pb2.TestAllTypes()
self.assertRaises(ValueError, proto.ClearField, 'nonexistent_field')
+ def testClearRemovesChildren(self):
+ # Make sure there aren't any implementation bugs that are only partially
+ # clearing the message (which can happen in the more complex C++
+ # implementation which has parallel message lists).
+ proto = unittest_pb2.TestRequiredForeign()
+ for i in range(10):
+ proto.repeated_message.add()
+ proto2 = unittest_pb2.TestRequiredForeign()
+ proto.CopyFrom(proto2)
+ self.assertRaises(IndexError, lambda: proto.repeated_message[5])
+
def testDisallowedAssignments(self):
# It's illegal to assign values directly to repeated fields
# or to nonrepeated composite fields. Ensure that this fails.
@@ -500,7 +600,6 @@ class ReflectionTest(unittest.TestCase):
# proto.nonexistent_field = 23 should fail as well.
self.assertRaises(AttributeError, setattr, proto, 'nonexistent_field', 23)
- # TODO(robinson): Add type-safety check for enums.
def testSingleScalarTypeSafety(self):
proto = unittest_pb2.TestAllTypes()
self.assertRaises(TypeError, setattr, proto, 'optional_int32', 1.1)
@@ -508,11 +607,37 @@ class ReflectionTest(unittest.TestCase):
self.assertRaises(TypeError, setattr, proto, 'optional_string', 10)
self.assertRaises(TypeError, setattr, proto, 'optional_bytes', 10)
+ def testIntegerTypes(self):
+ def TestGetAndDeserialize(field_name, value, expected_type):
+ proto = unittest_pb2.TestAllTypes()
+ setattr(proto, field_name, value)
+ self.assertTrue(isinstance(getattr(proto, field_name), expected_type))
+ proto2 = unittest_pb2.TestAllTypes()
+ proto2.ParseFromString(proto.SerializeToString())
+ self.assertTrue(isinstance(getattr(proto2, field_name), expected_type))
+
+ TestGetAndDeserialize('optional_int32', 1, int)
+ TestGetAndDeserialize('optional_int32', 1 << 30, int)
+ TestGetAndDeserialize('optional_uint32', 1 << 30, int)
+ if struct.calcsize('L') == 4:
+ # Python only has signed ints, so 32-bit python can't fit an uint32
+ # in an int.
+ TestGetAndDeserialize('optional_uint32', 1 << 31, long)
+ else:
+ # 64-bit python can fit uint32 inside an int
+ TestGetAndDeserialize('optional_uint32', 1 << 31, int)
+ TestGetAndDeserialize('optional_int64', 1 << 30, long)
+ TestGetAndDeserialize('optional_int64', 1 << 60, long)
+ TestGetAndDeserialize('optional_uint64', 1 << 30, long)
+ TestGetAndDeserialize('optional_uint64', 1 << 60, long)
+
def testSingleScalarBoundsChecking(self):
def TestMinAndMaxIntegers(field_name, expected_min, expected_max):
pb = unittest_pb2.TestAllTypes()
setattr(pb, field_name, expected_min)
+ self.assertEqual(expected_min, getattr(pb, field_name))
setattr(pb, field_name, expected_max)
+ self.assertEqual(expected_max, getattr(pb, field_name))
self.assertRaises(ValueError, setattr, pb, field_name, expected_min - 1)
self.assertRaises(ValueError, setattr, pb, field_name, expected_max + 1)
@@ -520,7 +645,10 @@ class ReflectionTest(unittest.TestCase):
TestMinAndMaxIntegers('optional_uint32', 0, 0xffffffff)
TestMinAndMaxIntegers('optional_int64', -(1 << 63), (1 << 63) - 1)
TestMinAndMaxIntegers('optional_uint64', 0, 0xffffffffffffffff)
- TestMinAndMaxIntegers('optional_nested_enum', -(1 << 31), (1 << 31) - 1)
+
+ pb = unittest_pb2.TestAllTypes()
+ pb.optional_nested_enum = 1
+ self.assertEqual(1, pb.optional_nested_enum)
def testRepeatedScalarTypeSafety(self):
proto = unittest_pb2.TestAllTypes()
@@ -534,11 +662,19 @@ class ReflectionTest(unittest.TestCase):
self.assertRaises(IndexError, proto.repeated_int32.__setitem__, 500, 23)
self.assertRaises(TypeError, proto.repeated_int32.__setitem__, 0, 'abc')
+ # Repeated enums tests.
+ #proto.repeated_nested_enum.append(0)
+
def testSingleScalarGettersAndSetters(self):
proto = unittest_pb2.TestAllTypes()
self.assertEqual(0, proto.optional_int32)
proto.optional_int32 = 1
self.assertEqual(1, proto.optional_int32)
+
+ proto.optional_uint64 = 0xffffffffffff
+ self.assertEqual(0xffffffffffff, proto.optional_uint64)
+ proto.optional_uint64 = 0xffffffffffffffff
+ self.assertEqual(0xffffffffffffffff, proto.optional_uint64)
# TODO(robinson): Test all other scalar field types.
def testSingleScalarClearField(self):
@@ -561,6 +697,77 @@ class ReflectionTest(unittest.TestCase):
self.assertEqual(3, proto.BAZ)
self.assertEqual(3, unittest_pb2.TestAllTypes.BAZ)
+ def testEnum_Name(self):
+ self.assertEqual('FOREIGN_FOO',
+ unittest_pb2.ForeignEnum.Name(unittest_pb2.FOREIGN_FOO))
+ self.assertEqual('FOREIGN_BAR',
+ unittest_pb2.ForeignEnum.Name(unittest_pb2.FOREIGN_BAR))
+ self.assertEqual('FOREIGN_BAZ',
+ unittest_pb2.ForeignEnum.Name(unittest_pb2.FOREIGN_BAZ))
+ self.assertRaises(ValueError,
+ unittest_pb2.ForeignEnum.Name, 11312)
+
+ proto = unittest_pb2.TestAllTypes()
+ self.assertEqual('FOO',
+ proto.NestedEnum.Name(proto.FOO))
+ self.assertEqual('FOO',
+ unittest_pb2.TestAllTypes.NestedEnum.Name(proto.FOO))
+ self.assertEqual('BAR',
+ proto.NestedEnum.Name(proto.BAR))
+ self.assertEqual('BAR',
+ unittest_pb2.TestAllTypes.NestedEnum.Name(proto.BAR))
+ self.assertEqual('BAZ',
+ proto.NestedEnum.Name(proto.BAZ))
+ self.assertEqual('BAZ',
+ unittest_pb2.TestAllTypes.NestedEnum.Name(proto.BAZ))
+ self.assertRaises(ValueError,
+ proto.NestedEnum.Name, 11312)
+ self.assertRaises(ValueError,
+ unittest_pb2.TestAllTypes.NestedEnum.Name, 11312)
+
+ def testEnum_Value(self):
+ self.assertEqual(unittest_pb2.FOREIGN_FOO,
+ unittest_pb2.ForeignEnum.Value('FOREIGN_FOO'))
+ self.assertEqual(unittest_pb2.FOREIGN_BAR,
+ unittest_pb2.ForeignEnum.Value('FOREIGN_BAR'))
+ self.assertEqual(unittest_pb2.FOREIGN_BAZ,
+ unittest_pb2.ForeignEnum.Value('FOREIGN_BAZ'))
+ self.assertRaises(ValueError,
+ unittest_pb2.ForeignEnum.Value, 'FO')
+
+ proto = unittest_pb2.TestAllTypes()
+ self.assertEqual(proto.FOO,
+ proto.NestedEnum.Value('FOO'))
+ self.assertEqual(proto.FOO,
+ unittest_pb2.TestAllTypes.NestedEnum.Value('FOO'))
+ self.assertEqual(proto.BAR,
+ proto.NestedEnum.Value('BAR'))
+ self.assertEqual(proto.BAR,
+ unittest_pb2.TestAllTypes.NestedEnum.Value('BAR'))
+ self.assertEqual(proto.BAZ,
+ proto.NestedEnum.Value('BAZ'))
+ self.assertEqual(proto.BAZ,
+ unittest_pb2.TestAllTypes.NestedEnum.Value('BAZ'))
+ self.assertRaises(ValueError,
+ proto.NestedEnum.Value, 'Foo')
+ self.assertRaises(ValueError,
+ unittest_pb2.TestAllTypes.NestedEnum.Value, 'Foo')
+
+ def testEnum_KeysAndValues(self):
+ self.assertEqual(['FOREIGN_FOO', 'FOREIGN_BAR', 'FOREIGN_BAZ'],
+ unittest_pb2.ForeignEnum.keys())
+ self.assertEqual([4, 5, 6],
+ unittest_pb2.ForeignEnum.values())
+ self.assertEqual([('FOREIGN_FOO', 4), ('FOREIGN_BAR', 5),
+ ('FOREIGN_BAZ', 6)],
+ unittest_pb2.ForeignEnum.items())
+
+ proto = unittest_pb2.TestAllTypes()
+ self.assertEqual(['FOO', 'BAR', 'BAZ', 'NEG'], proto.NestedEnum.keys())
+ self.assertEqual([1, 2, 3, -1], proto.NestedEnum.values())
+ self.assertEqual([('FOO', 1), ('BAR', 2), ('BAZ', 3), ('NEG', -1)],
+ proto.NestedEnum.items())
+
def testRepeatedScalars(self):
proto = unittest_pb2.TestAllTypes()
@@ -619,11 +826,38 @@ class ReflectionTest(unittest.TestCase):
del proto.repeated_int32[2:]
self.assertEqual([5, 35], proto.repeated_int32)
+ # Test extending.
+ proto.repeated_int32.extend([3, 13])
+ self.assertEqual([5, 35, 3, 13], proto.repeated_int32)
+
# Test clearing.
proto.ClearField('repeated_int32')
self.assertTrue(not proto.repeated_int32)
self.assertEqual(0, len(proto.repeated_int32))
+ proto.repeated_int32.append(1)
+ self.assertEqual(1, proto.repeated_int32[-1])
+ # Test assignment to a negative index.
+ proto.repeated_int32[-1] = 2
+ self.assertEqual(2, proto.repeated_int32[-1])
+
+ # Test deletion at negative indices.
+ proto.repeated_int32[:] = [0, 1, 2, 3]
+ del proto.repeated_int32[-1]
+ self.assertEqual([0, 1, 2], proto.repeated_int32)
+
+ del proto.repeated_int32[-2]
+ self.assertEqual([0, 2], proto.repeated_int32)
+
+ self.assertRaises(IndexError, proto.repeated_int32.__delitem__, -3)
+ self.assertRaises(IndexError, proto.repeated_int32.__delitem__, 300)
+
+ del proto.repeated_int32[-2:-1]
+ self.assertEqual([2], proto.repeated_int32)
+
+ del proto.repeated_int32[100:10000]
+ self.assertEqual([2], proto.repeated_int32)
+
def testRepeatedScalarsRemove(self):
proto = unittest_pb2.TestAllTypes()
@@ -661,7 +895,7 @@ class ReflectionTest(unittest.TestCase):
m1 = proto.repeated_nested_message.add()
self.assertTrue(proto.repeated_nested_message)
self.assertEqual(2, len(proto.repeated_nested_message))
- self.assertIs([m0, m1], proto.repeated_nested_message)
+ self.assertListsEqual([m0, m1], proto.repeated_nested_message)
self.assertTrue(isinstance(m0, unittest_pb2.TestAllTypes.NestedMessage))
# Test out-of-bounds indices.
@@ -680,32 +914,86 @@ class ReflectionTest(unittest.TestCase):
m2 = proto.repeated_nested_message.add()
m3 = proto.repeated_nested_message.add()
m4 = proto.repeated_nested_message.add()
- self.assertIs([m1, m2, m3], proto.repeated_nested_message[1:4])
- self.assertIs([m0, m1, m2, m3, m4], proto.repeated_nested_message[:])
+ self.assertListsEqual(
+ [m1, m2, m3], proto.repeated_nested_message[1:4])
+ self.assertListsEqual(
+ [m0, m1, m2, m3, m4], proto.repeated_nested_message[:])
+ self.assertListsEqual(
+ [m0, m1], proto.repeated_nested_message[:2])
+ self.assertListsEqual(
+ [m2, m3, m4], proto.repeated_nested_message[2:])
+ self.assertEqual(
+ m0, proto.repeated_nested_message[0])
+ self.assertListsEqual(
+ [m0], proto.repeated_nested_message[:1])
# Test that we can use the field as an iterator.
result = []
for i in proto.repeated_nested_message:
result.append(i)
- self.assertIs([m0, m1, m2, m3, m4], result)
+ self.assertListsEqual([m0, m1, m2, m3, m4], result)
# Test single deletion.
del proto.repeated_nested_message[2]
- self.assertIs([m0, m1, m3, m4], proto.repeated_nested_message)
+ self.assertListsEqual([m0, m1, m3, m4], proto.repeated_nested_message)
# Test slice deletion.
del proto.repeated_nested_message[2:]
- self.assertIs([m0, m1], proto.repeated_nested_message)
+ self.assertListsEqual([m0, m1], proto.repeated_nested_message)
+
+ # Test extending.
+ n1 = unittest_pb2.TestAllTypes.NestedMessage(bb=1)
+ n2 = unittest_pb2.TestAllTypes.NestedMessage(bb=2)
+ proto.repeated_nested_message.extend([n1,n2])
+ self.assertEqual(4, len(proto.repeated_nested_message))
+ self.assertEqual(n1, proto.repeated_nested_message[2])
+ self.assertEqual(n2, proto.repeated_nested_message[3])
# Test clearing.
proto.ClearField('repeated_nested_message')
self.assertTrue(not proto.repeated_nested_message)
self.assertEqual(0, len(proto.repeated_nested_message))
+ # Test constructing an element while adding it.
+ proto.repeated_nested_message.add(bb=23)
+ self.assertEqual(1, len(proto.repeated_nested_message))
+ self.assertEqual(23, proto.repeated_nested_message[0].bb)
+
+ def testRepeatedCompositeRemove(self):
+ proto = unittest_pb2.TestAllTypes()
+
+ self.assertEqual(0, len(proto.repeated_nested_message))
+ m0 = proto.repeated_nested_message.add()
+ # Need to set some differentiating variable so m0 != m1 != m2:
+ m0.bb = len(proto.repeated_nested_message)
+ m1 = proto.repeated_nested_message.add()
+ m1.bb = len(proto.repeated_nested_message)
+ self.assertTrue(m0 != m1)
+ m2 = proto.repeated_nested_message.add()
+ m2.bb = len(proto.repeated_nested_message)
+ self.assertListsEqual([m0, m1, m2], proto.repeated_nested_message)
+
+ self.assertEqual(3, len(proto.repeated_nested_message))
+ proto.repeated_nested_message.remove(m0)
+ self.assertEqual(2, len(proto.repeated_nested_message))
+ self.assertEqual(m1, proto.repeated_nested_message[0])
+ self.assertEqual(m2, proto.repeated_nested_message[1])
+
+ # Removing m0 again or removing None should raise error
+ self.assertRaises(ValueError, proto.repeated_nested_message.remove, m0)
+ self.assertRaises(ValueError, proto.repeated_nested_message.remove, None)
+ self.assertEqual(2, len(proto.repeated_nested_message))
+
+ proto.repeated_nested_message.remove(m2)
+ self.assertEqual(1, len(proto.repeated_nested_message))
+ self.assertEqual(m1, proto.repeated_nested_message[0])
+
def testHandWrittenReflection(self):
- # TODO(robinson): We probably need a better way to specify
- # protocol types by hand. But then again, this isn't something
- # we expect many people to do. Hmm.
+ # Hand written extensions are only supported by the pure-Python
+ # implementation of the API.
+ if api_implementation.Type() != 'python':
+ return
+
FieldDescriptor = descriptor.FieldDescriptor
foo_field_descriptor = FieldDescriptor(
name='foo_field', full_name='MyProto.foo_field',
@@ -730,6 +1018,68 @@ class ReflectionTest(unittest.TestCase):
self.assertEqual(23, myproto_instance.foo_field)
self.assertTrue(myproto_instance.HasField('foo_field'))
+ def testDescriptorProtoSupport(self):
+ # Hand written descriptors/reflection are only supported by the pure-Python
+ # implementation of the API.
+ if api_implementation.Type() != 'python':
+ return
+
+ def AddDescriptorField(proto, field_name, field_type):
+ AddDescriptorField.field_index += 1
+ new_field = proto.field.add()
+ new_field.name = field_name
+ new_field.type = field_type
+ new_field.number = AddDescriptorField.field_index
+ new_field.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL
+
+ AddDescriptorField.field_index = 0
+
+ desc_proto = descriptor_pb2.DescriptorProto()
+ desc_proto.name = 'Car'
+ fdp = descriptor_pb2.FieldDescriptorProto
+ AddDescriptorField(desc_proto, 'name', fdp.TYPE_STRING)
+ AddDescriptorField(desc_proto, 'year', fdp.TYPE_INT64)
+ AddDescriptorField(desc_proto, 'automatic', fdp.TYPE_BOOL)
+ AddDescriptorField(desc_proto, 'price', fdp.TYPE_DOUBLE)
+ # Add a repeated field
+ AddDescriptorField.field_index += 1
+ new_field = desc_proto.field.add()
+ new_field.name = 'owners'
+ new_field.type = fdp.TYPE_STRING
+ new_field.number = AddDescriptorField.field_index
+ new_field.label = descriptor_pb2.FieldDescriptorProto.LABEL_REPEATED
+
+ desc = descriptor.MakeDescriptor(desc_proto)
+ self.assertTrue(desc.fields_by_name.has_key('name'))
+ self.assertTrue(desc.fields_by_name.has_key('year'))
+ self.assertTrue(desc.fields_by_name.has_key('automatic'))
+ self.assertTrue(desc.fields_by_name.has_key('price'))
+ self.assertTrue(desc.fields_by_name.has_key('owners'))
+
+ class CarMessage(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = desc
+
+ prius = CarMessage()
+ prius.name = 'prius'
+ prius.year = 2010
+ prius.automatic = True
+ prius.price = 25134.75
+ prius.owners.extend(['bob', 'susan'])
+
+ serialized_prius = prius.SerializeToString()
+ new_prius = reflection.ParseMessage(desc, serialized_prius)
+ self.assertTrue(new_prius is not prius)
+ self.assertEqual(prius, new_prius)
+
+ # these are unnecessary assuming message equality works as advertised but
+ # explicitly check to be safe since we're mucking about in metaclass foo
+ self.assertEqual(prius.name, new_prius.name)
+ self.assertEqual(prius.year, new_prius.year)
+ self.assertEqual(prius.automatic, new_prius.automatic)
+ self.assertEqual(prius.price, new_prius.price)
+ self.assertEqual(prius.owners, new_prius.owners)
+
def testTopLevelExtensionsForOptionalScalar(self):
extendee_proto = unittest_pb2.TestAllExtensions()
extension = unittest_pb2.optional_int32_extension
@@ -819,6 +1169,14 @@ class ReflectionTest(unittest.TestCase):
self.assertTrue(required is not extendee_proto.Extensions[extension])
self.assertTrue(not extendee_proto.HasExtension(extension))
+ def testRegisteredExtensions(self):
+ self.assertTrue('protobuf_unittest.optional_int32_extension' in
+ unittest_pb2.TestAllExtensions._extensions_by_name)
+ self.assertTrue(1 in unittest_pb2.TestAllExtensions._extensions_by_number)
+ # Make sure extensions haven't been registered into types that shouldn't
+ # have any.
+ self.assertEquals(0, len(unittest_pb2.TestAllTypes._extensions_by_name))
+
# If message A directly contains message B, and
# a.HasField('b') is currently False, then mutating any
# extension in B should change a.HasField('b') to True
@@ -868,7 +1226,7 @@ class ReflectionTest(unittest.TestCase):
self.assertTrue(not toplevel.HasField('submessage'))
foreign = toplevel.submessage.Extensions[
more_extensions_pb2.repeated_message_extension].add()
- self.assertTrue(foreign is toplevel.submessage.Extensions[
+ self.assertEqual(foreign, toplevel.submessage.Extensions[
more_extensions_pb2.repeated_message_extension][0])
self.assertTrue(toplevel.HasField('submessage'))
@@ -971,6 +1329,12 @@ class ReflectionTest(unittest.TestCase):
self.assertEqual(123, proto2.repeated_nested_message[1].bb)
self.assertEqual(321, proto2.repeated_nested_message[2].bb)
+ proto3 = unittest_pb2.TestAllTypes()
+ proto3.repeated_nested_message.MergeFrom(proto2.repeated_nested_message)
+ self.assertEqual(999, proto3.repeated_nested_message[0].bb)
+ self.assertEqual(123, proto3.repeated_nested_message[1].bb)
+ self.assertEqual(321, proto3.repeated_nested_message[2].bb)
+
def testMergeFromAllFields(self):
# With all fields set.
proto1 = unittest_pb2.TestAllTypes()
@@ -1035,6 +1399,19 @@ class ReflectionTest(unittest.TestCase):
self.assertEqual(222, ext2[1].bb)
self.assertEqual(333, ext2[2].bb)
+ def testMergeFromBug(self):
+ message1 = unittest_pb2.TestAllTypes()
+ message2 = unittest_pb2.TestAllTypes()
+
+ # Cause optional_nested_message to be instantiated within message1, even
+ # though it is not considered to be "present".
+ message1.optional_nested_message
+ self.assertFalse(message1.HasField('optional_nested_message'))
+
+ # Merge into message2. This should not instantiate the field is message2.
+ message2.MergeFrom(message1)
+ self.assertFalse(message2.HasField('optional_nested_message'))
+
def testCopyFromSingularField(self):
# Test copy with just a singular field.
proto1 = unittest_pb2.TestAllTypes()
@@ -1087,9 +1464,36 @@ class ReflectionTest(unittest.TestCase):
self.assertEqual(2, proto1.optional_int32)
self.assertEqual('important-text', proto1.optional_string)
+ def testCopyFromBadType(self):
+ # The python implementation doesn't raise an exception in this
+ # case. In theory it should.
+ if api_implementation.Type() == 'python':
+ return
+ proto1 = unittest_pb2.TestAllTypes()
+ proto2 = unittest_pb2.TestAllExtensions()
+ self.assertRaises(TypeError, proto1.CopyFrom, proto2)
+
+ def testDeepCopy(self):
+ proto1 = unittest_pb2.TestAllTypes()
+ proto1.optional_int32 = 1
+ proto2 = copy.deepcopy(proto1)
+ self.assertEqual(1, proto2.optional_int32)
+
+ proto1.repeated_int32.append(2)
+ proto1.repeated_int32.append(3)
+ container = copy.deepcopy(proto1.repeated_int32)
+ self.assertEqual([2, 3], container)
+
+ # TODO(anuraag): Implement deepcopy for repeated composite / extension dict
+
def testClear(self):
proto = unittest_pb2.TestAllTypes()
- test_util.SetAllFields(proto)
+ # C++ implementation does not support lazy fields right now so leave it
+ # out for now.
+ if api_implementation.Type() == 'python':
+ test_util.SetAllFields(proto)
+ else:
+ test_util.SetAllNonLazyFields(proto)
# Clear the message.
proto.Clear()
self.assertEquals(proto.ByteSize(), 0)
@@ -1105,6 +1509,45 @@ class ReflectionTest(unittest.TestCase):
empty_proto = unittest_pb2.TestAllExtensions()
self.assertEquals(proto, empty_proto)
+ def testDisconnectingBeforeClear(self):
+ proto = unittest_pb2.TestAllTypes()
+ nested = proto.optional_nested_message
+ proto.Clear()
+ self.assertTrue(nested is not proto.optional_nested_message)
+ nested.bb = 23
+ self.assertTrue(not proto.HasField('optional_nested_message'))
+ self.assertEqual(0, proto.optional_nested_message.bb)
+
+ proto = unittest_pb2.TestAllTypes()
+ nested = proto.optional_nested_message
+ nested.bb = 5
+ foreign = proto.optional_foreign_message
+ foreign.c = 6
+
+ proto.Clear()
+ self.assertTrue(nested is not proto.optional_nested_message)
+ self.assertTrue(foreign is not proto.optional_foreign_message)
+ self.assertEqual(5, nested.bb)
+ self.assertEqual(6, foreign.c)
+ nested.bb = 15
+ foreign.c = 16
+ self.assertFalse(proto.HasField('optional_nested_message'))
+ self.assertEqual(0, proto.optional_nested_message.bb)
+ self.assertFalse(proto.HasField('optional_foreign_message'))
+ self.assertEqual(0, proto.optional_foreign_message.c)
+
+ def testOneOf(self):
+ proto = unittest_pb2.TestAllTypes()
+ proto.oneof_uint32 = 10
+ proto.oneof_nested_message.bb = 11
+ self.assertEqual(11, proto.oneof_nested_message.bb)
+ self.assertFalse(proto.HasField('oneof_uint32'))
+ nested = proto.oneof_nested_message
+ proto.oneof_string = 'abc'
+ self.assertEqual('abc', proto.oneof_string)
+ self.assertEqual(11, nested.bb)
+ self.assertFalse(proto.HasField('oneof_nested_message'))
+
def assertInitialized(self, proto):
self.assertTrue(proto.IsInitialized())
# Neither method should raise an exception.
@@ -1175,6 +1618,40 @@ class ReflectionTest(unittest.TestCase):
self.assertFalse(proto.IsInitialized(errors))
self.assertEqual(errors, ['a', 'b', 'c'])
+ @basetest.unittest.skipIf(
+ api_implementation.Type() != 'cpp' or api_implementation.Version() != 2,
+ 'Errors are only available from the most recent C++ implementation.')
+ def testFileDescriptorErrors(self):
+ file_name = 'test_file_descriptor_errors.proto'
+ package_name = 'test_file_descriptor_errors.proto'
+ file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
+ file_descriptor_proto.name = file_name
+ file_descriptor_proto.package = package_name
+ m1 = file_descriptor_proto.message_type.add()
+ m1.name = 'msg1'
+ # Compiles the proto into the C++ descriptor pool
+ descriptor.FileDescriptor(
+ file_name,
+ package_name,
+ serialized_pb=file_descriptor_proto.SerializeToString())
+ # Add a FileDescriptorProto that has duplicate symbols
+ another_file_name = 'another_test_file_descriptor_errors.proto'
+ file_descriptor_proto.name = another_file_name
+ m2 = file_descriptor_proto.message_type.add()
+ m2.name = 'msg2'
+ with self.assertRaises(TypeError) as cm:
+ descriptor.FileDescriptor(
+ another_file_name,
+ package_name,
+ serialized_pb=file_descriptor_proto.SerializeToString())
+ self.assertTrue(hasattr(cm, 'exception'), '%s not raised' %
+ getattr(cm.expected, '__name__', cm.expected))
+ self.assertIn('test_file_descriptor_errors.proto', str(cm.exception))
+ # Error message will say something about this definition being a
+ # duplicate, though we don't check the message exactly to avoid a
+ # dependency on the C++ logging code.
+ self.assertIn('test_file_descriptor_errors.msg1', str(cm.exception))
+
def testStringUTF8Encoding(self):
proto = unittest_pb2.TestAllTypes()
@@ -1192,16 +1669,15 @@ class ReflectionTest(unittest.TestCase):
proto.optional_string = str('Testing')
self.assertEqual(proto.optional_string, unicode('Testing'))
- # Values of type 'str' are also accepted as long as they can be encoded in
- # UTF-8.
- self.assertEqual(type(proto.optional_string), str)
-
# Try to assign a 'str' value which contains bytes that aren't 7-bit ASCII.
self.assertRaises(ValueError,
- setattr, proto, 'optional_string', str('a\x80a'))
- # Assign a 'str' object which contains a UTF-8 encoded string.
- self.assertRaises(ValueError,
- setattr, proto, 'optional_string', 'Тест')
+ setattr, proto, 'optional_string', b'a\x80a')
+ if str is bytes: # PY2
+ # Assign a 'str' object which contains a UTF-8 encoded string.
+ self.assertRaises(ValueError,
+ setattr, proto, 'optional_string', 'Тест')
+ else:
+ proto.optional_string = 'Тест'
# No exception thrown.
proto.optional_string = 'abc'
@@ -1224,7 +1700,8 @@ class ReflectionTest(unittest.TestCase):
self.assertEqual(proto.ByteSize(), len(serialized))
raw = unittest_mset_pb2.RawMessageSet()
- raw.MergeFromString(serialized)
+ bytes_read = raw.MergeFromString(serialized)
+ self.assertEqual(len(serialized), bytes_read)
message2 = unittest_mset_pb2.TestMessageSetExtension2()
@@ -1232,18 +1709,37 @@ class ReflectionTest(unittest.TestCase):
# Check that the type_id is the same as the tag ID in the .proto file.
self.assertEqual(raw.item[0].type_id, 1547769)
- # Check the actually bytes on the wire.
+ # Check the actual bytes on the wire.
self.assertTrue(
raw.item[0].message.endswith(test_utf8_bytes))
- message2.MergeFromString(raw.item[0].message)
+ bytes_read = message2.MergeFromString(raw.item[0].message)
+ self.assertEqual(len(raw.item[0].message), bytes_read)
self.assertEqual(type(message2.str), unicode)
self.assertEqual(message2.str, test_utf8)
- # How about if the bytes on the wire aren't a valid UTF-8 encoded string.
- bytes = raw.item[0].message.replace(
- test_utf8_bytes, len(test_utf8_bytes) * '\xff')
- self.assertRaises(UnicodeDecodeError, message2.MergeFromString, bytes)
+ # The pure Python API throws an exception on MergeFromString(),
+ # if any of the string fields of the message can't be UTF-8 decoded.
+ # The C++ implementation of the API has no way to check that on
+ # MergeFromString and thus has no way to throw the exception.
+ #
+ # The pure Python API always returns objects of type 'unicode' (UTF-8
+ # encoded), or 'bytes' (in 7 bit ASCII).
+ badbytes = raw.item[0].message.replace(
+ test_utf8_bytes, len(test_utf8_bytes) * b'\xff')
+
+ unicode_decode_failed = False
+ try:
+ message2.MergeFromString(badbytes)
+ except UnicodeDecodeError:
+ unicode_decode_failed = True
+ string_field = message2.str
+ self.assertTrue(unicode_decode_failed or type(string_field) is bytes)
+
+ def testBytesInTextFormat(self):
+ proto = unittest_pb2.TestAllTypes(optional_bytes=b'\x00\x7f\x80\xff')
+ self.assertEqual(u'optional_bytes: "\\000\\177\\200\\377"\n',
+ unicode(proto))
def testEmptyNestedMessage(self):
proto = unittest_pb2.TestAllTypes()
@@ -1257,16 +1753,19 @@ class ReflectionTest(unittest.TestCase):
self.assertTrue(proto.HasField('optional_nested_message'))
proto = unittest_pb2.TestAllTypes()
- proto.optional_nested_message.MergeFromString('')
+ bytes_read = proto.optional_nested_message.MergeFromString(b'')
+ self.assertEqual(0, bytes_read)
self.assertTrue(proto.HasField('optional_nested_message'))
proto = unittest_pb2.TestAllTypes()
- proto.optional_nested_message.ParseFromString('')
+ proto.optional_nested_message.ParseFromString(b'')
self.assertTrue(proto.HasField('optional_nested_message'))
serialized = proto.SerializeToString()
proto2 = unittest_pb2.TestAllTypes()
- proto2.MergeFromString(serialized)
+ self.assertEqual(
+ len(serialized),
+ proto2.MergeFromString(serialized))
self.assertTrue(proto2.HasField('optional_nested_message'))
def testSetInParent(self):
@@ -1280,12 +1779,15 @@ class ReflectionTest(unittest.TestCase):
# into separate TestCase classes.
-class TestAllTypesEqualityTest(unittest.TestCase):
+class TestAllTypesEqualityTest(basetest.TestCase):
def setUp(self):
self.first_proto = unittest_pb2.TestAllTypes()
self.second_proto = unittest_pb2.TestAllTypes()
+ def testNotHashable(self):
+ self.assertRaises(TypeError, hash, self.first_proto)
+
def testSelfEquality(self):
self.assertEqual(self.first_proto, self.first_proto)
@@ -1293,7 +1795,7 @@ class TestAllTypesEqualityTest(unittest.TestCase):
self.assertEqual(self.first_proto, self.second_proto)
-class FullProtosEqualityTest(unittest.TestCase):
+class FullProtosEqualityTest(basetest.TestCase):
"""Equality tests using completely-full protos as a starting point."""
@@ -1303,6 +1805,9 @@ class FullProtosEqualityTest(unittest.TestCase):
test_util.SetAllFields(self.first_proto)
test_util.SetAllFields(self.second_proto)
+ def testNotHashable(self):
+ self.assertRaises(TypeError, hash, self.first_proto)
+
def testNoneNotEqual(self):
self.assertNotEqual(self.first_proto, None)
self.assertNotEqual(None, self.second_proto)
@@ -1371,15 +1876,12 @@ class FullProtosEqualityTest(unittest.TestCase):
self.first_proto.ClearField('optional_nested_message')
self.second_proto.optional_nested_message.ClearField('bb')
self.assertNotEqual(self.first_proto, self.second_proto)
- # TODO(robinson): Replace next two lines with method
- # to set the "has" bit without changing the value,
- # if/when such a method exists.
self.first_proto.optional_nested_message.bb = 0
self.first_proto.optional_nested_message.ClearField('bb')
self.assertEqual(self.first_proto, self.second_proto)
-class ExtensionEqualityTest(unittest.TestCase):
+class ExtensionEqualityTest(basetest.TestCase):
def testExtensionEquality(self):
first_proto = unittest_pb2.TestAllExtensions()
@@ -1412,7 +1914,7 @@ class ExtensionEqualityTest(unittest.TestCase):
self.assertEqual(first_proto, second_proto)
-class MutualRecursionEqualityTest(unittest.TestCase):
+class MutualRecursionEqualityTest(basetest.TestCase):
def testEqualityWithMutualRecursion(self):
first_proto = unittest_pb2.TestMutualRecursionA()
@@ -1424,7 +1926,7 @@ class MutualRecursionEqualityTest(unittest.TestCase):
self.assertEqual(first_proto, second_proto)
-class ByteSizeTest(unittest.TestCase):
+class ByteSizeTest(basetest.TestCase):
def setUp(self):
self.proto = unittest_pb2.TestAllTypes()
@@ -1438,6 +1940,14 @@ class ByteSizeTest(unittest.TestCase):
def testEmptyMessage(self):
self.assertEqual(0, self.proto.ByteSize())
+ def testSizedOnKwargs(self):
+ # Use a separate message to ensure testing right after creation.
+ proto = unittest_pb2.TestAllTypes()
+ self.assertEqual(0, proto.ByteSize())
+ proto_kwargs = unittest_pb2.TestAllTypes(optional_int64 = 1)
+ # One byte for the tag, one to encode varint 1.
+ self.assertEqual(2, proto_kwargs.ByteSize())
+
def testVarints(self):
def Test(i, expected_varint_size):
self.proto.Clear()
@@ -1629,10 +2139,13 @@ class ByteSizeTest(unittest.TestCase):
self.assertEqual(3, self.proto.ByteSize())
self.proto.ClearField('optional_foreign_message')
self.assertEqual(0, self.proto.ByteSize())
- child = self.proto.optional_foreign_message
- self.proto.ClearField('optional_foreign_message')
- child.c = 128
- self.assertEqual(0, self.proto.ByteSize())
+
+ if api_implementation.Type() == 'python':
+ # This is only possible in pure-Python implementation of the API.
+ child = self.proto.optional_foreign_message
+ self.proto.ClearField('optional_foreign_message')
+ child.c = 128
+ self.assertEqual(0, self.proto.ByteSize())
# Test within extension.
extension = more_extensions_pb2.optional_message_extension
@@ -1698,7 +2211,6 @@ class ByteSizeTest(unittest.TestCase):
self.assertEqual(19, self.packed_extended_proto.ByteSize())
-# TODO(robinson): We need cross-language serialization consistency tests.
# Issues to be sure to cover include:
# * Handling of unrecognized tags ("uninterpreted_bytes").
# * Handling of MessageSets.
@@ -1710,14 +2222,16 @@ class ByteSizeTest(unittest.TestCase):
# * Handling of empty submessages (with and without "has"
# bits set).
-class SerializationTest(unittest.TestCase):
+class SerializationTest(basetest.TestCase):
def testSerializeEmtpyMessage(self):
first_proto = unittest_pb2.TestAllTypes()
second_proto = unittest_pb2.TestAllTypes()
serialized = first_proto.SerializeToString()
self.assertEqual(first_proto.ByteSize(), len(serialized))
- second_proto.MergeFromString(serialized)
+ self.assertEqual(
+ len(serialized),
+ second_proto.MergeFromString(serialized))
self.assertEqual(first_proto, second_proto)
def testSerializeAllFields(self):
@@ -1726,7 +2240,9 @@ class SerializationTest(unittest.TestCase):
test_util.SetAllFields(first_proto)
serialized = first_proto.SerializeToString()
self.assertEqual(first_proto.ByteSize(), len(serialized))
- second_proto.MergeFromString(serialized)
+ self.assertEqual(
+ len(serialized),
+ second_proto.MergeFromString(serialized))
self.assertEqual(first_proto, second_proto)
def testSerializeAllExtensions(self):
@@ -1734,7 +2250,19 @@ class SerializationTest(unittest.TestCase):
second_proto = unittest_pb2.TestAllExtensions()
test_util.SetAllExtensions(first_proto)
serialized = first_proto.SerializeToString()
- second_proto.MergeFromString(serialized)
+ self.assertEqual(
+ len(serialized),
+ second_proto.MergeFromString(serialized))
+ self.assertEqual(first_proto, second_proto)
+
+ def testSerializeWithOptionalGroup(self):
+ first_proto = unittest_pb2.TestAllTypes()
+ second_proto = unittest_pb2.TestAllTypes()
+ first_proto.optionalgroup.a = 242
+ serialized = first_proto.SerializeToString()
+ self.assertEqual(
+ len(serialized),
+ second_proto.MergeFromString(serialized))
self.assertEqual(first_proto, second_proto)
def testSerializeNegativeValues(self):
@@ -1753,6 +2281,10 @@ class SerializationTest(unittest.TestCase):
self.assertEqual(first_proto, second_proto)
def testParseTruncated(self):
+ # This test is only applicable for the Python implementation of the API.
+ if api_implementation.Type() != 'python':
+ return
+
first_proto = unittest_pb2.TestAllTypes()
test_util.SetAllFields(first_proto)
serialized = first_proto.SerializeToString()
@@ -1822,7 +2354,9 @@ class SerializationTest(unittest.TestCase):
second_proto.optional_int32 = 100
second_proto.optional_nested_message.bb = 999
- second_proto.MergeFromString(serialized)
+ bytes_parsed = second_proto.MergeFromString(serialized)
+ self.assertEqual(len(serialized), bytes_parsed)
+
# Ensure that we append to repeated fields.
self.assertEqual(['baz', 'foobar'], list(second_proto.repeated_string))
# Ensure that we overwrite nonrepeatd scalars.
@@ -1847,20 +2381,28 @@ class SerializationTest(unittest.TestCase):
raw = unittest_mset_pb2.RawMessageSet()
self.assertEqual(False,
raw.DESCRIPTOR.GetOptions().message_set_wire_format)
- raw.MergeFromString(serialized)
+ self.assertEqual(
+ len(serialized),
+ raw.MergeFromString(serialized))
self.assertEqual(2, len(raw.item))
message1 = unittest_mset_pb2.TestMessageSetExtension1()
- message1.MergeFromString(raw.item[0].message)
+ self.assertEqual(
+ len(raw.item[0].message),
+ message1.MergeFromString(raw.item[0].message))
self.assertEqual(123, message1.i)
message2 = unittest_mset_pb2.TestMessageSetExtension2()
- message2.MergeFromString(raw.item[1].message)
+ self.assertEqual(
+ len(raw.item[1].message),
+ message2.MergeFromString(raw.item[1].message))
self.assertEqual('foo', message2.str)
# Deserialize using the MessageSet wire format.
proto2 = unittest_mset_pb2.TestMessageSet()
- proto2.MergeFromString(serialized)
+ self.assertEqual(
+ len(serialized),
+ proto2.MergeFromString(serialized))
self.assertEqual(123, proto2.Extensions[extension1].i)
self.assertEqual('foo', proto2.Extensions[extension2].str)
@@ -1900,7 +2442,9 @@ class SerializationTest(unittest.TestCase):
# Parse message using the message set wire format.
proto = unittest_mset_pb2.TestMessageSet()
- proto.MergeFromString(serialized)
+ self.assertEqual(
+ len(serialized),
+ proto.MergeFromString(serialized))
# Check that the message parsed well.
extension_message1 = unittest_mset_pb2.TestMessageSetExtension1
@@ -1918,7 +2462,9 @@ class SerializationTest(unittest.TestCase):
proto2 = unittest_pb2.TestEmptyMessage()
# Parsing this message should succeed.
- proto2.MergeFromString(serialized)
+ self.assertEqual(
+ len(serialized),
+ proto2.MergeFromString(serialized))
# Now test with a int64 field set.
proto = unittest_pb2.TestAllTypes()
@@ -1928,13 +2474,15 @@ class SerializationTest(unittest.TestCase):
# unknown.
proto2 = unittest_pb2.TestEmptyMessage()
# Parsing this message should succeed.
- proto2.MergeFromString(serialized)
+ self.assertEqual(
+ len(serialized),
+ proto2.MergeFromString(serialized))
def _CheckRaises(self, exc_class, callable_obj, exception):
"""This method checks if the excpetion type and message are as expected."""
try:
callable_obj()
- except exc_class, ex:
+ except exc_class as ex:
# Check if the exception message is the right one.
self.assertEqual(exception, str(ex))
return
@@ -1946,15 +2494,22 @@ class SerializationTest(unittest.TestCase):
self._CheckRaises(
message.EncodeError,
proto.SerializeToString,
- 'Message is missing required fields: a,b,c')
+ 'Message protobuf_unittest.TestRequired is missing required fields: '
+ 'a,b,c')
# Shouldn't raise exceptions.
partial = proto.SerializePartialToString()
+ proto2 = unittest_pb2.TestRequired()
+ self.assertFalse(proto2.HasField('a'))
+ # proto2 ParseFromString does not check that required fields are set.
+ proto2.ParseFromString(partial)
+ self.assertFalse(proto2.HasField('a'))
+
proto.a = 1
self._CheckRaises(
message.EncodeError,
proto.SerializeToString,
- 'Message is missing required fields: b,c')
+ 'Message protobuf_unittest.TestRequired is missing required fields: b,c')
# Shouldn't raise exceptions.
partial = proto.SerializePartialToString()
@@ -1962,7 +2517,7 @@ class SerializationTest(unittest.TestCase):
self._CheckRaises(
message.EncodeError,
proto.SerializeToString,
- 'Message is missing required fields: c')
+ 'Message protobuf_unittest.TestRequired is missing required fields: c')
# Shouldn't raise exceptions.
partial = proto.SerializePartialToString()
@@ -1972,11 +2527,15 @@ class SerializationTest(unittest.TestCase):
partial = proto.SerializePartialToString()
proto2 = unittest_pb2.TestRequired()
- proto2.MergeFromString(serialized)
+ self.assertEqual(
+ len(serialized),
+ proto2.MergeFromString(serialized))
self.assertEqual(1, proto2.a)
self.assertEqual(2, proto2.b)
self.assertEqual(3, proto2.c)
- proto2.ParseFromString(partial)
+ self.assertEqual(
+ len(partial),
+ proto2.MergeFromString(partial))
self.assertEqual(1, proto2.a)
self.assertEqual(2, proto2.b)
self.assertEqual(3, proto2.c)
@@ -1991,7 +2550,8 @@ class SerializationTest(unittest.TestCase):
self._CheckRaises(
message.EncodeError,
proto.SerializeToString,
- 'Message is missing required fields: '
+ 'Message protobuf_unittest.TestRequiredForeign '
+ 'is missing required fields: '
'optional_message.b,optional_message.c')
proto.optional_message.b = 2
@@ -2003,7 +2563,7 @@ class SerializationTest(unittest.TestCase):
self._CheckRaises(
message.EncodeError,
proto.SerializeToString,
- 'Message is missing required fields: '
+ 'Message protobuf_unittest.TestRequiredForeign is missing required fields: '
'repeated_message[0].b,repeated_message[0].c,'
'repeated_message[1].a,repeated_message[1].c')
@@ -2043,7 +2603,9 @@ class SerializationTest(unittest.TestCase):
second_proto.packed_double.extend([1.0, 2.0])
second_proto.packed_sint32.append(4)
- second_proto.MergeFromString(serialized)
+ self.assertEqual(
+ len(serialized),
+ second_proto.MergeFromString(serialized))
self.assertEqual([3, 1, 2], second_proto.packed_int32)
self.assertEqual([1.0, 2.0, 3.0], second_proto.packed_double)
self.assertEqual([4], second_proto.packed_sint32)
@@ -2076,7 +2638,10 @@ class SerializationTest(unittest.TestCase):
unpacked = unittest_pb2.TestUnpackedTypes()
test_util.SetAllUnpackedFields(unpacked)
packed = unittest_pb2.TestPackedTypes()
- packed.MergeFromString(unpacked.SerializeToString())
+ serialized = unpacked.SerializeToString()
+ self.assertEqual(
+ len(serialized),
+ packed.MergeFromString(serialized))
expected = unittest_pb2.TestPackedTypes()
test_util.SetAllPackedFields(expected)
self.assertEqual(expected, packed)
@@ -2085,7 +2650,10 @@ class SerializationTest(unittest.TestCase):
packed = unittest_pb2.TestPackedTypes()
test_util.SetAllPackedFields(packed)
unpacked = unittest_pb2.TestUnpackedTypes()
- unpacked.MergeFromString(packed.SerializeToString())
+ serialized = packed.SerializeToString()
+ self.assertEqual(
+ len(serialized),
+ unpacked.MergeFromString(serialized))
expected = unittest_pb2.TestUnpackedTypes()
test_util.SetAllUnpackedFields(expected)
self.assertEqual(expected, unpacked)
@@ -2137,7 +2705,7 @@ class SerializationTest(unittest.TestCase):
optional_int32=1,
optional_string='foo',
optional_bool=True,
- optional_bytes='bar',
+ optional_bytes=b'bar',
optional_nested_message=unittest_pb2.TestAllTypes.NestedMessage(bb=1),
optional_foreign_message=unittest_pb2.ForeignMessage(c=1),
optional_nested_enum=unittest_pb2.TestAllTypes.FOO,
@@ -2155,7 +2723,7 @@ class SerializationTest(unittest.TestCase):
self.assertEqual(1, proto.optional_int32)
self.assertEqual('foo', proto.optional_string)
self.assertEqual(True, proto.optional_bool)
- self.assertEqual('bar', proto.optional_bytes)
+ self.assertEqual(b'bar', proto.optional_bytes)
self.assertEqual(1, proto.optional_nested_message.bb)
self.assertEqual(1, proto.optional_foreign_message.c)
self.assertEqual(unittest_pb2.TestAllTypes.FOO,
@@ -2205,7 +2773,7 @@ class SerializationTest(unittest.TestCase):
self.assertEqual(3, proto.repeated_int32[2])
-class OptionsTest(unittest.TestCase):
+class OptionsTest(basetest.TestCase):
def testMessageOptions(self):
proto = unittest_mset_pb2.TestMessageSet()
@@ -2232,5 +2800,135 @@ class OptionsTest(unittest.TestCase):
+class ClassAPITest(basetest.TestCase):
+
+ def testMakeClassWithNestedDescriptor(self):
+ leaf_desc = descriptor.Descriptor('leaf', 'package.parent.child.leaf', '',
+ containing_type=None, fields=[],
+ nested_types=[], enum_types=[],
+ extensions=[])
+ child_desc = descriptor.Descriptor('child', 'package.parent.child', '',
+ containing_type=None, fields=[],
+ nested_types=[leaf_desc], enum_types=[],
+ extensions=[])
+ sibling_desc = descriptor.Descriptor('sibling', 'package.parent.sibling',
+ '', containing_type=None, fields=[],
+ nested_types=[], enum_types=[],
+ extensions=[])
+ parent_desc = descriptor.Descriptor('parent', 'package.parent', '',
+ containing_type=None, fields=[],
+ nested_types=[child_desc, sibling_desc],
+ enum_types=[], extensions=[])
+ message_class = reflection.MakeClass(parent_desc)
+ self.assertIn('child', message_class.__dict__)
+ self.assertIn('sibling', message_class.__dict__)
+ self.assertIn('leaf', message_class.child.__dict__)
+
+ def _GetSerializedFileDescriptor(self, name):
+ """Get a serialized representation of a test FileDescriptorProto.
+
+ Args:
+ name: All calls to this must use a unique message name, to avoid
+ collisions in the cpp descriptor pool.
+ Returns:
+ A string containing the serialized form of a test FileDescriptorProto.
+ """
+ file_descriptor_str = (
+ 'message_type {'
+ ' name: "' + name + '"'
+ ' field {'
+ ' name: "flat"'
+ ' number: 1'
+ ' label: LABEL_REPEATED'
+ ' type: TYPE_UINT32'
+ ' }'
+ ' field {'
+ ' name: "bar"'
+ ' number: 2'
+ ' label: LABEL_OPTIONAL'
+ ' type: TYPE_MESSAGE'
+ ' type_name: "Bar"'
+ ' }'
+ ' nested_type {'
+ ' name: "Bar"'
+ ' field {'
+ ' name: "baz"'
+ ' number: 3'
+ ' label: LABEL_OPTIONAL'
+ ' type: TYPE_MESSAGE'
+ ' type_name: "Baz"'
+ ' }'
+ ' nested_type {'
+ ' name: "Baz"'
+ ' enum_type {'
+ ' name: "deep_enum"'
+ ' value {'
+ ' name: "VALUE_A"'
+ ' number: 0'
+ ' }'
+ ' }'
+ ' field {'
+ ' name: "deep"'
+ ' number: 4'
+ ' label: LABEL_OPTIONAL'
+ ' type: TYPE_UINT32'
+ ' }'
+ ' }'
+ ' }'
+ '}')
+ file_descriptor = descriptor_pb2.FileDescriptorProto()
+ text_format.Merge(file_descriptor_str, file_descriptor)
+ return file_descriptor.SerializeToString()
+
+ def testParsingFlatClassWithExplicitClassDeclaration(self):
+ """Test that the generated class can parse a flat message."""
+ file_descriptor = descriptor_pb2.FileDescriptorProto()
+ file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('A'))
+ msg_descriptor = descriptor.MakeDescriptor(
+ file_descriptor.message_type[0])
+
+ class MessageClass(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = msg_descriptor
+ msg = MessageClass()
+ msg_str = (
+ 'flat: 0 '
+ 'flat: 1 '
+ 'flat: 2 ')
+ text_format.Merge(msg_str, msg)
+ self.assertEqual(msg.flat, [0, 1, 2])
+
+ def testParsingFlatClass(self):
+ """Test that the generated class can parse a flat message."""
+ file_descriptor = descriptor_pb2.FileDescriptorProto()
+ file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('B'))
+ msg_descriptor = descriptor.MakeDescriptor(
+ file_descriptor.message_type[0])
+ msg_class = reflection.MakeClass(msg_descriptor)
+ msg = msg_class()
+ msg_str = (
+ 'flat: 0 '
+ 'flat: 1 '
+ 'flat: 2 ')
+ text_format.Merge(msg_str, msg)
+ self.assertEqual(msg.flat, [0, 1, 2])
+
+ def testParsingNestedClass(self):
+ """Test that the generated class can parse a nested message."""
+ file_descriptor = descriptor_pb2.FileDescriptorProto()
+ file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('C'))
+ msg_descriptor = descriptor.MakeDescriptor(
+ file_descriptor.message_type[0])
+ msg_class = reflection.MakeClass(msg_descriptor)
+ msg = msg_class()
+ msg_str = (
+ 'bar {'
+ ' baz {'
+ ' deep: 4'
+ ' }'
+ '}')
+ text_format.Merge(msg_str, msg)
+ self.assertEqual(msg.bar.baz.deep, 4)
+
if __name__ == '__main__':
- unittest.main()
+ basetest.main()
diff --git a/python/google/protobuf/internal/service_reflection_test.py b/python/google/protobuf/internal/service_reflection_test.py
index e04f825..07dcf44 100755
--- a/python/google/protobuf/internal/service_reflection_test.py
+++ b/python/google/protobuf/internal/service_reflection_test.py
@@ -2,7 +2,7 @@
#
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -34,13 +34,13 @@
__author__ = 'petar@google.com (Petar Petrov)'
-import unittest
+from google.apputils import basetest
from google.protobuf import unittest_pb2
from google.protobuf import service_reflection
from google.protobuf import service
-class FooUnitTest(unittest.TestCase):
+class FooUnitTest(basetest.TestCase):
def testService(self):
class MockRpcChannel(service.RpcChannel):
@@ -133,4 +133,4 @@ class FooUnitTest(unittest.TestCase):
if __name__ == '__main__':
- unittest.main()
+ basetest.main()
diff --git a/python/google/protobuf/internal/symbol_database_test.py b/python/google/protobuf/internal/symbol_database_test.py
new file mode 100644
index 0000000..47572d5
--- /dev/null
+++ b/python/google/protobuf/internal/symbol_database_test.py
@@ -0,0 +1,120 @@
+#! /usr/bin/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.
+
+"""Tests for google.protobuf.symbol_database."""
+
+from google.apputils import basetest
+from google.protobuf import unittest_pb2
+from google.protobuf import symbol_database
+
+
+class SymbolDatabaseTest(basetest.TestCase):
+
+ def _Database(self):
+ 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
+
+ def testGetPrototype(self):
+ instance = self._Database().GetPrototype(
+ unittest_pb2.TestAllTypes.DESCRIPTOR)
+ self.assertTrue(instance is unittest_pb2.TestAllTypes)
+
+ def testGetMessages(self):
+ messages = self._Database().GetMessages(
+ ['google/protobuf/unittest.proto'])
+ self.assertTrue(
+ unittest_pb2.TestAllTypes is
+ messages['protobuf_unittest.TestAllTypes'])
+
+ def testGetSymbol(self):
+ self.assertEquals(
+ unittest_pb2.TestAllTypes, self._Database().GetSymbol(
+ 'protobuf_unittest.TestAllTypes'))
+ self.assertEquals(
+ unittest_pb2.TestAllTypes.NestedMessage, self._Database().GetSymbol(
+ 'protobuf_unittest.TestAllTypes.NestedMessage'))
+ self.assertEquals(
+ unittest_pb2.TestAllTypes.OptionalGroup, self._Database().GetSymbol(
+ 'protobuf_unittest.TestAllTypes.OptionalGroup'))
+ self.assertEquals(
+ unittest_pb2.TestAllTypes.RepeatedGroup, self._Database().GetSymbol(
+ 'protobuf_unittest.TestAllTypes.RepeatedGroup'))
+
+ def testEnums(self):
+ # Check registration of types in the pool.
+ self.assertEquals(
+ 'protobuf_unittest.ForeignEnum',
+ self._Database().pool.FindEnumTypeByName(
+ 'protobuf_unittest.ForeignEnum').full_name)
+ self.assertEquals(
+ 'protobuf_unittest.TestAllTypes.NestedEnum',
+ self._Database().pool.FindEnumTypeByName(
+ 'protobuf_unittest.TestAllTypes.NestedEnum').full_name)
+
+ def testFindMessageTypeByName(self):
+ self.assertEquals(
+ 'protobuf_unittest.TestAllTypes',
+ self._Database().pool.FindMessageTypeByName(
+ 'protobuf_unittest.TestAllTypes').full_name)
+ self.assertEquals(
+ 'protobuf_unittest.TestAllTypes.NestedMessage',
+ self._Database().pool.FindMessageTypeByName(
+ 'protobuf_unittest.TestAllTypes.NestedMessage').full_name)
+
+ def testFindFindContainingSymbol(self):
+ # Lookup based on either enum or message.
+ self.assertEquals(
+ 'google/protobuf/unittest.proto',
+ self._Database().pool.FindFileContainingSymbol(
+ 'protobuf_unittest.TestAllTypes.NestedEnum').name)
+ self.assertEquals(
+ 'google/protobuf/unittest.proto',
+ self._Database().pool.FindFileContainingSymbol(
+ 'protobuf_unittest.TestAllTypes').name)
+
+ def testFindFileByName(self):
+ self.assertEquals(
+ 'google/protobuf/unittest.proto',
+ self._Database().pool.FindFileByName(
+ 'google/protobuf/unittest.proto').name)
+
+
+if __name__ == '__main__':
+ basetest.main()
diff --git a/python/google/protobuf/internal/test_bad_identifiers.proto b/python/google/protobuf/internal/test_bad_identifiers.proto
new file mode 100644
index 0000000..9eb18cb
--- /dev/null
+++ b/python/google/protobuf/internal/test_bad_identifiers.proto
@@ -0,0 +1,52 @@
+// 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: kenton@google.com (Kenton Varda)
+
+
+package protobuf_unittest;
+
+option py_generic_services = true;
+
+message TestBadIdentifiers {
+ extensions 100 to max;
+}
+
+// Make sure these reasonable extension names don't conflict with internal
+// variables.
+extend TestBadIdentifiers {
+ optional string message = 100 [default="foo"];
+ optional string descriptor = 101 [default="bar"];
+ optional string reflection = 102 [default="baz"];
+ optional string service = 103 [default="qux"];
+}
+
+message AnotherMessage {}
+service AnotherService {}
diff --git a/python/google/protobuf/internal/test_util.py b/python/google/protobuf/internal/test_util.py
index 1df1619..787f465 100755
--- a/python/google/protobuf/internal/test_util.py
+++ b/python/google/protobuf/internal/test_util.py
@@ -1,6 +1,6 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -42,8 +42,8 @@ from google.protobuf import unittest_import_pb2
from google.protobuf import unittest_pb2
-def SetAllFields(message):
- """Sets every field in the message to a unique value.
+def SetAllNonLazyFields(message):
+ """Sets every non-lazy field in the message to a unique value.
Args:
message: A unittest_pb2.TestAllTypes instance.
@@ -66,26 +66,21 @@ def SetAllFields(message):
message.optional_float = 111
message.optional_double = 112
message.optional_bool = True
- # TODO(robinson): Firmly spec out and test how
- # protos interact with unicode. One specific example:
- # what happens if we change the literal below to
- # u'115'? What *should* happen? Still some discussion
- # to finish with Kenton about bytes vs. strings
- # and forcing everything to be utf8. :-/
- message.optional_string = '115'
- message.optional_bytes = '116'
+ message.optional_string = u'115'
+ message.optional_bytes = b'116'
message.optionalgroup.a = 117
message.optional_nested_message.bb = 118
message.optional_foreign_message.c = 119
message.optional_import_message.d = 120
+ message.optional_public_import_message.e = 126
message.optional_nested_enum = unittest_pb2.TestAllTypes.BAZ
message.optional_foreign_enum = unittest_pb2.FOREIGN_BAZ
message.optional_import_enum = unittest_import_pb2.IMPORT_BAZ
- message.optional_string_piece = '124'
- message.optional_cord = '125'
+ message.optional_string_piece = u'124'
+ message.optional_cord = u'125'
#
# Repeated fields.
@@ -104,20 +99,21 @@ def SetAllFields(message):
message.repeated_float.append(211)
message.repeated_double.append(212)
message.repeated_bool.append(True)
- message.repeated_string.append('215')
- message.repeated_bytes.append('216')
+ message.repeated_string.append(u'215')
+ message.repeated_bytes.append(b'216')
message.repeatedgroup.add().a = 217
message.repeated_nested_message.add().bb = 218
message.repeated_foreign_message.add().c = 219
message.repeated_import_message.add().d = 220
+ message.repeated_lazy_message.add().bb = 227
message.repeated_nested_enum.append(unittest_pb2.TestAllTypes.BAR)
message.repeated_foreign_enum.append(unittest_pb2.FOREIGN_BAR)
message.repeated_import_enum.append(unittest_import_pb2.IMPORT_BAR)
- message.repeated_string_piece.append('224')
- message.repeated_cord.append('225')
+ message.repeated_string_piece.append(u'224')
+ message.repeated_cord.append(u'225')
# Add a second one of each field.
message.repeated_int32.append(301)
@@ -133,20 +129,21 @@ def SetAllFields(message):
message.repeated_float.append(311)
message.repeated_double.append(312)
message.repeated_bool.append(False)
- message.repeated_string.append('315')
- message.repeated_bytes.append('316')
+ message.repeated_string.append(u'315')
+ message.repeated_bytes.append(b'316')
message.repeatedgroup.add().a = 317
message.repeated_nested_message.add().bb = 318
message.repeated_foreign_message.add().c = 319
message.repeated_import_message.add().d = 320
+ message.repeated_lazy_message.add().bb = 327
message.repeated_nested_enum.append(unittest_pb2.TestAllTypes.BAZ)
message.repeated_foreign_enum.append(unittest_pb2.FOREIGN_BAZ)
message.repeated_import_enum.append(unittest_import_pb2.IMPORT_BAZ)
- message.repeated_string_piece.append('324')
- message.repeated_cord.append('325')
+ message.repeated_string_piece.append(u'324')
+ message.repeated_cord.append(u'325')
#
# Fields that have defaults.
@@ -166,7 +163,7 @@ def SetAllFields(message):
message.default_double = 412
message.default_bool = False
message.default_string = '415'
- message.default_bytes = '416'
+ message.default_bytes = b'416'
message.default_nested_enum = unittest_pb2.TestAllTypes.FOO
message.default_foreign_enum = unittest_pb2.FOREIGN_FOO
@@ -175,6 +172,16 @@ def SetAllFields(message):
message.default_string_piece = '424'
message.default_cord = '425'
+ message.oneof_uint32 = 601
+ message.oneof_nested_message.bb = 602
+ message.oneof_string = '603'
+ message.oneof_bytes = b'604'
+
+
+def SetAllFields(message):
+ SetAllNonLazyFields(message)
+ message.optional_lazy_message.bb = 127
+
def SetAllExtensions(message):
"""Sets every extension in the message to a unique value.
@@ -204,21 +211,23 @@ def SetAllExtensions(message):
extensions[pb2.optional_float_extension] = 111
extensions[pb2.optional_double_extension] = 112
extensions[pb2.optional_bool_extension] = True
- extensions[pb2.optional_string_extension] = '115'
- extensions[pb2.optional_bytes_extension] = '116'
+ extensions[pb2.optional_string_extension] = u'115'
+ extensions[pb2.optional_bytes_extension] = b'116'
extensions[pb2.optionalgroup_extension].a = 117
extensions[pb2.optional_nested_message_extension].bb = 118
extensions[pb2.optional_foreign_message_extension].c = 119
extensions[pb2.optional_import_message_extension].d = 120
+ extensions[pb2.optional_public_import_message_extension].e = 126
+ extensions[pb2.optional_lazy_message_extension].bb = 127
extensions[pb2.optional_nested_enum_extension] = pb2.TestAllTypes.BAZ
extensions[pb2.optional_nested_enum_extension] = pb2.TestAllTypes.BAZ
extensions[pb2.optional_foreign_enum_extension] = pb2.FOREIGN_BAZ
extensions[pb2.optional_import_enum_extension] = import_pb2.IMPORT_BAZ
- extensions[pb2.optional_string_piece_extension] = '124'
- extensions[pb2.optional_cord_extension] = '125'
+ extensions[pb2.optional_string_piece_extension] = u'124'
+ extensions[pb2.optional_cord_extension] = u'125'
#
# Repeated fields.
@@ -237,20 +246,21 @@ def SetAllExtensions(message):
extensions[pb2.repeated_float_extension].append(211)
extensions[pb2.repeated_double_extension].append(212)
extensions[pb2.repeated_bool_extension].append(True)
- extensions[pb2.repeated_string_extension].append('215')
- extensions[pb2.repeated_bytes_extension].append('216')
+ extensions[pb2.repeated_string_extension].append(u'215')
+ extensions[pb2.repeated_bytes_extension].append(b'216')
extensions[pb2.repeatedgroup_extension].add().a = 217
extensions[pb2.repeated_nested_message_extension].add().bb = 218
extensions[pb2.repeated_foreign_message_extension].add().c = 219
extensions[pb2.repeated_import_message_extension].add().d = 220
+ extensions[pb2.repeated_lazy_message_extension].add().bb = 227
extensions[pb2.repeated_nested_enum_extension].append(pb2.TestAllTypes.BAR)
extensions[pb2.repeated_foreign_enum_extension].append(pb2.FOREIGN_BAR)
extensions[pb2.repeated_import_enum_extension].append(import_pb2.IMPORT_BAR)
- extensions[pb2.repeated_string_piece_extension].append('224')
- extensions[pb2.repeated_cord_extension].append('225')
+ extensions[pb2.repeated_string_piece_extension].append(u'224')
+ extensions[pb2.repeated_cord_extension].append(u'225')
# Append a second one of each field.
extensions[pb2.repeated_int32_extension].append(301)
@@ -266,20 +276,21 @@ def SetAllExtensions(message):
extensions[pb2.repeated_float_extension].append(311)
extensions[pb2.repeated_double_extension].append(312)
extensions[pb2.repeated_bool_extension].append(False)
- extensions[pb2.repeated_string_extension].append('315')
- extensions[pb2.repeated_bytes_extension].append('316')
+ extensions[pb2.repeated_string_extension].append(u'315')
+ extensions[pb2.repeated_bytes_extension].append(b'316')
extensions[pb2.repeatedgroup_extension].add().a = 317
extensions[pb2.repeated_nested_message_extension].add().bb = 318
extensions[pb2.repeated_foreign_message_extension].add().c = 319
extensions[pb2.repeated_import_message_extension].add().d = 320
+ extensions[pb2.repeated_lazy_message_extension].add().bb = 327
extensions[pb2.repeated_nested_enum_extension].append(pb2.TestAllTypes.BAZ)
extensions[pb2.repeated_foreign_enum_extension].append(pb2.FOREIGN_BAZ)
extensions[pb2.repeated_import_enum_extension].append(import_pb2.IMPORT_BAZ)
- extensions[pb2.repeated_string_piece_extension].append('324')
- extensions[pb2.repeated_cord_extension].append('325')
+ extensions[pb2.repeated_string_piece_extension].append(u'324')
+ extensions[pb2.repeated_cord_extension].append(u'325')
#
# Fields with defaults.
@@ -298,16 +309,21 @@ def SetAllExtensions(message):
extensions[pb2.default_float_extension] = 411
extensions[pb2.default_double_extension] = 412
extensions[pb2.default_bool_extension] = False
- extensions[pb2.default_string_extension] = '415'
- extensions[pb2.default_bytes_extension] = '416'
+ extensions[pb2.default_string_extension] = u'415'
+ extensions[pb2.default_bytes_extension] = b'416'
extensions[pb2.default_nested_enum_extension] = pb2.TestAllTypes.FOO
extensions[pb2.default_foreign_enum_extension] = pb2.FOREIGN_FOO
extensions[pb2.default_import_enum_extension] = import_pb2.IMPORT_FOO
- extensions[pb2.default_string_piece_extension] = '424'
+ extensions[pb2.default_string_piece_extension] = u'424'
extensions[pb2.default_cord_extension] = '425'
+ extensions[pb2.oneof_uint32_extension] = 601
+ extensions[pb2.oneof_nested_message_extension].bb = 602
+ extensions[pb2.oneof_string_extension] = u'603'
+ extensions[pb2.oneof_bytes_extension] = b'604'
+
def SetAllFieldsAndExtensions(message):
"""Sets every field and extension in the message to a unique value.
@@ -346,7 +362,7 @@ def ExpectAllFieldsAndExtensionsInOrder(serialized):
message.my_float = 1.0
expected_strings.append(message.SerializeToString())
message.Clear()
- expected = ''.join(expected_strings)
+ expected = b''.join(expected_strings)
if expected != serialized:
raise ValueError('Expected %r, found %r' % (expected, serialized))
@@ -401,12 +417,14 @@ def ExpectAllFieldsSet(test_case, message):
test_case.assertEqual(112, message.optional_double)
test_case.assertEqual(True, message.optional_bool)
test_case.assertEqual('115', message.optional_string)
- test_case.assertEqual('116', message.optional_bytes)
+ test_case.assertEqual(b'116', message.optional_bytes)
test_case.assertEqual(117, message.optionalgroup.a)
test_case.assertEqual(118, message.optional_nested_message.bb)
test_case.assertEqual(119, message.optional_foreign_message.c)
test_case.assertEqual(120, message.optional_import_message.d)
+ test_case.assertEqual(126, message.optional_public_import_message.e)
+ test_case.assertEqual(127, message.optional_lazy_message.bb)
test_case.assertEqual(unittest_pb2.TestAllTypes.BAZ,
message.optional_nested_enum)
@@ -458,12 +476,13 @@ def ExpectAllFieldsSet(test_case, message):
test_case.assertEqual(212, message.repeated_double[0])
test_case.assertEqual(True, message.repeated_bool[0])
test_case.assertEqual('215', message.repeated_string[0])
- test_case.assertEqual('216', message.repeated_bytes[0])
+ test_case.assertEqual(b'216', message.repeated_bytes[0])
test_case.assertEqual(217, message.repeatedgroup[0].a)
test_case.assertEqual(218, message.repeated_nested_message[0].bb)
test_case.assertEqual(219, message.repeated_foreign_message[0].c)
test_case.assertEqual(220, message.repeated_import_message[0].d)
+ test_case.assertEqual(227, message.repeated_lazy_message[0].bb)
test_case.assertEqual(unittest_pb2.TestAllTypes.BAR,
message.repeated_nested_enum[0])
@@ -486,12 +505,13 @@ def ExpectAllFieldsSet(test_case, message):
test_case.assertEqual(312, message.repeated_double[1])
test_case.assertEqual(False, message.repeated_bool[1])
test_case.assertEqual('315', message.repeated_string[1])
- test_case.assertEqual('316', message.repeated_bytes[1])
+ test_case.assertEqual(b'316', message.repeated_bytes[1])
test_case.assertEqual(317, message.repeatedgroup[1].a)
test_case.assertEqual(318, message.repeated_nested_message[1].bb)
test_case.assertEqual(319, message.repeated_foreign_message[1].c)
test_case.assertEqual(320, message.repeated_import_message[1].d)
+ test_case.assertEqual(327, message.repeated_lazy_message[1].bb)
test_case.assertEqual(unittest_pb2.TestAllTypes.BAZ,
message.repeated_nested_enum[1])
@@ -536,7 +556,7 @@ def ExpectAllFieldsSet(test_case, message):
test_case.assertEqual(412, message.default_double)
test_case.assertEqual(False, message.default_bool)
test_case.assertEqual('415', message.default_string)
- test_case.assertEqual('416', message.default_bytes)
+ test_case.assertEqual(b'416', message.default_bytes)
test_case.assertEqual(unittest_pb2.TestAllTypes.FOO,
message.default_nested_enum)
@@ -545,6 +565,7 @@ def ExpectAllFieldsSet(test_case, message):
test_case.assertEqual(unittest_import_pb2.IMPORT_FOO,
message.default_import_enum)
+
def GoldenFile(filename):
"""Finds the given golden file and returns a file object representing it."""
@@ -558,9 +579,15 @@ def GoldenFile(filename):
path = os.path.join(path, '..')
raise RuntimeError(
- '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.')
+ '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.')
+
+
+def GoldenFileData(filename):
+ """Finds the given golden file and returns its contents."""
+ with GoldenFile(filename) as f:
+ return f.read()
def SetAllPackedFields(message):
diff --git a/python/google/protobuf/internal/text_encoding_test.py b/python/google/protobuf/internal/text_encoding_test.py
new file mode 100755
index 0000000..db0222b
--- /dev/null
+++ b/python/google/protobuf/internal/text_encoding_test.py
@@ -0,0 +1,68 @@
+#! /usr/bin/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.
+
+"""Tests for google.protobuf.text_encoding."""
+
+from google.apputils import basetest
+from google.protobuf import text_encoding
+
+TEST_VALUES = [
+ ("foo\\rbar\\nbaz\\t",
+ "foo\\rbar\\nbaz\\t",
+ b"foo\rbar\nbaz\t"),
+ ("\\'full of \\\"sound\\\" and \\\"fury\\\"\\'",
+ "\\'full of \\\"sound\\\" and \\\"fury\\\"\\'",
+ b"'full of \"sound\" and \"fury\"'"),
+ ("signi\\\\fying\\\\ nothing\\\\",
+ "signi\\\\fying\\\\ nothing\\\\",
+ b"signi\\fying\\ nothing\\"),
+ ("\\010\\t\\n\\013\\014\\r",
+ "\x08\\t\\n\x0b\x0c\\r",
+ b"\010\011\012\013\014\015")]
+
+
+class TextEncodingTestCase(basetest.TestCase):
+ def testCEscape(self):
+ for escaped, escaped_utf8, unescaped in TEST_VALUES:
+ self.assertEquals(escaped,
+ text_encoding.CEscape(unescaped, as_utf8=False))
+ self.assertEquals(escaped_utf8,
+ text_encoding.CEscape(unescaped, as_utf8=True))
+
+ def testCUnescape(self):
+ for escaped, escaped_utf8, unescaped in TEST_VALUES:
+ self.assertEquals(unescaped, text_encoding.CUnescape(escaped))
+ self.assertEquals(unescaped, text_encoding.CUnescape(escaped_utf8))
+
+
+if __name__ == "__main__":
+ basetest.main()
diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py
index e0991cb..b0a3a5f 100755
--- a/python/google/protobuf/internal/text_format_test.py
+++ b/python/google/protobuf/internal/text_format_test.py
@@ -2,7 +2,7 @@
#
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -34,48 +34,71 @@
__author__ = 'kenton@google.com (Kenton Varda)'
-import difflib
+import re
-import unittest
+from google.apputils import basetest
from google.protobuf import text_format
+from google.protobuf.internal import api_implementation
from google.protobuf.internal import test_util
from google.protobuf import unittest_pb2
from google.protobuf import unittest_mset_pb2
+class TextFormatTest(basetest.TestCase):
-class TextFormatTest(unittest.TestCase):
def ReadGolden(self, golden_filename):
- f = test_util.GoldenFile(golden_filename)
- golden_lines = f.readlines()
- f.close()
- return golden_lines
+ with test_util.GoldenFile(golden_filename) as f:
+ return (f.readlines() if str is bytes else # PY3
+ [golden_line.decode('utf-8') for golden_line in f])
def CompareToGoldenFile(self, text, golden_filename):
golden_lines = self.ReadGolden(golden_filename)
- self.CompareToGoldenLines(text, golden_lines)
+ self.assertMultiLineEqual(text, ''.join(golden_lines))
def CompareToGoldenText(self, text, golden_text):
- self.CompareToGoldenLines(text, golden_text.splitlines(1))
-
- def CompareToGoldenLines(self, text, golden_lines):
- actual_lines = text.splitlines(1)
- self.assertEqual(golden_lines, actual_lines,
- "Text doesn't match golden. Diff:\n" +
- ''.join(difflib.ndiff(golden_lines, actual_lines)))
+ self.assertMultiLineEqual(text, golden_text)
def testPrintAllFields(self):
message = unittest_pb2.TestAllTypes()
test_util.SetAllFields(message)
self.CompareToGoldenFile(
- self.RemoveRedundantZeros(text_format.MessageToString(message)),
- 'text_format_unittest_data.txt')
+ self.RemoveRedundantZeros(text_format.MessageToString(message)),
+ 'text_format_unittest_data_oneof_implemented.txt')
+
+ def testPrintInIndexOrder(self):
+ message = unittest_pb2.TestFieldOrderings()
+ message.my_string = '115'
+ message.my_int = 101
+ message.my_float = 111
+ self.CompareToGoldenText(
+ self.RemoveRedundantZeros(text_format.MessageToString(
+ message, use_index_order=True)),
+ 'my_string: \"115\"\nmy_int: 101\nmy_float: 111\n')
+ self.CompareToGoldenText(
+ self.RemoveRedundantZeros(text_format.MessageToString(
+ message)), 'my_int: 101\nmy_string: \"115\"\nmy_float: 111\n')
def testPrintAllExtensions(self):
message = unittest_pb2.TestAllExtensions()
test_util.SetAllExtensions(message)
self.CompareToGoldenFile(
- self.RemoveRedundantZeros(text_format.MessageToString(message)),
- 'text_format_unittest_extensions_data.txt')
+ self.RemoveRedundantZeros(text_format.MessageToString(message)),
+ 'text_format_unittest_extensions_data.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 testPrintAllExtensionsPointy(self):
+ message = unittest_pb2.TestAllExtensions()
+ test_util.SetAllExtensions(message)
+ self.CompareToGoldenFile(
+ self.RemoveRedundantZeros(text_format.MessageToString(
+ message, pointy_brackets=True)),
+ 'text_format_unittest_extensions_data_pointy.txt')
def testPrintMessageSet(self):
message = unittest_mset_pb2.TestMessageSetContainer()
@@ -83,33 +106,179 @@ class TextFormatTest(unittest.TestCase):
ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
message.message_set.Extensions[ext1].i = 23
message.message_set.Extensions[ext2].str = 'foo'
- self.CompareToGoldenText(text_format.MessageToString(message),
- 'message_set {\n'
- ' [protobuf_unittest.TestMessageSetExtension1] {\n'
- ' i: 23\n'
- ' }\n'
- ' [protobuf_unittest.TestMessageSetExtension2] {\n'
- ' str: \"foo\"\n'
- ' }\n'
- '}\n')
+ self.CompareToGoldenText(
+ text_format.MessageToString(message),
+ 'message_set {\n'
+ ' [protobuf_unittest.TestMessageSetExtension1] {\n'
+ ' i: 23\n'
+ ' }\n'
+ ' [protobuf_unittest.TestMessageSetExtension2] {\n'
+ ' str: \"foo\"\n'
+ ' }\n'
+ '}\n')
def testPrintExotic(self):
message = unittest_pb2.TestAllTypes()
- message.repeated_int64.append(-9223372036854775808);
- message.repeated_uint64.append(18446744073709551615);
- message.repeated_double.append(123.456);
- message.repeated_double.append(1.23e22);
- message.repeated_double.append(1.23e-18);
- message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'\"');
+ message.repeated_int64.append(-9223372036854775808)
+ message.repeated_uint64.append(18446744073709551615)
+ message.repeated_double.append(123.456)
+ message.repeated_double.append(1.23e22)
+ message.repeated_double.append(1.23e-18)
+ 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)),
+ 'repeated_int64: -9223372036854775808\n'
+ 'repeated_uint64: 18446744073709551615\n'
+ 'repeated_double: 123.456\n'
+ 'repeated_double: 1.23e+22\n'
+ 'repeated_double: 1.23e-18\n'
+ 'repeated_string:'
+ ' "\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n'
+ 'repeated_string: "\\303\\274\\352\\234\\237"\n')
+
+ def testPrintExoticUnicodeSubclass(self):
+ class UnicodeSub(unicode):
+ pass
+ message = unittest_pb2.TestAllTypes()
+ message.repeated_string.append(UnicodeSub(u'\u00fc\ua71f'))
+ self.CompareToGoldenText(
+ text_format.MessageToString(message),
+ 'repeated_string: "\\303\\274\\352\\234\\237"\n')
+
+ def testPrintNestedMessageAsOneLine(self):
+ message = unittest_pb2.TestAllTypes()
+ msg = message.repeated_nested_message.add()
+ msg.bb = 42
+ self.CompareToGoldenText(
+ text_format.MessageToString(message, as_one_line=True),
+ 'repeated_nested_message { bb: 42 }')
+
+ def testPrintRepeatedFieldsAsOneLine(self):
+ message = unittest_pb2.TestAllTypes()
+ message.repeated_int32.append(1)
+ message.repeated_int32.append(1)
+ message.repeated_int32.append(3)
+ message.repeated_string.append("Google")
+ message.repeated_string.append("Zurich")
+ self.CompareToGoldenText(
+ text_format.MessageToString(message, as_one_line=True),
+ 'repeated_int32: 1 repeated_int32: 1 repeated_int32: 3 '
+ 'repeated_string: "Google" repeated_string: "Zurich"')
+
+ def testPrintNestedNewLineInStringAsOneLine(self):
+ message = unittest_pb2.TestAllTypes()
+ message.optional_string = "a\nnew\nline"
+ self.CompareToGoldenText(
+ text_format.MessageToString(message, as_one_line=True),
+ 'optional_string: "a\\nnew\\nline"')
+
+ def testPrintMessageSetAsOneLine(self):
+ 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'
+ self.CompareToGoldenText(
+ text_format.MessageToString(message, as_one_line=True),
+ 'message_set {'
+ ' [protobuf_unittest.TestMessageSetExtension1] {'
+ ' i: 23'
+ ' }'
+ ' [protobuf_unittest.TestMessageSetExtension2] {'
+ ' str: \"foo\"'
+ ' }'
+ ' }')
+
+ def testPrintExoticAsOneLine(self):
+ message = unittest_pb2.TestAllTypes()
+ message.repeated_int64.append(-9223372036854775808)
+ message.repeated_uint64.append(18446744073709551615)
+ message.repeated_double.append(123.456)
+ message.repeated_double.append(1.23e22)
+ message.repeated_double.append(1.23e-18)
+ 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)),
+ 'repeated_int64: -9223372036854775808'
+ ' repeated_uint64: 18446744073709551615'
+ ' repeated_double: 123.456'
+ ' repeated_double: 1.23e+22'
+ ' repeated_double: 1.23e-18'
+ ' repeated_string: '
+ '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""'
+ ' repeated_string: "\\303\\274\\352\\234\\237"')
+
+ def testRoundTripExoticAsOneLine(self):
+ message = unittest_pb2.TestAllTypes()
+ message.repeated_int64.append(-9223372036854775808)
+ message.repeated_uint64.append(18446744073709551615)
+ message.repeated_double.append(123.456)
+ message.repeated_double.append(1.23e22)
+ message.repeated_double.append(1.23e-18)
+ message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
+ message.repeated_string.append(u'\u00fc\ua71f')
+
+ # Test as_utf8 = False.
+ wire_text = text_format.MessageToString(
+ message, as_one_line=True, as_utf8=False)
+ parsed_message = unittest_pb2.TestAllTypes()
+ r = text_format.Parse(wire_text, parsed_message)
+ self.assertIs(r, parsed_message)
+ self.assertEquals(message, parsed_message)
+
+ # Test as_utf8 = True.
+ wire_text = text_format.MessageToString(
+ message, as_one_line=True, as_utf8=True)
+ parsed_message = unittest_pb2.TestAllTypes()
+ r = text_format.Parse(wire_text, parsed_message)
+ self.assertIs(r, parsed_message)
+ self.assertEquals(message, parsed_message,
+ '\n%s != %s' % (message, parsed_message))
+
+ def testPrintRawUtf8String(self):
+ message = unittest_pb2.TestAllTypes()
+ message.repeated_string.append(u'\u00fc\ua71f')
+ text = text_format.MessageToString(message, as_utf8=True)
+ self.CompareToGoldenText(text, 'repeated_string: "\303\274\352\234\237"\n')
+ parsed_message = unittest_pb2.TestAllTypes()
+ text_format.Parse(text, parsed_message)
+ self.assertEquals(message, parsed_message,
+ '\n%s != %s' % (message, parsed_message))
+
+ def testPrintFloatFormat(self):
+ # Check that float_format argument is passed to sub-message formatting.
+ message = unittest_pb2.NestedTestAllTypes()
+ # We use 1.25 as it is a round number in binary. The proto 32-bit float
+ # will not gain additional imprecise digits as a 64-bit Python float and
+ # show up in its str. 32-bit 1.2 is noisy when extended to 64-bit:
+ # >>> struct.unpack('f', struct.pack('f', 1.2))[0]
+ # 1.2000000476837158
+ # >>> struct.unpack('f', struct.pack('f', 1.25))[0]
+ # 1.25
+ message.payload.optional_float = 1.25
+ # Check rounding at 15 significant digits
+ message.payload.optional_double = -.000003456789012345678
+ # Check no decimal point.
+ message.payload.repeated_float.append(-5642)
+ # Check no trailing zeros.
+ 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']
+ text_message = text_format.MessageToString(message, float_format='.15g')
self.CompareToGoldenText(
- self.RemoveRedundantZeros(text_format.MessageToString(message)),
- 'repeated_int64: -9223372036854775808\n'
- 'repeated_uint64: 18446744073709551615\n'
- 'repeated_double: 123.456\n'
- 'repeated_double: 1.23e+22\n'
- 'repeated_double: 1.23e-18\n'
- 'repeated_string: '
- '\"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\\"\"\n')
+ self.RemoveRedundantZeros(text_message),
+ 'payload {{\n {}\n {}\n {}\n {}\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,
+ float_format='.15g')
+ self.CompareToGoldenText(
+ self.RemoveRedundantZeros(text_message),
+ 'payload {{ {} {} {} {} }}'.format(*formatted_fields))
def testMessageToString(self):
message = unittest_pb2.ForeignMessage()
@@ -119,52 +288,57 @@ class TextFormatTest(unittest.TestCase):
def RemoveRedundantZeros(self, text):
# Some platforms print 1e+5 as 1e+005. This is fine, but we need to remove
# these zeros in order to match the golden file.
- return text.replace('e+0','e+').replace('e+0','e+') \
+ text = text.replace('e+0','e+').replace('e+0','e+') \
.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)
+ return text
- def testMergeGolden(self):
+ def testParseGolden(self):
golden_text = '\n'.join(self.ReadGolden('text_format_unittest_data.txt'))
parsed_message = unittest_pb2.TestAllTypes()
- text_format.Merge(golden_text, parsed_message)
+ r = text_format.Parse(golden_text, parsed_message)
+ self.assertIs(r, parsed_message)
message = unittest_pb2.TestAllTypes()
test_util.SetAllFields(message)
self.assertEquals(message, parsed_message)
- def testMergeGoldenExtensions(self):
+ def testParseGoldenExtensions(self):
golden_text = '\n'.join(self.ReadGolden(
'text_format_unittest_extensions_data.txt'))
parsed_message = unittest_pb2.TestAllExtensions()
- text_format.Merge(golden_text, parsed_message)
+ text_format.Parse(golden_text, parsed_message)
message = unittest_pb2.TestAllExtensions()
test_util.SetAllExtensions(message)
self.assertEquals(message, parsed_message)
- def testMergeAllFields(self):
+ def testParseAllFields(self):
message = unittest_pb2.TestAllTypes()
test_util.SetAllFields(message)
ascii_text = text_format.MessageToString(message)
parsed_message = unittest_pb2.TestAllTypes()
- text_format.Merge(ascii_text, parsed_message)
+ text_format.Parse(ascii_text, parsed_message)
self.assertEqual(message, parsed_message)
test_util.ExpectAllFieldsSet(self, message)
- def testMergeAllExtensions(self):
+ def testParseAllExtensions(self):
message = unittest_pb2.TestAllExtensions()
test_util.SetAllExtensions(message)
ascii_text = text_format.MessageToString(message)
parsed_message = unittest_pb2.TestAllExtensions()
- text_format.Merge(ascii_text, parsed_message)
+ text_format.Parse(ascii_text, parsed_message)
self.assertEqual(message, parsed_message)
- def testMergeMessageSet(self):
+ def testParseMessageSet(self):
message = unittest_pb2.TestAllTypes()
text = ('repeated_uint64: 1\n'
'repeated_uint64: 2\n')
- text_format.Merge(text, message)
+ text_format.Parse(text, message)
self.assertEqual(1, message.repeated_uint64[0])
self.assertEqual(2, message.repeated_uint64[1])
@@ -177,13 +351,13 @@ class TextFormatTest(unittest.TestCase):
' str: \"foo\"\n'
' }\n'
'}\n')
- text_format.Merge(text, message)
+ text_format.Parse(text, message)
ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
self.assertEquals(23, message.message_set.Extensions[ext1].i)
self.assertEquals('foo', message.message_set.Extensions[ext2].str)
- def testMergeExotic(self):
+ def testParseExotic(self):
message = unittest_pb2.TestAllTypes()
text = ('repeated_int64: -9223372036854775808\n'
'repeated_uint64: 18446744073709551615\n'
@@ -191,9 +365,12 @@ class TextFormatTest(unittest.TestCase):
'repeated_double: 1.23e+22\n'
'repeated_double: 1.23e-18\n'
'repeated_string: \n'
- '\"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\\"\"\n'
- 'repeated_string: "foo" \'corge\' "grault"')
- text_format.Merge(text, message)
+ '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n'
+ 'repeated_string: "foo" \'corge\' "grault"\n'
+ 'repeated_string: "\\303\\274\\352\\234\\237"\n'
+ 'repeated_string: "\\xc3\\xbc"\n'
+ 'repeated_string: "\xc3\xbc"\n')
+ text_format.Parse(text, message)
self.assertEqual(-9223372036854775808, message.repeated_int64[0])
self.assertEqual(18446744073709551615, message.repeated_uint64[0])
@@ -201,95 +378,224 @@ class TextFormatTest(unittest.TestCase):
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])
+ '\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])
- def testMergeUnknownField(self):
+ def testParseTrailingCommas(self):
+ message = unittest_pb2.TestAllTypes()
+ text = ('repeated_int64: 100;\n'
+ 'repeated_int64: 200;\n'
+ 'repeated_int64: 300,\n'
+ 'repeated_string: "one",\n'
+ 'repeated_string: "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 testParseEmptyText(self):
+ message = unittest_pb2.TestAllTypes()
+ text = ''
+ text_format.Parse(text, message)
+ self.assertEquals(unittest_pb2.TestAllTypes(), message)
+
+ def testParseInvalidUtf8(self):
+ message = unittest_pb2.TestAllTypes()
+ text = 'repeated_string: "\\xc3\\xc3"'
+ self.assertRaises(text_format.ParseError, text_format.Parse, text, message)
+
+ def testParseSingleWord(self):
+ message = unittest_pb2.TestAllTypes()
+ text = 'foo'
+ self.assertRaisesWithLiteralMatch(
+ text_format.ParseError,
+ ('1:1 : Message type "protobuf_unittest.TestAllTypes" has no field named '
+ '"foo".'),
+ text_format.Parse, text, message)
+
+ def testParseUnknownField(self):
message = unittest_pb2.TestAllTypes()
text = 'unknown_field: 8\n'
- self.assertRaisesWithMessage(
+ self.assertRaisesWithLiteralMatch(
text_format.ParseError,
('1:1 : Message type "protobuf_unittest.TestAllTypes" has no field named '
'"unknown_field".'),
- text_format.Merge, text, message)
+ text_format.Parse, text, message)
- def testMergeBadExtension(self):
+ def testParseBadExtension(self):
message = unittest_pb2.TestAllExtensions()
text = '[unknown_extension]: 8\n'
- self.assertRaisesWithMessage(
+ self.assertRaisesWithLiteralMatch(
text_format.ParseError,
'1:2 : Extension "unknown_extension" not registered.',
- text_format.Merge, text, message)
+ text_format.Parse, text, message)
message = unittest_pb2.TestAllTypes()
- self.assertRaisesWithMessage(
+ self.assertRaisesWithLiteralMatch(
text_format.ParseError,
('1:2 : Message type "protobuf_unittest.TestAllTypes" does not have '
'extensions.'),
- text_format.Merge, text, message)
+ text_format.Parse, text, message)
- def testMergeGroupNotClosed(self):
+ def testParseGroupNotClosed(self):
message = unittest_pb2.TestAllTypes()
text = 'RepeatedGroup: <'
- self.assertRaisesWithMessage(
+ self.assertRaisesWithLiteralMatch(
text_format.ParseError, '1:16 : Expected ">".',
- text_format.Merge, text, message)
+ text_format.Parse, text, message)
text = 'RepeatedGroup: {'
- self.assertRaisesWithMessage(
+ self.assertRaisesWithLiteralMatch(
text_format.ParseError, '1:16 : Expected "}".',
- text_format.Merge, text, message)
+ text_format.Parse, text, message)
- def testMergeEmptyGroup(self):
+ def testParseEmptyGroup(self):
message = unittest_pb2.TestAllTypes()
text = 'OptionalGroup: {}'
- text_format.Merge(text, message)
+ text_format.Parse(text, message)
self.assertTrue(message.HasField('optionalgroup'))
message.Clear()
message = unittest_pb2.TestAllTypes()
text = 'OptionalGroup: <>'
- text_format.Merge(text, message)
+ text_format.Parse(text, message)
self.assertTrue(message.HasField('optionalgroup'))
- def testMergeBadEnumValue(self):
+ def testParseBadEnumValue(self):
message = unittest_pb2.TestAllTypes()
text = 'optional_nested_enum: BARR'
- self.assertRaisesWithMessage(
+ self.assertRaisesWithLiteralMatch(
text_format.ParseError,
('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" '
'has no value named BARR.'),
- text_format.Merge, text, message)
+ text_format.Parse, text, message)
message = unittest_pb2.TestAllTypes()
text = 'optional_nested_enum: 100'
- self.assertRaisesWithMessage(
+ self.assertRaisesWithLiteralMatch(
text_format.ParseError,
('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" '
'has no value with number 100.'),
- text_format.Merge, text, message)
-
- def assertRaisesWithMessage(self, e_class, e, func, *args, **kwargs):
- """Same as assertRaises, but also compares the exception message."""
- if hasattr(e_class, '__name__'):
- exc_name = e_class.__name__
- else:
- exc_name = str(e_class)
-
- try:
- func(*args, **kwargs)
- except e_class, expr:
- if str(expr) != e:
- msg = '%s raised, but with wrong message: "%s" instead of "%s"'
- raise self.failureException(msg % (exc_name,
- str(expr).encode('string_escape'),
- e.encode('string_escape')))
- return
- else:
- raise self.failureException('%s not raised' % exc_name)
-
-
-class TokenizerTest(unittest.TestCase):
+ text_format.Parse, text, message)
+
+ def testParseBadIntValue(self):
+ message = unittest_pb2.TestAllTypes()
+ text = 'optional_int32: bork'
+ self.assertRaisesWithLiteralMatch(
+ text_format.ParseError,
+ ('1:17 : Couldn\'t parse integer: bork'),
+ text_format.Parse, text, message)
+
+ def testParseStringFieldUnescape(self):
+ message = unittest_pb2.TestAllTypes()
+ text = r'''repeated_string: "\xf\x62"
+ repeated_string: "\\xf\\x62"
+ repeated_string: "\\\xf\\\x62"
+ repeated_string: "\\\\xf\\\\x62"
+ repeated_string: "\\\\\xf\\\\\x62"
+ repeated_string: "\x5cx20"'''
+ text_format.Parse(text, message)
+
+ SLASH = '\\'
+ self.assertEqual('\x0fb', message.repeated_string[0])
+ self.assertEqual(SLASH + 'xf' + SLASH + 'x62', message.repeated_string[1])
+ self.assertEqual(SLASH + '\x0f' + SLASH + 'b', message.repeated_string[2])
+ self.assertEqual(SLASH + SLASH + 'xf' + SLASH + SLASH + 'x62',
+ message.repeated_string[3])
+ self.assertEqual(SLASH + SLASH + '\x0f' + SLASH + SLASH + 'b',
+ message.repeated_string[4])
+ self.assertEqual(SLASH + 'x20', message.repeated_string[5])
+
+ def testMergeRepeatedScalars(self):
+ message = unittest_pb2.TestAllTypes()
+ text = ('optional_int32: 42 '
+ 'optional_int32: 67')
+ r = text_format.Merge(text, message)
+ self.assertIs(r, message)
+ self.assertEqual(67, message.optional_int32)
+
+ def testParseRepeatedScalars(self):
+ message = unittest_pb2.TestAllTypes()
+ text = ('optional_int32: 42 '
+ 'optional_int32: 67')
+ self.assertRaisesWithLiteralMatch(
+ text_format.ParseError,
+ ('1:36 : Message type "protobuf_unittest.TestAllTypes" should not '
+ 'have multiple "optional_int32" fields.'),
+ text_format.Parse, text, message)
+
+ def testMergeRepeatedNestedMessageScalars(self):
+ message = unittest_pb2.TestAllTypes()
+ text = ('optional_nested_message { bb: 1 } '
+ 'optional_nested_message { bb: 2 }')
+ r = text_format.Merge(text, message)
+ self.assertTrue(r is message)
+ self.assertEqual(2, message.optional_nested_message.bb)
+
+ def testParseRepeatedNestedMessageScalars(self):
+ message = unittest_pb2.TestAllTypes()
+ text = ('optional_nested_message { bb: 1 } '
+ 'optional_nested_message { bb: 2 }')
+ self.assertRaisesWithLiteralMatch(
+ text_format.ParseError,
+ ('1:65 : Message type "protobuf_unittest.TestAllTypes.NestedMessage" '
+ 'should not have multiple "bb" fields.'),
+ text_format.Parse, text, message)
+
+ def testMergeRepeatedExtensionScalars(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])
+
+ def testParseRepeatedExtensionScalars(self):
+ message = unittest_pb2.TestAllExtensions()
+ text = ('[protobuf_unittest.optional_int32_extension]: 42 '
+ '[protobuf_unittest.optional_int32_extension]: 67')
+ self.assertRaisesWithLiteralMatch(
+ 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 testParseLinesGolden(self):
+ opened = self.ReadGolden('text_format_unittest_data.txt')
+ parsed_message = unittest_pb2.TestAllTypes()
+ r = text_format.ParseLines(opened, parsed_message)
+ self.assertIs(r, parsed_message)
+
+ message = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(message)
+ self.assertEquals(message, parsed_message)
+
+ def testMergeLinesGolden(self):
+ opened = self.ReadGolden('text_format_unittest_data.txt')
+ parsed_message = unittest_pb2.TestAllTypes()
+ r = text_format.MergeLines(opened, parsed_message)
+ self.assertIs(r, parsed_message)
+
+ message = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(message)
+ self.assertEqual(message, parsed_message)
+
+ def testParseOneof(self):
+ m = unittest_pb2.TestAllTypes()
+ m.oneof_uint32 = 11
+ m2 = unittest_pb2.TestAllTypes()
+ text_format.Parse(text_format.MessageToString(m), m2)
+ self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
+
+
+class TokenizerTest(basetest.TestCase):
def testSimpleTokenCases(self):
text = ('identifier1:"string1"\n \n\n'
@@ -297,8 +603,9 @@ class TokenizerTest(unittest.TestCase):
'identifiER_4 : 1.1e+2 ID5:-0.23 ID6:\'aaaa\\\'bbbb\'\n'
'ID7 : "aa\\"bb"\n\n\n\n ID8: {A:inf B:-inf C:true D:false}\n'
'ID9: 22 ID10: -111111111111111111 ID11: -22\n'
- 'ID12: 2222222222222222222')
- tokenizer = text_format._Tokenizer(text)
+ '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.ConsumeString, 'string1'),
@@ -325,10 +632,10 @@ class TokenizerTest(unittest.TestCase):
'{',
(tokenizer.ConsumeIdentifier, 'A'),
':',
- (tokenizer.ConsumeFloat, text_format._INFINITY),
+ (tokenizer.ConsumeFloat, float('inf')),
(tokenizer.ConsumeIdentifier, 'B'),
':',
- (tokenizer.ConsumeFloat, -text_format._INFINITY),
+ (tokenizer.ConsumeFloat, -float('inf')),
(tokenizer.ConsumeIdentifier, 'C'),
':',
(tokenizer.ConsumeBool, True),
@@ -347,7 +654,25 @@ class TokenizerTest(unittest.TestCase):
(tokenizer.ConsumeInt32, -22),
(tokenizer.ConsumeIdentifier, 'ID12'),
':',
- (tokenizer.ConsumeUint64, 2222222222222222222)]
+ (tokenizer.ConsumeUint64, 2222222222222222222),
+ (tokenizer.ConsumeIdentifier, 'ID13'),
+ ':',
+ (tokenizer.ConsumeFloat, 1.23456),
+ (tokenizer.ConsumeIdentifier, 'ID14'),
+ ':',
+ (tokenizer.ConsumeFloat, 1.2e+2),
+ (tokenizer.ConsumeIdentifier, 'false_bool'),
+ ':',
+ (tokenizer.ConsumeBool, False),
+ (tokenizer.ConsumeIdentifier, 'true_BOOL'),
+ ':',
+ (tokenizer.ConsumeBool, True),
+ (tokenizer.ConsumeIdentifier, 'true_bool1'),
+ ':',
+ (tokenizer.ConsumeBool, True),
+ (tokenizer.ConsumeIdentifier, 'false_BOOL1'),
+ ':',
+ (tokenizer.ConsumeBool, False)]
i = 0
while not tokenizer.AtEnd():
@@ -366,7 +691,7 @@ class TokenizerTest(unittest.TestCase):
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)
+ 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())
@@ -380,7 +705,7 @@ class TokenizerTest(unittest.TestCase):
self.assertTrue(tokenizer.AtEnd())
text = '-0 -0 0 0'
- tokenizer = text_format._Tokenizer(text)
+ tokenizer = text_format._Tokenizer(text.splitlines())
self.assertEqual(0, tokenizer.ConsumeUint32())
self.assertEqual(0, tokenizer.ConsumeUint64())
self.assertEqual(0, tokenizer.ConsumeUint32())
@@ -389,40 +714,30 @@ class TokenizerTest(unittest.TestCase):
def testConsumeByteString(self):
text = '"string1\''
- tokenizer = text_format._Tokenizer(text)
+ tokenizer = text_format._Tokenizer(text.splitlines())
self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
text = 'string1"'
- tokenizer = text_format._Tokenizer(text)
+ tokenizer = text_format._Tokenizer(text.splitlines())
self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
text = '\n"\\xt"'
- tokenizer = text_format._Tokenizer(text)
+ tokenizer = text_format._Tokenizer(text.splitlines())
self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
text = '\n"\\"'
- tokenizer = text_format._Tokenizer(text)
+ tokenizer = text_format._Tokenizer(text.splitlines())
self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
text = '\n"\\x"'
- tokenizer = text_format._Tokenizer(text)
+ 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)
+ tokenizer = text_format._Tokenizer(text.splitlines())
self.assertRaises(text_format.ParseError, tokenizer.ConsumeBool)
- def testInfNan(self):
- # Make sure our infinity and NaN definitions are sound.
- self.assertEquals(float, type(text_format._INFINITY))
- self.assertEquals(float, type(text_format._NAN))
- self.assertTrue(text_format._NAN != text_format._NAN)
-
- inf_times_zero = text_format._INFINITY * 0
- self.assertTrue(inf_times_zero != inf_times_zero)
- self.assertTrue(text_format._INFINITY > 0)
-
if __name__ == '__main__':
- unittest.main()
+ basetest.main()
diff --git a/python/google/protobuf/internal/type_checkers.py b/python/google/protobuf/internal/type_checkers.py
index 2b3cd4d..56d2646 100755
--- a/python/google/protobuf/internal/type_checkers.py
+++ b/python/google/protobuf/internal/type_checkers.py
@@ -1,6 +1,6 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -28,6 +28,10 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#PY25 compatible for GAE.
+#
+# Copyright 2008 Google Inc. All Rights Reserved.
+
"""Provides type checking routines.
This module defines type checking utilities in the forms of dictionaries:
@@ -45,6 +49,9 @@ TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization
__author__ = 'robinson@google.com (Will Robinson)'
+import sys ##PY25
+if sys.version < '2.6': bytes = str ##PY25
+from google.protobuf.internal import api_implementation
from google.protobuf.internal import decoder
from google.protobuf.internal import encoder
from google.protobuf.internal import wire_format
@@ -53,21 +60,22 @@ from google.protobuf import descriptor
_FieldDescriptor = descriptor.FieldDescriptor
-def GetTypeChecker(cpp_type, field_type):
+def GetTypeChecker(field):
"""Returns a type checker for a message field of the specified types.
Args:
- cpp_type: C++ type of the field (see descriptor.py).
- field_type: Protocol message field type (see descriptor.py).
+ field: FieldDescriptor object for this field.
Returns:
An instance of TypeChecker which can be used to verify the types
of values assigned to a field of the specified type.
"""
- if (cpp_type == _FieldDescriptor.CPPTYPE_STRING and
- field_type == _FieldDescriptor.TYPE_STRING):
+ if (field.cpp_type == _FieldDescriptor.CPPTYPE_STRING and
+ field.type == _FieldDescriptor.TYPE_STRING):
return UnicodeValueChecker()
- return _VALUE_CHECKERS[cpp_type]
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM:
+ return EnumValueChecker(field.enum_type)
+ return _VALUE_CHECKERS[field.cpp_type]
# None of the typecheckers below make any attempt to guard against people
@@ -85,10 +93,15 @@ class TypeChecker(object):
self._acceptable_types = acceptable_types
def CheckValue(self, proposed_value):
+ """Type check the provided value and return it.
+
+ The returned value might have been normalized to another type.
+ """
if not isinstance(proposed_value, self._acceptable_types):
message = ('%.1024r has type %s, but expected one of: %s' %
(proposed_value, type(proposed_value), self._acceptable_types))
raise TypeError(message)
+ return proposed_value
# IntValueChecker and its subclasses perform integer type-checks
@@ -104,28 +117,54 @@ class IntValueChecker(object):
raise TypeError(message)
if not self._MIN <= proposed_value <= self._MAX:
raise ValueError('Value out of range: %d' % proposed_value)
+ # 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.
+ proposed_value = self._TYPE(proposed_value)
+ return proposed_value
+
+
+class EnumValueChecker(object):
+
+ """Checker used for enum fields. Performs type-check and range check."""
+
+ def __init__(self, enum_type):
+ self._enum_type = enum_type
+
+ def CheckValue(self, proposed_value):
+ if not isinstance(proposed_value, (int, long)):
+ message = ('%.1024r has type %s, but expected one of: %s' %
+ (proposed_value, type(proposed_value), (int, long)))
+ raise TypeError(message)
+ if proposed_value not in self._enum_type.values_by_number:
+ raise ValueError('Unknown enum value: %d' % proposed_value)
+ return proposed_value
class UnicodeValueChecker(object):
- """Checker used for string fields."""
+ """Checker used for string fields.
+
+ Always returns a unicode value, even if the input is of type str.
+ """
def CheckValue(self, proposed_value):
- if not isinstance(proposed_value, (str, unicode)):
+ if not isinstance(proposed_value, (bytes, unicode)):
message = ('%.1024r has type %s, but expected one of: %s' %
- (proposed_value, type(proposed_value), (str, unicode)))
+ (proposed_value, type(proposed_value), (bytes, unicode)))
raise TypeError(message)
- # If the value is of type 'str' make sure that it is in 7-bit ASCII
+ # If the value is of type 'bytes' make sure that it is in 7-bit ASCII
# encoding.
- if isinstance(proposed_value, str):
+ if isinstance(proposed_value, bytes):
try:
- unicode(proposed_value, 'ascii')
+ proposed_value = proposed_value.decode('ascii')
except UnicodeDecodeError:
- raise ValueError('%.1024r has type str, but isn\'t in 7-bit ASCII '
+ raise ValueError('%.1024r has type bytes, but isn\'t in 7-bit ASCII '
'encoding. Non-ASCII strings must be converted to '
'unicode objects before being added.' %
(proposed_value))
+ return proposed_value
class Int32ValueChecker(IntValueChecker):
@@ -133,21 +172,25 @@ class Int32ValueChecker(IntValueChecker):
# efficient.
_MIN = -2147483648
_MAX = 2147483647
+ _TYPE = int
class Uint32ValueChecker(IntValueChecker):
_MIN = 0
_MAX = (1 << 32) - 1
+ _TYPE = int
class Int64ValueChecker(IntValueChecker):
_MIN = -(1 << 63)
_MAX = (1 << 63) - 1
+ _TYPE = long
class Uint64ValueChecker(IntValueChecker):
_MIN = 0
_MAX = (1 << 64) - 1
+ _TYPE = long
# Type-checkers for all scalar CPPTYPEs.
@@ -161,8 +204,7 @@ _VALUE_CHECKERS = {
_FieldDescriptor.CPPTYPE_FLOAT: TypeChecker(
float, int, long),
_FieldDescriptor.CPPTYPE_BOOL: TypeChecker(bool, int),
- _FieldDescriptor.CPPTYPE_ENUM: Int32ValueChecker(),
- _FieldDescriptor.CPPTYPE_STRING: TypeChecker(str),
+ _FieldDescriptor.CPPTYPE_STRING: TypeChecker(bytes),
}
diff --git a/python/google/protobuf/internal/unknown_fields_test.py b/python/google/protobuf/internal/unknown_fields_test.py
new file mode 100755
index 0000000..7177560
--- /dev/null
+++ b/python/google/protobuf/internal/unknown_fields_test.py
@@ -0,0 +1,231 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# 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 preservation of unknown fields in the pure Python implementation."""
+
+__author__ = 'bohdank@google.com (Bohdan Koval)'
+
+from google.apputils import basetest
+from google.protobuf import unittest_mset_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf.internal import encoder
+from google.protobuf.internal import missing_enum_values_pb2
+from google.protobuf.internal import test_util
+from google.protobuf.internal import type_checkers
+
+
+class UnknownFieldsTest(basetest.TestCase):
+
+ def setUp(self):
+ self.descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
+ self.all_fields = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(self.all_fields)
+ self.all_fields_data = self.all_fields.SerializeToString()
+ self.empty_message = unittest_pb2.TestEmptyMessage()
+ self.empty_message.ParseFromString(self.all_fields_data)
+ self.unknown_fields = self.empty_message._unknown_fields
+
+ def GetField(self, name):
+ field_descriptor = self.descriptor.fields_by_name[name]
+ wire_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type]
+ field_tag = encoder.TagBytes(field_descriptor.number, wire_type)
+ result_dict = {}
+ for tag_bytes, value in self.unknown_fields:
+ if tag_bytes == field_tag:
+ decoder = unittest_pb2.TestAllTypes._decoders_by_tag[tag_bytes][0]
+ decoder(value, 0, len(value), self.all_fields, result_dict)
+ return result_dict[field_descriptor]
+
+ def testEnum(self):
+ value = self.GetField('optional_nested_enum')
+ self.assertEqual(self.all_fields.optional_nested_enum, value)
+
+ def testRepeatedEnum(self):
+ value = self.GetField('repeated_nested_enum')
+ self.assertEqual(self.all_fields.repeated_nested_enum, value)
+
+ def testVarint(self):
+ value = self.GetField('optional_int32')
+ self.assertEqual(self.all_fields.optional_int32, value)
+
+ def testFixed32(self):
+ value = self.GetField('optional_fixed32')
+ self.assertEqual(self.all_fields.optional_fixed32, value)
+
+ def testFixed64(self):
+ value = self.GetField('optional_fixed64')
+ self.assertEqual(self.all_fields.optional_fixed64, value)
+
+ def testLengthDelimited(self):
+ value = self.GetField('optional_string')
+ self.assertEqual(self.all_fields.optional_string, value)
+
+ def testGroup(self):
+ value = self.GetField('optionalgroup')
+ self.assertEqual(self.all_fields.optionalgroup, value)
+
+ def testSerialize(self):
+ data = self.empty_message.SerializeToString()
+
+ # Don't use assertEqual because we don't want to dump raw binary data to
+ # stdout.
+ self.assertTrue(data == self.all_fields_data)
+
+ def testCopyFrom(self):
+ message = unittest_pb2.TestEmptyMessage()
+ message.CopyFrom(self.empty_message)
+ self.assertEqual(self.unknown_fields, message._unknown_fields)
+
+ def testMergeFrom(self):
+ message = unittest_pb2.TestAllTypes()
+ message.optional_int32 = 1
+ message.optional_uint32 = 2
+ source = unittest_pb2.TestEmptyMessage()
+ source.ParseFromString(message.SerializeToString())
+
+ message.ClearField('optional_int32')
+ message.optional_int64 = 3
+ message.optional_uint32 = 4
+ destination = unittest_pb2.TestEmptyMessage()
+ destination.ParseFromString(message.SerializeToString())
+ unknown_fields = destination._unknown_fields[:]
+
+ destination.MergeFrom(source)
+ self.assertEqual(unknown_fields + source._unknown_fields,
+ destination._unknown_fields)
+
+ def testClear(self):
+ self.empty_message.Clear()
+ self.assertEqual(0, len(self.empty_message._unknown_fields))
+
+ def testByteSize(self):
+ self.assertEqual(self.all_fields.ByteSize(), self.empty_message.ByteSize())
+
+ def testUnknownExtensions(self):
+ message = unittest_pb2.TestEmptyMessageWithExtensions()
+ message.ParseFromString(self.all_fields_data)
+ self.assertEqual(self.empty_message._unknown_fields,
+ message._unknown_fields)
+
+ def testListFields(self):
+ # Make sure ListFields doesn't return unknown fields.
+ self.assertEqual(0, len(self.empty_message.ListFields()))
+
+ def testSerializeMessageSetWireFormatUnknownExtension(self):
+ # Create a message using the message set wire format with an unknown
+ # message.
+ raw = unittest_mset_pb2.RawMessageSet()
+
+ # Add an unknown extension.
+ item = raw.item.add()
+ item.type_id = 1545009
+ message1 = unittest_mset_pb2.TestMessageSetExtension1()
+ message1.i = 12345
+ item.message = message1.SerializeToString()
+
+ serialized = raw.SerializeToString()
+
+ # Parse message using the message set wire format.
+ proto = unittest_mset_pb2.TestMessageSet()
+ proto.MergeFromString(serialized)
+
+ # Verify that the unknown extension is serialized unchanged
+ reserialized = proto.SerializeToString()
+ new_raw = unittest_mset_pb2.RawMessageSet()
+ new_raw.MergeFromString(reserialized)
+ self.assertEqual(raw, new_raw)
+
+ def testEquals(self):
+ message = unittest_pb2.TestEmptyMessage()
+ message.ParseFromString(self.all_fields_data)
+ self.assertEqual(self.empty_message, message)
+
+ self.all_fields.ClearField('optional_string')
+ message.ParseFromString(self.all_fields.SerializeToString())
+ self.assertNotEqual(self.empty_message, message)
+
+
+class UnknownFieldsTest(basetest.TestCase):
+
+ def setUp(self):
+ self.descriptor = missing_enum_values_pb2.TestEnumValues.DESCRIPTOR
+
+ self.message = missing_enum_values_pb2.TestEnumValues()
+ self.message.optional_nested_enum = (
+ missing_enum_values_pb2.TestEnumValues.ZERO)
+ self.message.repeated_nested_enum.extend([
+ missing_enum_values_pb2.TestEnumValues.ZERO,
+ missing_enum_values_pb2.TestEnumValues.ONE,
+ ])
+ self.message.packed_nested_enum.extend([
+ missing_enum_values_pb2.TestEnumValues.ZERO,
+ missing_enum_values_pb2.TestEnumValues.ONE,
+ ])
+ self.message_data = self.message.SerializeToString()
+ self.missing_message = missing_enum_values_pb2.TestMissingEnumValues()
+ self.missing_message.ParseFromString(self.message_data)
+ self.unknown_fields = self.missing_message._unknown_fields
+
+ def GetField(self, name):
+ field_descriptor = self.descriptor.fields_by_name[name]
+ wire_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type]
+ field_tag = encoder.TagBytes(field_descriptor.number, wire_type)
+ result_dict = {}
+ for tag_bytes, value in self.unknown_fields:
+ if tag_bytes == field_tag:
+ decoder = missing_enum_values_pb2.TestEnumValues._decoders_by_tag[
+ tag_bytes][0]
+ decoder(value, 0, len(value), self.message, result_dict)
+ return result_dict[field_descriptor]
+
+ def testUnknownEnumValue(self):
+ self.assertFalse(self.missing_message.HasField('optional_nested_enum'))
+ value = self.GetField('optional_nested_enum')
+ self.assertEqual(self.message.optional_nested_enum, value)
+
+ def testUnknownRepeatedEnumValue(self):
+ value = self.GetField('repeated_nested_enum')
+ self.assertEqual(self.message.repeated_nested_enum, value)
+
+ def testUnknownPackedEnumValue(self):
+ value = self.GetField('packed_nested_enum')
+ self.assertEqual(self.message.packed_nested_enum, value)
+
+ def testRoundTrip(self):
+ new_message = missing_enum_values_pb2.TestEnumValues()
+ new_message.ParseFromString(self.missing_message.SerializeToString())
+ self.assertEqual(self.message, new_message)
+
+
+if __name__ == '__main__':
+ basetest.main()
diff --git a/python/google/protobuf/internal/wire_format.py b/python/google/protobuf/internal/wire_format.py
index c941fe1..883f525 100755
--- a/python/google/protobuf/internal/wire_format.py
+++ b/python/google/protobuf/internal/wire_format.py
@@ -1,6 +1,6 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
diff --git a/python/google/protobuf/internal/wire_format_test.py b/python/google/protobuf/internal/wire_format_test.py
index 7600778..f39035c 100755
--- a/python/google/protobuf/internal/wire_format_test.py
+++ b/python/google/protobuf/internal/wire_format_test.py
@@ -2,7 +2,7 @@
#
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -34,12 +34,12 @@
__author__ = 'robinson@google.com (Will Robinson)'
-import unittest
+from google.apputils import basetest
from google.protobuf import message
from google.protobuf.internal import wire_format
-class WireFormatTest(unittest.TestCase):
+class WireFormatTest(basetest.TestCase):
def testPackTag(self):
field_number = 0xabc
@@ -195,7 +195,7 @@ class WireFormatTest(unittest.TestCase):
# Test UTF-8 string byte size calculation.
# 1 byte for tag, 1 byte for length, 8 bytes for content.
self.assertEqual(10, wire_format.StringByteSize(
- 5, unicode('\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82', 'utf-8')))
+ 5, b'\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82'.decode('utf-8')))
class MockMessage(object):
def __init__(self, byte_size):
@@ -250,4 +250,4 @@ class WireFormatTest(unittest.TestCase):
if __name__ == '__main__':
- unittest.main()
+ basetest.main()
diff --git a/python/google/protobuf/message.py b/python/google/protobuf/message.py
index f839847..c186452 100755
--- a/python/google/protobuf/message.py
+++ b/python/google/protobuf/message.py
@@ -1,6 +1,6 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -67,14 +67,28 @@ class Message(object):
DESCRIPTOR = None
+ def __deepcopy__(self, memo=None):
+ clone = type(self)()
+ clone.MergeFrom(self)
+ return clone
+
def __eq__(self, other_msg):
+ """Recursively compares two messages by value and structure."""
raise NotImplementedError
def __ne__(self, other_msg):
# Can't just say self != other_msg, since that would infinitely recurse. :)
return not self == other_msg
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
def __str__(self):
+ """Outputs a human-readable representation of the message."""
+ raise NotImplementedError
+
+ def __unicode__(self):
+ """Outputs a human-readable representation of the message."""
raise NotImplementedError
def MergeFrom(self, other_msg):
@@ -163,7 +177,11 @@ class Message(object):
raise NotImplementedError
def ParseFromString(self, serialized):
- """Like MergeFromString(), except we clear the object first."""
+ """Parse serialized protocol buffer data into this message.
+
+ Like MergeFromString(), except we clear the object first and
+ do not return the value that MergeFromString returns.
+ """
self.Clear()
self.MergeFromString(serialized)
@@ -215,6 +233,9 @@ class Message(object):
raise NotImplementedError
def HasField(self, field_name):
+ """Checks if a certain field is set for the message. Note if the
+ field_name is not defined in the message descriptor, ValueError will be
+ raised."""
raise NotImplementedError
def ClearField(self, field_name):
@@ -252,3 +273,12 @@ class Message(object):
via a previous _SetListener() call.
"""
raise NotImplementedError
+
+ def __getstate__(self):
+ """Support the pickle protocol."""
+ return dict(serialized=self.SerializePartialToString())
+
+ def __setstate__(self, state):
+ """Support the pickle protocol."""
+ self.__init__()
+ self.ParseFromString(state['serialized'])
diff --git a/python/google/protobuf/message_factory.py b/python/google/protobuf/message_factory.py
new file mode 100644
index 0000000..7fd7bec
--- /dev/null
+++ b/python/google/protobuf/message_factory.py
@@ -0,0 +1,155 @@
+# 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.
+
+#PY25 compatible for GAE.
+#
+# Copyright 2012 Google Inc. All Rights Reserved.
+
+"""Provides a factory class for generating dynamic messages.
+
+The easiest way to use this class is if you have access to the FileDescriptor
+protos containing the messages you want to create you can just do the following:
+
+message_classes = message_factory.GetMessages(iterable_of_file_descriptors)
+my_proto_instance = message_classes['some.proto.package.MessageName']()
+"""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+import sys ##PY25
+from google.protobuf import descriptor_database
+from google.protobuf import descriptor_pool
+from google.protobuf import message
+from google.protobuf import reflection
+
+
+class MessageFactory(object):
+ """Factory for creating Proto2 messages from descriptors in a pool."""
+
+ def __init__(self, pool=None):
+ """Initializes a new factory."""
+ self.pool = (pool or descriptor_pool.DescriptorPool(
+ descriptor_database.DescriptorDatabase()))
+
+ # local cache of all classes built from protobuf descriptors
+ self._classes = {}
+
+ 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.
+ """
+ if descriptor.full_name not in self._classes:
+ descriptor_name = descriptor.name
+ if sys.version_info[0] < 3: ##PY25
+##!PY25 if str is bytes: # PY2
+ descriptor_name = descriptor.name.encode('ascii', 'ignore')
+ result_class = reflection.GeneratedProtocolMessageType(
+ descriptor_name,
+ (message.Message,),
+ {'DESCRIPTOR': descriptor, '__module__': None})
+ # If module not set, it wrongly points to the reflection.py module.
+ self._classes[descriptor.full_name] = result_class
+ for field in descriptor.fields:
+ if field.message_type:
+ self.GetPrototype(field.message_type)
+ for extension in result_class.DESCRIPTOR.extensions:
+ if extension.containing_type.full_name not in self._classes:
+ self.GetPrototype(extension.containing_type)
+ extended_class = self._classes[extension.containing_type.full_name]
+ extended_class.RegisterExtension(extension)
+ return self._classes[descriptor.full_name]
+
+ def GetMessages(self, files):
+ """Gets all the messages from a specified file.
+
+ This will find and resolve dependencies, failing if the descriptor
+ pool cannot satisfy them.
+
+ 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.
+ """
+ result = {}
+ for file_name in files:
+ file_desc = self.pool.FindFileByName(file_name)
+ for name, msg in file_desc.message_types_by_name.iteritems():
+ if file_desc.package:
+ full_name = '.'.join([file_desc.package, name])
+ else:
+ full_name = msg.name
+ result[full_name] = self.GetPrototype(
+ self.pool.FindMessageTypeByName(full_name))
+
+ # While the extension FieldDescriptors are created by the descriptor pool,
+ # the python classes created in the factory need them to be registered
+ # explicitly, which is done below.
+ #
+ # The call to RegisterExtension will specifically check if the
+ # extension was already registered on the object and either
+ # ignore the registration if the original was the same, or raise
+ # an error if they were different.
+
+ for name, extension in file_desc.extensions_by_name.iteritems():
+ if extension.containing_type.full_name not in self._classes:
+ self.GetPrototype(extension.containing_type)
+ extended_class = self._classes[extension.containing_type.full_name]
+ extended_class.RegisterExtension(extension)
+ return result
+
+
+_FACTORY = MessageFactory()
+
+
+def GetMessages(file_protos):
+ """Builds a dictionary of all the messages available in a set of files.
+
+ Args:
+ file_protos: A sequence of file protos to build messages out of.
+
+ 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.
+ """
+ for file_proto in file_protos:
+ _FACTORY.pool.Add(file_proto)
+ return _FACTORY.GetMessages([file_proto.name for file_proto in file_protos])
diff --git a/python/google/protobuf/pyext/README b/python/google/protobuf/pyext/README
new file mode 100644
index 0000000..6d61cb4
--- /dev/null
+++ b/python/google/protobuf/pyext/README
@@ -0,0 +1,6 @@
+This is the 'v2' C++ implementation for python proto2.
+
+It is active when:
+
+PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp
+PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION=2
diff --git a/MODULE_LICENSE_BSD_LIKE b/python/google/protobuf/pyext/__init__.py
index e69de29..e69de29 100644
--- a/MODULE_LICENSE_BSD_LIKE
+++ b/python/google/protobuf/pyext/__init__.py
diff --git a/python/google/protobuf/pyext/cpp_message.py b/python/google/protobuf/pyext/cpp_message.py
new file mode 100644
index 0000000..dcf34a0
--- /dev/null
+++ b/python/google/protobuf/pyext/cpp_message.py
@@ -0,0 +1,61 @@
+# 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.
+
+"""Protocol message implementation hooks for C++ implementation.
+
+Contains helper functions used to create protocol message classes from
+Descriptor objects at runtime backed by the protocol buffer C++ API.
+"""
+
+__author__ = 'tibell@google.com (Johan Tibell)'
+
+from google.protobuf.pyext import _message
+from google.protobuf import message
+
+
+def NewMessage(bases, message_descriptor, dictionary):
+ """Creates a new protocol message *class*."""
+ new_bases = []
+ for base in bases:
+ if base is message.Message:
+ # _message.Message must come before message.Message as it
+ # overrides methods in that class.
+ new_bases.append(_message.Message)
+ new_bases.append(base)
+ return tuple(new_bases)
+
+
+def InitMessage(message_descriptor, cls):
+ """Constructs a new message instance (called before instance's __init__)."""
+
+ def SubInit(self, **kwargs):
+ super(cls, self).__init__(message_descriptor, **kwargs)
+ cls.__init__ = SubInit
+ cls.AddDescriptors(message_descriptor)
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc
new file mode 100644
index 0000000..3f7be73
--- /dev/null
+++ b/python/google/protobuf/pyext/descriptor.cc
@@ -0,0 +1,357 @@
+// 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: petar@google.com (Petar Petrov)
+
+#include <Python.h>
+#include <string>
+
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/pyext/descriptor.h>
+#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+
+#define C(str) const_cast<char*>(str)
+
+#if PY_MAJOR_VERSION >= 3
+ #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
+ #define PyInt_FromLong PyLong_FromLong
+ #if PY_VERSION_HEX < 0x03030000
+ #error "Python 3.0 - 3.2 are not supported."
+ #else
+ #define PyString_AsString(ob) \
+ (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AS_STRING(ob))
+ #endif
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+
+#ifndef PyVarObject_HEAD_INIT
+#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
+#endif
+#ifndef Py_TYPE
+#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
+#endif
+
+
+static google::protobuf::DescriptorPool* g_descriptor_pool = NULL;
+
+namespace cfield_descriptor {
+
+static void Dealloc(CFieldDescriptor* self) {
+ Py_CLEAR(self->descriptor_field);
+ Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+static PyObject* GetFullName(CFieldDescriptor* self, void *closure) {
+ return PyString_FromStringAndSize(
+ self->descriptor->full_name().c_str(),
+ self->descriptor->full_name().size());
+}
+
+static PyObject* GetName(CFieldDescriptor *self, void *closure) {
+ return PyString_FromStringAndSize(
+ self->descriptor->name().c_str(),
+ self->descriptor->name().size());
+}
+
+static PyObject* GetCppType(CFieldDescriptor *self, void *closure) {
+ return PyInt_FromLong(self->descriptor->cpp_type());
+}
+
+static PyObject* GetLabel(CFieldDescriptor *self, void *closure) {
+ return PyInt_FromLong(self->descriptor->label());
+}
+
+static PyObject* GetID(CFieldDescriptor *self, void *closure) {
+ return PyLong_FromVoidPtr(self);
+}
+
+static PyGetSetDef Getters[] = {
+ { C("full_name"), (getter)GetFullName, NULL, "Full name", NULL},
+ { C("name"), (getter)GetName, NULL, "last name", NULL},
+ { C("cpp_type"), (getter)GetCppType, NULL, "C++ Type", NULL},
+ { C("label"), (getter)GetLabel, NULL, "Label", NULL},
+ { C("id"), (getter)GetID, NULL, "ID", NULL},
+ {NULL}
+};
+
+} // namespace cfield_descriptor
+
+PyTypeObject CFieldDescriptor_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ C("google.protobuf.internal."
+ "_net_proto2___python."
+ "CFieldDescriptor"), // tp_name
+ sizeof(CFieldDescriptor), // tp_basicsize
+ 0, // tp_itemsize
+ (destructor)cfield_descriptor::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
+ C("A Field Descriptor"), // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ cfield_descriptor::Getters, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ PyType_GenericAlloc, // tp_alloc
+ PyType_GenericNew, // tp_new
+ PyObject_Del, // tp_free
+};
+
+namespace cdescriptor_pool {
+
+static void Dealloc(CDescriptorPool* self) {
+ Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+static PyObject* NewCDescriptor(
+ const google::protobuf::FieldDescriptor* field_descriptor) {
+ CFieldDescriptor* cfield_descriptor = PyObject_New(
+ CFieldDescriptor, &CFieldDescriptor_Type);
+ if (cfield_descriptor == NULL) {
+ return NULL;
+ }
+ cfield_descriptor->descriptor = field_descriptor;
+ cfield_descriptor->descriptor_field = NULL;
+
+ return reinterpret_cast<PyObject*>(cfield_descriptor);
+}
+
+PyObject* FindFieldByName(CDescriptorPool* self, PyObject* name) {
+ const char* full_field_name = PyString_AsString(name);
+ if (full_field_name == NULL) {
+ return NULL;
+ }
+
+ const google::protobuf::FieldDescriptor* field_descriptor = NULL;
+
+ field_descriptor = self->pool->FindFieldByName(full_field_name);
+
+ if (field_descriptor == NULL) {
+ PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s",
+ full_field_name);
+ return NULL;
+ }
+
+ return NewCDescriptor(field_descriptor);
+}
+
+PyObject* FindExtensionByName(CDescriptorPool* self, PyObject* arg) {
+ const char* full_field_name = PyString_AsString(arg);
+ if (full_field_name == NULL) {
+ return NULL;
+ }
+
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ self->pool->FindExtensionByName(full_field_name);
+ if (field_descriptor == NULL) {
+ PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s",
+ full_field_name);
+ return NULL;
+ }
+
+ return NewCDescriptor(field_descriptor);
+}
+
+static PyMethodDef Methods[] = {
+ { C("FindFieldByName"),
+ (PyCFunction)FindFieldByName,
+ METH_O,
+ C("Searches for a field descriptor by full name.") },
+ { C("FindExtensionByName"),
+ (PyCFunction)FindExtensionByName,
+ METH_O,
+ C("Searches for extension descriptor by full name.") },
+ {NULL}
+};
+
+} // namespace cdescriptor_pool
+
+PyTypeObject CDescriptorPool_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ C("google.protobuf.internal."
+ "_net_proto2___python."
+ "CFieldDescriptor"), // tp_name
+ sizeof(CDescriptorPool), // tp_basicsize
+ 0, // tp_itemsize
+ (destructor)cdescriptor_pool::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
+ C("A Descriptor Pool"), // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ cdescriptor_pool::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
+ PyType_GenericAlloc, // tp_alloc
+ PyType_GenericNew, // tp_new
+ PyObject_Del, // tp_free
+};
+
+google::protobuf::DescriptorPool* GetDescriptorPool() {
+ if (g_descriptor_pool == NULL) {
+ g_descriptor_pool = new google::protobuf::DescriptorPool(
+ google::protobuf::DescriptorPool::generated_pool());
+ }
+ return g_descriptor_pool;
+}
+
+PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args) {
+ CDescriptorPool* cdescriptor_pool = PyObject_New(
+ CDescriptorPool, &CDescriptorPool_Type);
+ if (cdescriptor_pool == NULL) {
+ return NULL;
+ }
+ cdescriptor_pool->pool = GetDescriptorPool();
+ return reinterpret_cast<PyObject*>(cdescriptor_pool);
+}
+
+
+// Collects errors that occur during proto file building to allow them to be
+// propagated in the python exception instead of only living in ERROR logs.
+class BuildFileErrorCollector : public google::protobuf::DescriptorPool::ErrorCollector {
+ public:
+ BuildFileErrorCollector() : error_message(""), had_errors(false) {}
+
+ void AddError(const string& filename, const string& element_name,
+ const Message* descriptor, ErrorLocation location,
+ const string& message) {
+ // Replicates the logging behavior that happens in the C++ implementation
+ // when an error collector is not passed in.
+ if (!had_errors) {
+ error_message +=
+ ("Invalid proto descriptor for file \"" + filename + "\":\n");
+ }
+ // As this only happens on failure and will result in the program not
+ // running at all, no effort is made to optimize this string manipulation.
+ error_message += (" " + element_name + ": " + message + "\n");
+ }
+
+ string error_message;
+ bool had_errors;
+};
+
+PyObject* Python_BuildFile(PyObject* ignored, PyObject* arg) {
+ char* message_type;
+ Py_ssize_t message_len;
+
+ if (PyBytes_AsStringAndSize(arg, &message_type, &message_len) < 0) {
+ return NULL;
+ }
+
+ google::protobuf::FileDescriptorProto file_proto;
+ if (!file_proto.ParseFromArray(message_type, message_len)) {
+ PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!");
+ return NULL;
+ }
+
+ if (google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
+ file_proto.name()) != NULL) {
+ Py_RETURN_NONE;
+ }
+
+ BuildFileErrorCollector error_collector;
+ const google::protobuf::FileDescriptor* descriptor =
+ GetDescriptorPool()->BuildFileCollectingErrors(file_proto,
+ &error_collector);
+ if (descriptor == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "Couldn't build proto file into descriptor pool!\n%s",
+ error_collector.error_message.c_str());
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+bool InitDescriptor() {
+ CFieldDescriptor_Type.tp_new = PyType_GenericNew;
+ if (PyType_Ready(&CFieldDescriptor_Type) < 0)
+ return false;
+
+ CDescriptorPool_Type.tp_new = PyType_GenericNew;
+ if (PyType_Ready(&CDescriptorPool_Type) < 0)
+ return false;
+
+ return true;
+}
+
+} // namespace python
+} // namespace protobuf
+} // namespace google
diff --git a/python/google/protobuf/pyext/descriptor.h b/python/google/protobuf/pyext/descriptor.h
new file mode 100644
index 0000000..ae7a1b9
--- /dev/null
+++ b/python/google/protobuf/pyext/descriptor.h
@@ -0,0 +1,96 @@
+// 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: petar@google.com (Petar Petrov)
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_H__
+
+#include <Python.h>
+#include <structmember.h>
+
+#include <google/protobuf/descriptor.h>
+
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+typedef struct CFieldDescriptor {
+ PyObject_HEAD
+
+ // The proto2 descriptor that this object represents.
+ const google::protobuf::FieldDescriptor* descriptor;
+
+ // Reference to the original field object in the Python DESCRIPTOR.
+ PyObject* descriptor_field;
+} CFieldDescriptor;
+
+typedef struct {
+ PyObject_HEAD
+
+ const google::protobuf::DescriptorPool* pool;
+} CDescriptorPool;
+
+extern PyTypeObject CFieldDescriptor_Type;
+
+extern PyTypeObject CDescriptorPool_Type;
+
+namespace cdescriptor_pool {
+
+// Looks up a field by name. Returns a CDescriptor corresponding to
+// the field on success, or NULL on failure.
+//
+// Returns a new reference.
+PyObject* FindFieldByName(CDescriptorPool* self, PyObject* name);
+
+// Looks up an extension by name. Returns a CDescriptor corresponding
+// to the field on success, or NULL on failure.
+//
+// Returns a new reference.
+PyObject* FindExtensionByName(CDescriptorPool* self, PyObject* arg);
+
+} // namespace cdescriptor_pool
+
+PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args);
+PyObject* Python_BuildFile(PyObject* ignored, PyObject* args);
+bool InitDescriptor();
+google::protobuf::DescriptorPool* GetDescriptorPool();
+
+} // namespace python
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_H__
diff --git a/python/google/protobuf/pyext/descriptor_cpp2_test.py b/python/google/protobuf/pyext/descriptor_cpp2_test.py
new file mode 100644
index 0000000..3cf45a2
--- /dev/null
+++ b/python/google/protobuf/pyext/descriptor_cpp2_test.py
@@ -0,0 +1,58 @@
+#! /usr/bin/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.
+
+"""Tests for google.protobuf.pyext behavior."""
+
+__author__ = 'anuraag@google.com (Anuraag Agrawal)'
+
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION'] = '2'
+
+# We must set the implementation version above before the google3 imports.
+# pylint: disable=g-import-not-at-top
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+# Run all tests from the original module by putting them in our namespace.
+# pylint: disable=wildcard-import
+from google.protobuf.internal.descriptor_test import *
+
+
+class ConfirmCppApi2Test(basetest.TestCase):
+
+ def testImplementationSetting(self):
+ self.assertEqual('cpp', api_implementation.Type())
+ self.assertEqual(2, api_implementation.Version())
+
+
+if __name__ == '__main__':
+ basetest.main()
diff --git a/python/google/protobuf/pyext/extension_dict.cc b/python/google/protobuf/pyext/extension_dict.cc
new file mode 100644
index 0000000..3861c79
--- /dev/null
+++ b/python/google/protobuf/pyext/extension_dict.cc
@@ -0,0 +1,338 @@
+// 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: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#include <google/protobuf/pyext/extension_dict.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/pyext/descriptor.h>
+#include <google/protobuf/pyext/message.h>
+#include <google/protobuf/pyext/repeated_composite_container.h>
+#include <google/protobuf/pyext/repeated_scalar_container.h>
+#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+#include <google/protobuf/stubs/shared_ptr.h>
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+extern google::protobuf::DynamicMessageFactory* global_message_factory;
+
+namespace extension_dict {
+
+// TODO(tibell): Always use self->message for clarity, just like in
+// RepeatedCompositeContainer.
+static google::protobuf::Message* GetMessage(ExtensionDict* self) {
+ if (self->parent != NULL) {
+ return self->parent->message;
+ } else {
+ return self->message;
+ }
+}
+
+CFieldDescriptor* InternalGetCDescriptorFromExtension(PyObject* extension) {
+ PyObject* cdescriptor = PyObject_GetAttrString(extension, "_cdescriptor");
+ if (cdescriptor == NULL) {
+ PyErr_SetString(PyExc_KeyError, "Unregistered extension.");
+ return NULL;
+ }
+ if (!PyObject_TypeCheck(cdescriptor, &CFieldDescriptor_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Not a CFieldDescriptor");
+ Py_DECREF(cdescriptor);
+ return NULL;
+ }
+ CFieldDescriptor* descriptor =
+ reinterpret_cast<CFieldDescriptor*>(cdescriptor);
+ return descriptor;
+}
+
+PyObject* len(ExtensionDict* self) {
+#if PY_MAJOR_VERSION >= 3
+ return PyLong_FromLong(PyDict_Size(self->values));
+#else
+ return PyInt_FromLong(PyDict_Size(self->values));
+#endif
+}
+
+// TODO(tibell): Use VisitCompositeField.
+int ReleaseExtension(ExtensionDict* self,
+ PyObject* extension,
+ const google::protobuf::FieldDescriptor* descriptor) {
+ if (descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+ if (descriptor->cpp_type() ==
+ google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (repeated_composite_container::Release(
+ reinterpret_cast<RepeatedCompositeContainer*>(
+ extension)) < 0) {
+ return -1;
+ }
+ } else {
+ if (repeated_scalar_container::Release(
+ reinterpret_cast<RepeatedScalarContainer*>(
+ extension)) < 0) {
+ return -1;
+ }
+ }
+ } else if (descriptor->cpp_type() ==
+ google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (cmessage::ReleaseSubMessage(
+ GetMessage(self), descriptor,
+ reinterpret_cast<CMessage*>(extension)) < 0) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+PyObject* subscript(ExtensionDict* self, PyObject* key) {
+ CFieldDescriptor* cdescriptor = InternalGetCDescriptorFromExtension(
+ key);
+ if (cdescriptor == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr py_cdescriptor(reinterpret_cast<PyObject*>(cdescriptor));
+ const google::protobuf::FieldDescriptor* descriptor = cdescriptor->descriptor;
+ if (descriptor == NULL) {
+ return NULL;
+ }
+ if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
+ descriptor->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+ return cmessage::InternalGetScalar(self->parent, descriptor);
+ }
+
+ PyObject* value = PyDict_GetItem(self->values, key);
+ if (value != NULL) {
+ Py_INCREF(value);
+ return value;
+ }
+
+ if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
+ descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ PyObject* sub_message = cmessage::InternalGetSubMessage(
+ self->parent, cdescriptor);
+ if (sub_message == NULL) {
+ return NULL;
+ }
+ PyDict_SetItem(self->values, key, sub_message);
+ return sub_message;
+ }
+
+ if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
+ if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // COPIED
+ PyObject* py_container = PyObject_CallObject(
+ reinterpret_cast<PyObject*>(&RepeatedCompositeContainer_Type),
+ NULL);
+ if (py_container == NULL) {
+ return NULL;
+ }
+ RepeatedCompositeContainer* container =
+ reinterpret_cast<RepeatedCompositeContainer*>(py_container);
+ PyObject* field = cdescriptor->descriptor_field;
+ PyObject* message_type = PyObject_GetAttrString(field, "message_type");
+ PyObject* concrete_class = PyObject_GetAttrString(message_type,
+ "_concrete_class");
+ container->owner = self->owner;
+ container->parent = self->parent;
+ container->message = self->parent->message;
+ container->parent_field = cdescriptor;
+ container->subclass_init = concrete_class;
+ Py_DECREF(message_type);
+ PyDict_SetItem(self->values, key, py_container);
+ return py_container;
+ } else {
+ // COPIED
+ ScopedPyObjectPtr init_args(PyTuple_Pack(2, self->parent, cdescriptor));
+ PyObject* py_container = PyObject_CallObject(
+ reinterpret_cast<PyObject*>(&RepeatedScalarContainer_Type),
+ init_args);
+ if (py_container == NULL) {
+ return NULL;
+ }
+ PyDict_SetItem(self->values, key, py_container);
+ return py_container;
+ }
+ }
+ PyErr_SetString(PyExc_ValueError, "control reached unexpected line");
+ return NULL;
+}
+
+int ass_subscript(ExtensionDict* self, PyObject* key, PyObject* value) {
+ CFieldDescriptor* cdescriptor = InternalGetCDescriptorFromExtension(
+ key);
+ if (cdescriptor == NULL) {
+ return -1;
+ }
+ ScopedPyObjectPtr py_cdescriptor(reinterpret_cast<PyObject*>(cdescriptor));
+ const google::protobuf::FieldDescriptor* descriptor = cdescriptor->descriptor;
+ if (descriptor->label() != FieldDescriptor::LABEL_OPTIONAL ||
+ descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ PyErr_SetString(PyExc_TypeError, "Extension is repeated and/or composite "
+ "type");
+ return -1;
+ }
+ 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);
+ return 0;
+}
+
+PyObject* ClearExtension(ExtensionDict* self, PyObject* extension) {
+ CFieldDescriptor* cdescriptor = InternalGetCDescriptorFromExtension(
+ extension);
+ if (cdescriptor == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr py_cdescriptor(reinterpret_cast<PyObject*>(cdescriptor));
+ PyObject* value = PyDict_GetItem(self->values, extension);
+ if (value != NULL) {
+ if (ReleaseExtension(self, value, cdescriptor->descriptor) < 0) {
+ return NULL;
+ }
+ }
+ if (cmessage::ClearFieldByDescriptor(self->parent,
+ cdescriptor->descriptor) == NULL) {
+ return NULL;
+ }
+ if (PyDict_DelItem(self->values, extension) < 0) {
+ PyErr_Clear();
+ }
+ Py_RETURN_NONE;
+}
+
+PyObject* HasExtension(ExtensionDict* self, PyObject* extension) {
+ CFieldDescriptor* cdescriptor = InternalGetCDescriptorFromExtension(
+ extension);
+ if (cdescriptor == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr py_cdescriptor(reinterpret_cast<PyObject*>(cdescriptor));
+ PyObject* result = cmessage::HasFieldByDescriptor(
+ self->parent, cdescriptor->descriptor);
+ return result;
+}
+
+PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* name) {
+ ScopedPyObjectPtr extensions_by_name(PyObject_GetAttrString(
+ reinterpret_cast<PyObject*>(self->parent), "_extensions_by_name"));
+ if (extensions_by_name == NULL) {
+ return NULL;
+ }
+ PyObject* result = PyDict_GetItem(extensions_by_name, name);
+ if (result == NULL) {
+ Py_RETURN_NONE;
+ } else {
+ Py_INCREF(result);
+ return result;
+ }
+}
+
+int init(ExtensionDict* self, PyObject* args, PyObject* kwargs) {
+ self->parent = NULL;
+ self->message = NULL;
+ self->values = PyDict_New();
+ return 0;
+}
+
+void dealloc(ExtensionDict* self) {
+ Py_CLEAR(self->values);
+ self->owner.reset();
+ Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+static PyMappingMethods MpMethods = {
+ (lenfunc)len, /* mp_length */
+ (binaryfunc)subscript, /* mp_subscript */
+ (objobjargproc)ass_subscript,/* mp_ass_subscript */
+};
+
+#define EDMETHOD(name, args, doc) { #name, (PyCFunction)name, args, doc }
+static PyMethodDef Methods[] = {
+ EDMETHOD(ClearExtension, METH_O, "Clears an extension from the object."),
+ EDMETHOD(HasExtension, METH_O, "Checks if the object has an extension."),
+ EDMETHOD(_FindExtensionByName, METH_O,
+ "Finds an extension by name."),
+ { NULL, NULL }
+};
+
+} // namespace extension_dict
+
+PyTypeObject ExtensionDict_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "google.protobuf.internal."
+ "cpp._message.ExtensionDict", // tp_name
+ sizeof(ExtensionDict), // tp_basicsize
+ 0, // tp_itemsize
+ (destructor)extension_dict::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
+ &extension_dict::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
+ "An extension dict", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ extension_dict::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
+ (initproc)extension_dict::init, // tp_init
+};
+
+} // namespace python
+} // namespace protobuf
+} // namespace google
diff --git a/python/google/protobuf/pyext/extension_dict.h b/python/google/protobuf/pyext/extension_dict.h
new file mode 100644
index 0000000..13c874a
--- /dev/null
+++ b/python/google/protobuf/pyext/extension_dict.h
@@ -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.
+
+// Author: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_EXTENSION_DICT_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_EXTENSION_DICT_H__
+
+#include <Python.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+
+
+namespace google {
+namespace protobuf {
+
+class Message;
+class FieldDescriptor;
+
+using internal::shared_ptr;
+
+namespace python {
+
+struct CMessage;
+struct CFieldDescriptor;
+
+typedef struct ExtensionDict {
+ PyObject_HEAD;
+ shared_ptr<Message> owner;
+ CMessage* parent;
+ Message* message;
+ PyObject* values;
+} ExtensionDict;
+
+extern PyTypeObject ExtensionDict_Type;
+
+namespace extension_dict {
+
+// Gets the _cdescriptor reference to a CFieldDescriptor object given a
+// python descriptor object.
+//
+// Returns a new reference.
+CFieldDescriptor* InternalGetCDescriptorFromExtension(PyObject* extension);
+
+// Gets the number of extension values in this ExtensionDict as a python object.
+//
+// Returns a new reference.
+PyObject* len(ExtensionDict* self);
+
+// Releases extensions referenced outside this dictionary to keep outside
+// references alive.
+//
+// Returns 0 on success, -1 on failure.
+int ReleaseExtension(ExtensionDict* self,
+ PyObject* extension,
+ const google::protobuf::FieldDescriptor* descriptor);
+
+// Gets an extension from the dict for the given extension descriptor.
+//
+// Returns a new reference.
+PyObject* subscript(ExtensionDict* self, PyObject* key);
+
+// Assigns a value to an extension in the dict. Can only be used for singular
+// simple types.
+//
+// Returns 0 on success, -1 on failure.
+int ass_subscript(ExtensionDict* self, PyObject* key, PyObject* value);
+
+// Clears an extension from the dict. Will release the extension if there
+// is still an external reference left to it.
+//
+// Returns None on success.
+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);
+
+} // namespace extension_dict
+} // namespace python
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_PYTHON_CPP_EXTENSION_DICT_H__
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
new file mode 100644
index 0000000..9fb7083
--- /dev/null
+++ b/python/google/protobuf/pyext/message.cc
@@ -0,0 +1,2561 @@
+// 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: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#include <google/protobuf/pyext/message.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+#include <string>
+#include <vector>
+
+#ifndef PyVarObject_HEAD_INIT
+#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
+#endif
+#ifndef Py_TYPE
+#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
+#endif
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/pyext/descriptor.h>
+#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/scoped_pyobject_ptr.h>
+
+#if PY_MAJOR_VERSION >= 3
+ #define PyInt_Check PyLong_Check
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyString_Check PyUnicode_Check
+ #define PyString_FromString PyUnicode_FromString
+ #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
+ #if PY_VERSION_HEX < 0x03030000
+ #error "Python 3.0 - 3.2 are not supported."
+ #else
+ #define PyString_AsString(ob) \
+ (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AS_STRING(ob))
+ #endif
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+// Forward declarations
+namespace cmessage {
+static PyObject* GetDescriptor(CMessage* self, PyObject* name);
+static string GetMessageName(CMessage* self);
+int InternalReleaseFieldByDescriptor(
+ const google::protobuf::FieldDescriptor* field_descriptor,
+ PyObject* composite_field,
+ google::protobuf::Message* parent_message);
+} // namespace cmessage
+
+// ---------------------------------------------------------------------
+// Visiting the composite children of a CMessage
+
+struct ChildVisitor {
+ // Returns 0 on success, -1 on failure.
+ int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
+ return 0;
+ }
+
+ // Returns 0 on success, -1 on failure.
+ int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
+ return 0;
+ }
+
+ // Returns 0 on success, -1 on failure.
+ int VisitCMessage(CMessage* cmessage,
+ const google::protobuf::FieldDescriptor* field_descriptor) {
+ return 0;
+ }
+};
+
+// Apply a function to a composite field. Does nothing if child is of
+// non-composite type.
+template<class Visitor>
+static int VisitCompositeField(const FieldDescriptor* descriptor,
+ PyObject* child,
+ Visitor visitor) {
+ if (descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+ if (descriptor->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+ RepeatedCompositeContainer* container =
+ reinterpret_cast<RepeatedCompositeContainer*>(child);
+ if (visitor.VisitRepeatedCompositeContainer(container) == -1)
+ return -1;
+ } else {
+ RepeatedScalarContainer* container =
+ reinterpret_cast<RepeatedScalarContainer*>(child);
+ if (visitor.VisitRepeatedScalarContainer(container) == -1)
+ return -1;
+ }
+ } else if (descriptor->cpp_type() ==
+ google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+ CMessage* cmsg = reinterpret_cast<CMessage*>(child);
+ if (visitor.VisitCMessage(cmsg, descriptor) == -1)
+ return -1;
+ }
+ // The ExtensionDict might contain non-composite fields, which we
+ // skip here.
+ return 0;
+}
+
+// Visit each composite field and extension field of this CMessage.
+// Returns -1 on error and 0 on success.
+template<class Visitor>
+int ForEachCompositeField(CMessage* self, Visitor visitor) {
+ Py_ssize_t pos = 0;
+ PyObject* key;
+ PyObject* field;
+
+ // Visit normal fields.
+ while (PyDict_Next(self->composite_fields, &pos, &key, &field)) {
+ PyObject* cdescriptor = cmessage::GetDescriptor(self, key);
+ if (cdescriptor != NULL) {
+ const google::protobuf::FieldDescriptor* descriptor =
+ reinterpret_cast<CFieldDescriptor*>(cdescriptor)->descriptor;
+ if (VisitCompositeField(descriptor, field, visitor) == -1)
+ return -1;
+ }
+ }
+
+ // Visit extension fields.
+ if (self->extensions != NULL) {
+ while (PyDict_Next(self->extensions->values, &pos, &key, &field)) {
+ CFieldDescriptor* cdescriptor =
+ extension_dict::InternalGetCDescriptorFromExtension(key);
+ if (cdescriptor == NULL)
+ return -1;
+ if (VisitCompositeField(cdescriptor->descriptor, field, visitor) == -1)
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+// ---------------------------------------------------------------------
+
+// Constants used for integer type range checking.
+PyObject* kPythonZero;
+PyObject* kint32min_py;
+PyObject* kint32max_py;
+PyObject* kuint32max_py;
+PyObject* kint64min_py;
+PyObject* kint64max_py;
+PyObject* kuint64max_py;
+
+PyObject* EnumTypeWrapper_class;
+PyObject* EncodeError_class;
+PyObject* DecodeError_class;
+PyObject* PickleError_class;
+
+// Constant PyString values used for GetAttr/GetItem.
+static PyObject* kDESCRIPTOR;
+static PyObject* k__descriptors;
+static PyObject* kfull_name;
+static PyObject* kname;
+static PyObject* kmessage_type;
+static PyObject* kis_extendable;
+static PyObject* kextensions_by_name;
+static PyObject* k_extensions_by_name;
+static PyObject* k_extensions_by_number;
+static PyObject* k_concrete_class;
+static PyObject* kfields_by_name;
+
+static CDescriptorPool* descriptor_pool;
+
+/* Is 64bit */
+void FormatTypeError(PyObject* arg, char* expected_types) {
+ PyObject* repr = PyObject_Repr(arg);
+ if (repr) {
+ PyErr_Format(PyExc_TypeError,
+ "%.100s has type %.100s, but expected one of: %s",
+ PyString_AsString(repr),
+ Py_TYPE(arg)->tp_name,
+ expected_types);
+ Py_DECREF(repr);
+ }
+}
+
+template<class T>
+bool CheckAndGetInteger(
+ PyObject* arg, T* value, PyObject* min, PyObject* max) {
+ bool is_long = PyLong_Check(arg);
+#if PY_MAJOR_VERSION < 3
+ if (!PyInt_Check(arg) && !is_long) {
+ FormatTypeError(arg, "int, long");
+ return false;
+ }
+ if (PyObject_Compare(min, arg) > 0 || PyObject_Compare(max, arg) < 0) {
+#else
+ if (!is_long) {
+ FormatTypeError(arg, "int");
+ return false;
+ }
+ 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);
+ }
+ return false;
+ }
+#if PY_MAJOR_VERSION < 3
+ if (!is_long) {
+ *value = static_cast<T>(PyInt_AsLong(arg));
+ } else // NOLINT
+#endif
+ {
+ if (min == kPythonZero) {
+ *value = static_cast<T>(PyLong_AsUnsignedLongLong(arg));
+ } else {
+ *value = static_cast<T>(PyLong_AsLongLong(arg));
+ }
+ }
+ return true;
+}
+
+// These are referenced by repeated_scalar_container, and must
+// be explicitly instantiated.
+template bool CheckAndGetInteger<int32>(
+ PyObject*, int32*, PyObject*, PyObject*);
+template bool CheckAndGetInteger<int64>(
+ PyObject*, int64*, PyObject*, PyObject*);
+template bool CheckAndGetInteger<uint32>(
+ PyObject*, uint32*, PyObject*, PyObject*);
+template bool CheckAndGetInteger<uint64>(
+ PyObject*, uint64*, PyObject*, PyObject*);
+
+bool CheckAndGetDouble(PyObject* arg, double* value) {
+ if (!PyInt_Check(arg) && !PyLong_Check(arg) &&
+ !PyFloat_Check(arg)) {
+ FormatTypeError(arg, "int, long, float");
+ return false;
+ }
+ *value = PyFloat_AsDouble(arg);
+ return true;
+}
+
+bool CheckAndGetFloat(PyObject* arg, float* value) {
+ double double_value;
+ if (!CheckAndGetDouble(arg, &double_value)) {
+ return false;
+ }
+ *value = static_cast<float>(double_value);
+ return true;
+}
+
+bool CheckAndGetBool(PyObject* arg, bool* value) {
+ if (!PyInt_Check(arg) && !PyBool_Check(arg) && !PyLong_Check(arg)) {
+ FormatTypeError(arg, "int, long, bool");
+ return false;
+ }
+ *value = static_cast<bool>(PyInt_AsLong(arg));
+ return true;
+}
+
+bool CheckAndSetString(
+ PyObject* arg, google::protobuf::Message* message,
+ const google::protobuf::FieldDescriptor* descriptor,
+ const google::protobuf::Reflection* reflection,
+ bool append,
+ int index) {
+ GOOGLE_DCHECK(descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING ||
+ descriptor->type() == google::protobuf::FieldDescriptor::TYPE_BYTES);
+ if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) {
+ if (!PyBytes_Check(arg) && !PyUnicode_Check(arg)) {
+ FormatTypeError(arg, "bytes, unicode");
+ return false;
+ }
+
+ if (PyBytes_Check(arg)) {
+ PyObject* unicode = PyUnicode_FromEncodedObject(arg, "ascii", NULL);
+ if (unicode == NULL) {
+ PyObject* repr = PyObject_Repr(arg);
+ PyErr_Format(PyExc_ValueError,
+ "%s has type str, but isn't in 7-bit ASCII "
+ "encoding. Non-ASCII strings must be converted to "
+ "unicode objects before being added.",
+ PyString_AsString(repr));
+ Py_DECREF(repr);
+ return false;
+ } else {
+ Py_DECREF(unicode);
+ }
+ }
+ } else if (!PyBytes_Check(arg)) {
+ FormatTypeError(arg, "bytes");
+ return false;
+ }
+
+ PyObject* encoded_string = NULL;
+ if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) {
+ if (PyBytes_Check(arg)) {
+#if PY_MAJOR_VERSION < 3
+ encoded_string = PyString_AsEncodedObject(arg, "utf-8", NULL);
+#else
+ encoded_string = arg; // Already encoded.
+ Py_INCREF(encoded_string);
+#endif
+ } else {
+ encoded_string = PyUnicode_AsEncodedObject(arg, "utf-8", NULL);
+ }
+ } else {
+ // In this case field type is "bytes".
+ encoded_string = arg;
+ Py_INCREF(encoded_string);
+ }
+
+ if (encoded_string == NULL) {
+ return false;
+ }
+
+ char* value;
+ Py_ssize_t value_len;
+ if (PyBytes_AsStringAndSize(encoded_string, &value, &value_len) < 0) {
+ Py_DECREF(encoded_string);
+ return false;
+ }
+
+ string value_string(value, value_len);
+ if (append) {
+ reflection->AddString(message, descriptor, value_string);
+ } else if (index < 0) {
+ reflection->SetString(message, descriptor, value_string);
+ } else {
+ reflection->SetRepeatedString(message, descriptor, index, value_string);
+ }
+ Py_DECREF(encoded_string);
+ return true;
+}
+
+PyObject* ToStringObject(
+ const google::protobuf::FieldDescriptor* descriptor, string value) {
+ if (descriptor->type() != google::protobuf::FieldDescriptor::TYPE_STRING) {
+ return PyBytes_FromStringAndSize(value.c_str(), value.length());
+ }
+
+ PyObject* result = PyUnicode_DecodeUTF8(value.c_str(), value.length(), NULL);
+ // If the string can't be decoded in UTF-8, just return a string object that
+ // contains the raw bytes. This can't happen if the value was assigned using
+ // the members of the Python message object, but can happen if the values were
+ // parsed from the wire (binary).
+ if (result == NULL) {
+ PyErr_Clear();
+ result = PyBytes_FromStringAndSize(value.c_str(), value.length());
+ }
+ return result;
+}
+
+google::protobuf::DynamicMessageFactory* global_message_factory;
+
+namespace cmessage {
+
+static int MaybeReleaseOverlappingOneofField(
+ CMessage* cmessage,
+ const google::protobuf::FieldDescriptor* field) {
+#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
+ google::protobuf::Message* message = cmessage->message;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ if (!field->containing_oneof() ||
+ !reflection->HasOneof(*message, field->containing_oneof()) ||
+ reflection->HasField(*message, field)) {
+ // No other field in this oneof, no need to release.
+ return 0;
+ }
+
+ const OneofDescriptor* oneof = field->containing_oneof();
+ const FieldDescriptor* existing_field =
+ reflection->GetOneofFieldDescriptor(*message, oneof);
+ if (existing_field->cpp_type() != google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Non-message fields don't need to be released.
+ return 0;
+ }
+ const char* field_name = existing_field->name().c_str();
+ PyObject* child_message = PyDict_GetItemString(
+ cmessage->composite_fields, field_name);
+ if (child_message == NULL) {
+ // No python reference to this field so no need to release.
+ return 0;
+ }
+
+ if (InternalReleaseFieldByDescriptor(
+ existing_field, child_message, message) < 0) {
+ return -1;
+ }
+ return PyDict_DelItemString(cmessage->composite_fields, field_name);
+#else
+ return 0;
+#endif
+}
+
+// ---------------------------------------------------------------------
+// Making a message writable
+
+static google::protobuf::Message* GetMutableMessage(
+ CMessage* parent,
+ const google::protobuf::FieldDescriptor* parent_field) {
+ google::protobuf::Message* parent_message = parent->message;
+ const google::protobuf::Reflection* reflection = parent_message->GetReflection();
+ if (MaybeReleaseOverlappingOneofField(parent, parent_field) < 0) {
+ return NULL;
+ }
+ return reflection->MutableMessage(
+ parent_message, parent_field, global_message_factory);
+}
+
+struct FixupMessageReference : public ChildVisitor {
+ // message must outlive this object.
+ explicit FixupMessageReference(google::protobuf::Message* message) :
+ message_(message) {}
+
+ int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
+ container->message = message_;
+ return 0;
+ }
+
+ int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
+ container->message = message_;
+ return 0;
+ }
+
+ private:
+ google::protobuf::Message* message_;
+};
+
+int AssureWritable(CMessage* self) {
+ if (self == NULL || !self->read_only) {
+ return 0;
+ }
+
+ if (self->parent == NULL) {
+ // If parent is NULL but we are trying to modify a read-only message, this
+ // is a reference to a constant default instance that needs to be replaced
+ // with a mutable top-level message.
+ const Message* prototype = global_message_factory->GetPrototype(
+ self->message->GetDescriptor());
+ self->message = prototype->New();
+ self->owner.reset(self->message);
+ } else {
+ // Otherwise, we need a mutable child message.
+ if (AssureWritable(self->parent) == -1)
+ return -1;
+
+ // Make self->message writable.
+ google::protobuf::Message* parent_message = self->parent->message;
+ google::protobuf::Message* mutable_message = GetMutableMessage(
+ self->parent,
+ self->parent_field->descriptor);
+ if (mutable_message == NULL) {
+ return -1;
+ }
+ self->message = mutable_message;
+ }
+ self->read_only = false;
+
+ // 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
+ // three places such references occur: RepeatedScalarContainer,
+ // RepeatedCompositeContainer, and ExtensionDict.
+ if (self->extensions != NULL)
+ self->extensions->message = self->message;
+ if (ForEachCompositeField(self, FixupMessageReference(self->message)) == -1)
+ return -1;
+
+ return 0;
+}
+
+// --- Globals:
+
+static PyObject* GetDescriptor(CMessage* self, PyObject* name) {
+ PyObject* descriptors =
+ PyDict_GetItem(Py_TYPE(self)->tp_dict, k__descriptors);
+ if (descriptors == NULL) {
+ PyErr_SetString(PyExc_TypeError, "No __descriptors");
+ return NULL;
+ }
+
+ return PyDict_GetItem(descriptors, name);
+}
+
+static const google::protobuf::Message* CreateMessage(const char* message_type) {
+ string message_name(message_type);
+ const google::protobuf::Descriptor* descriptor =
+ GetDescriptorPool()->FindMessageTypeByName(message_name);
+ if (descriptor == NULL) {
+ PyErr_SetString(PyExc_TypeError, message_type);
+ return NULL;
+ }
+ return global_message_factory->GetPrototype(descriptor);
+}
+
+// If cmessage_list is not NULL, this function releases values into the
+// container CMessages instead of just removing. Repeated composite container
+// needs to do this to make sure CMessages stay alive if they're still
+// referenced after deletion. Repeated scalar container doesn't need to worry.
+int InternalDeleteRepeatedField(
+ google::protobuf::Message* message,
+ const google::protobuf::FieldDescriptor* field_descriptor,
+ PyObject* slice,
+ PyObject* cmessage_list) {
+ Py_ssize_t length, from, to, step, slice_length;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ int min, max;
+ length = reflection->FieldSize(*message, field_descriptor);
+
+ if (PyInt_Check(slice) || PyLong_Check(slice)) {
+ from = to = PyLong_AsLong(slice);
+ if (from < 0) {
+ from = to = length + from;
+ }
+ step = 1;
+ min = max = from;
+
+ // Range check.
+ if (from < 0 || from >= length) {
+ PyErr_Format(PyExc_IndexError, "list assignment index out of range");
+ return -1;
+ }
+ } else if (PySlice_Check(slice)) {
+ from = to = step = slice_length = 0;
+ PySlice_GetIndicesEx(
+#if PY_MAJOR_VERSION < 3
+ reinterpret_cast<PySliceObject*>(slice),
+#else
+ slice,
+#endif
+ length, &from, &to, &step, &slice_length);
+ if (from < to) {
+ min = from;
+ max = to - 1;
+ } else {
+ min = to + 1;
+ max = from;
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError, "list indices must be integers");
+ return -1;
+ }
+
+ Py_ssize_t i = from;
+ std::vector<bool> to_delete(length, false);
+ while (i >= min && i <= max) {
+ to_delete[i] = true;
+ i += step;
+ }
+
+ to = 0;
+ for (i = 0; i < length; ++i) {
+ if (!to_delete[i]) {
+ if (i != to) {
+ reflection->SwapElements(message, field_descriptor, i, to);
+ if (cmessage_list != NULL) {
+ // If a list of cmessages is passed in (i.e. from a repeated
+ // composite container), swap those as well to correspond to the
+ // swaps in the underlying message so they're in the right order
+ // when we start releasing.
+ PyObject* tmp = PyList_GET_ITEM(cmessage_list, i);
+ PyList_SET_ITEM(cmessage_list, i,
+ PyList_GET_ITEM(cmessage_list, to));
+ PyList_SET_ITEM(cmessage_list, to, tmp);
+ }
+ }
+ ++to;
+ }
+ }
+
+ while (i > to) {
+ if (cmessage_list == NULL) {
+ reflection->RemoveLast(message, field_descriptor);
+ } else {
+ CMessage* last_cmessage = reinterpret_cast<CMessage*>(
+ PyList_GET_ITEM(cmessage_list, PyList_GET_SIZE(cmessage_list) - 1));
+ repeated_composite_container::ReleaseLastTo(
+ field_descriptor, message, last_cmessage);
+ if (PySequence_DelItem(cmessage_list, -1) < 0) {
+ return -1;
+ }
+ }
+ --i;
+ }
+
+ return 0;
+}
+
+int InitAttributes(CMessage* self, PyObject* arg, PyObject* kwargs) {
+ ScopedPyObjectPtr descriptor;
+ if (arg == NULL) {
+ descriptor.reset(
+ PyObject_GetAttr(reinterpret_cast<PyObject*>(self), kDESCRIPTOR));
+ if (descriptor == NULL) {
+ return NULL;
+ }
+ } else {
+ descriptor.reset(arg);
+ descriptor.inc();
+ }
+ ScopedPyObjectPtr is_extendable(PyObject_GetAttr(descriptor, kis_extendable));
+ if (is_extendable == NULL) {
+ return NULL;
+ }
+ int retcode = PyObject_IsTrue(is_extendable);
+ if (retcode == -1) {
+ return NULL;
+ }
+ if (retcode) {
+ PyObject* py_extension_dict = PyObject_CallObject(
+ reinterpret_cast<PyObject*>(&ExtensionDict_Type), NULL);
+ if (py_extension_dict == NULL) {
+ return NULL;
+ }
+ ExtensionDict* extension_dict = reinterpret_cast<ExtensionDict*>(
+ py_extension_dict);
+ extension_dict->parent = self;
+ extension_dict->message = self->message;
+ self->extensions = extension_dict;
+ }
+
+ if (kwargs == NULL) {
+ return 0;
+ }
+
+ Py_ssize_t pos = 0;
+ PyObject* name;
+ PyObject* value;
+ while (PyDict_Next(kwargs, &pos, &name, &value)) {
+ if (!PyString_Check(name)) {
+ PyErr_SetString(PyExc_ValueError, "Field name must be a string");
+ return -1;
+ }
+ PyObject* py_cdescriptor = GetDescriptor(self, name);
+ if (py_cdescriptor == NULL) {
+ PyErr_Format(PyExc_ValueError, "Protocol message has no \"%s\" field.",
+ PyString_AsString(name));
+ return -1;
+ }
+ const google::protobuf::FieldDescriptor* descriptor =
+ reinterpret_cast<CFieldDescriptor*>(py_cdescriptor)->descriptor;
+ if (descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+ ScopedPyObjectPtr container(GetAttr(self, name));
+ if (container == NULL) {
+ return -1;
+ }
+ if (descriptor->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (repeated_composite_container::Extend(
+ reinterpret_cast<RepeatedCompositeContainer*>(container.get()),
+ value)
+ == NULL) {
+ return -1;
+ }
+ } else {
+ if (repeated_scalar_container::Extend(
+ reinterpret_cast<RepeatedScalarContainer*>(container.get()),
+ value) ==
+ NULL) {
+ return -1;
+ }
+ }
+ } else if (descriptor->cpp_type() ==
+ google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+ ScopedPyObjectPtr message(GetAttr(self, name));
+ if (message == NULL) {
+ return -1;
+ }
+ if (MergeFrom(reinterpret_cast<CMessage*>(message.get()),
+ value) == NULL) {
+ return -1;
+ }
+ } else {
+ if (SetAttr(self, name, value) < 0) {
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) {
+ CMessage* self = reinterpret_cast<CMessage*>(type->tp_alloc(type, 0));
+ if (self == NULL) {
+ return NULL;
+ }
+
+ self->message = NULL;
+ self->parent = NULL;
+ self->parent_field = NULL;
+ self->read_only = false;
+ self->extensions = NULL;
+
+ self->composite_fields = PyDict_New();
+ if (self->composite_fields == NULL) {
+ return NULL;
+ }
+ return reinterpret_cast<PyObject*>(self);
+}
+
+PyObject* NewEmpty(PyObject* type) {
+ return New(reinterpret_cast<PyTypeObject*>(type), NULL, NULL);
+}
+
+static int Init(CMessage* self, PyObject* args, PyObject* kwargs) {
+ if (kwargs == NULL) {
+ // TODO(anuraag): Set error
+ return -1;
+ }
+
+ PyObject* descriptor = PyTuple_GetItem(args, 0);
+ if (descriptor == NULL || PyTuple_Size(args) != 1) {
+ PyErr_SetString(PyExc_ValueError, "args must contain one arg: descriptor");
+ return -1;
+ }
+
+ ScopedPyObjectPtr py_message_type(PyObject_GetAttr(descriptor, kfull_name));
+ if (py_message_type == NULL) {
+ return -1;
+ }
+
+ const char* message_type = PyString_AsString(py_message_type.get());
+ const google::protobuf::Message* message = CreateMessage(message_type);
+ if (message == NULL) {
+ return -1;
+ }
+
+ self->message = message->New();
+ self->owner.reset(self->message);
+
+ if (InitAttributes(self, descriptor, kwargs) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+// ---------------------------------------------------------------------
+// Deallocating a CMessage
+//
+// Deallocating a CMessage requires that we clear any weak references
+// from children to the message being deallocated.
+
+// Clear the weak reference from the child to the parent.
+struct ClearWeakReferences : public ChildVisitor {
+ int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
+ container->parent = NULL;
+ // The elements in the container have the same parent as the
+ // container itself, so NULL out that pointer as well.
+ const Py_ssize_t n = PyList_GET_SIZE(container->child_messages);
+ for (Py_ssize_t i = 0; i < n; ++i) {
+ CMessage* child_cmessage = reinterpret_cast<CMessage*>(
+ PyList_GET_ITEM(container->child_messages, i));
+ child_cmessage->parent = NULL;
+ }
+ return 0;
+ }
+
+ int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
+ container->parent = NULL;
+ return 0;
+ }
+
+ int VisitCMessage(CMessage* cmessage,
+ const google::protobuf::FieldDescriptor* field_descriptor) {
+ cmessage->parent = NULL;
+ return 0;
+ }
+};
+
+static void Dealloc(CMessage* self) {
+ // Null out all weak references from children to this message.
+ GOOGLE_CHECK_EQ(0, ForEachCompositeField(self, ClearWeakReferences()));
+
+ Py_CLEAR(self->extensions);
+ Py_CLEAR(self->composite_fields);
+ self->owner.reset();
+ Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+// ---------------------------------------------------------------------
+
+
+PyObject* IsInitialized(CMessage* self, PyObject* args) {
+ PyObject* errors = NULL;
+ if (PyArg_ParseTuple(args, "|O", &errors) < 0) {
+ return NULL;
+ }
+ if (self->message->IsInitialized()) {
+ Py_RETURN_TRUE;
+ }
+ if (errors != NULL) {
+ ScopedPyObjectPtr initialization_errors(
+ FindInitializationErrors(self));
+ if (initialization_errors == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr extend_name(PyString_FromString("extend"));
+ if (extend_name == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr result(PyObject_CallMethodObjArgs(
+ errors,
+ extend_name.get(),
+ initialization_errors.get(),
+ NULL));
+ if (result == NULL) {
+ return NULL;
+ }
+ }
+ Py_RETURN_FALSE;
+}
+
+PyObject* HasFieldByDescriptor(
+ CMessage* self, const google::protobuf::FieldDescriptor* field_descriptor) {
+ google::protobuf::Message* message = self->message;
+ if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+ PyErr_SetString(PyExc_KeyError,
+ "Field does not belong to message!");
+ return NULL;
+ }
+ if (field_descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+ PyErr_SetString(PyExc_KeyError,
+ "Field is repeated. A singular method is required.");
+ return NULL;
+ }
+ bool has_field =
+ message->GetReflection()->HasField(*message, field_descriptor);
+ return PyBool_FromLong(has_field ? 1 : 0);
+}
+
+const google::protobuf::FieldDescriptor* FindFieldWithOneofs(
+ const google::protobuf::Message* message, const char* field_name, bool* in_oneof) {
+ const google::protobuf::Descriptor* descriptor = message->GetDescriptor();
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ descriptor->FindFieldByName(field_name);
+ if (field_descriptor == NULL) {
+ const google::protobuf::OneofDescriptor* oneof_desc =
+ message->GetDescriptor()->FindOneofByName(field_name);
+ if (oneof_desc == NULL) {
+ *in_oneof = false;
+ return NULL;
+ } else {
+ *in_oneof = true;
+ return message->GetReflection()->GetOneofFieldDescriptor(
+ *message, oneof_desc);
+ }
+ }
+ return field_descriptor;
+}
+
+PyObject* HasField(CMessage* self, PyObject* arg) {
+#if PY_MAJOR_VERSION < 3
+ char* field_name;
+ if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) {
+#else
+ char* field_name = PyUnicode_AsUTF8(arg);
+ if (!field_name) {
+#endif
+ return NULL;
+ }
+
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Descriptor* descriptor = message->GetDescriptor();
+ bool is_in_oneof;
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ FindFieldWithOneofs(message, field_name, &is_in_oneof);
+ if (field_descriptor == NULL) {
+ if (!is_in_oneof) {
+ PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name);
+ return NULL;
+ } else {
+ Py_RETURN_FALSE;
+ }
+ }
+
+ if (field_descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+ PyErr_Format(PyExc_ValueError,
+ "Protocol message has no singular \"%s\" field.", field_name);
+ return NULL;
+ }
+
+ bool has_field =
+ message->GetReflection()->HasField(*message, field_descriptor);
+ if (!has_field && field_descriptor->cpp_type() ==
+ google::protobuf::FieldDescriptor::CPPTYPE_ENUM) {
+ // We may have an invalid enum value stored in the UnknownFieldSet and need
+ // to check presence in there as well.
+ const google::protobuf::UnknownFieldSet& unknown_field_set =
+ message->GetReflection()->GetUnknownFields(*message);
+ for (int i = 0; i < unknown_field_set.field_count(); ++i) {
+ if (unknown_field_set.field(i).number() == field_descriptor->number()) {
+ Py_RETURN_TRUE;
+ }
+ }
+ Py_RETURN_FALSE;
+ }
+ return PyBool_FromLong(has_field ? 1 : 0);
+}
+
+PyObject* ClearExtension(CMessage* self, PyObject* arg) {
+ if (self->extensions != NULL) {
+ return extension_dict::ClearExtension(self->extensions, arg);
+ }
+ PyErr_SetString(PyExc_TypeError, "Message is not extendable");
+ return NULL;
+}
+
+PyObject* HasExtension(CMessage* self, PyObject* arg) {
+ if (self->extensions != NULL) {
+ return extension_dict::HasExtension(self->extensions, arg);
+ }
+ PyErr_SetString(PyExc_TypeError, "Message is not extendable");
+ return NULL;
+}
+
+// ---------------------------------------------------------------------
+// Releasing messages
+//
+// The Python API's ClearField() and Clear() methods behave
+// differently than their C++ counterparts. While the C++ versions
+// clears the children the Python versions detaches the children,
+// without touching their content. This impedance mismatch causes
+// some complexity in the implementation, which is captured in this
+// section.
+//
+// When a CMessage field is cleared we need to:
+//
+// * Release the Message used as the backing store for the CMessage
+// from its parent.
+//
+// * Change the owner field of the released CMessage and all of its
+// children to point to the newly released Message.
+//
+// * Clear the weak references from the released CMessage to the
+// parent.
+//
+// When a RepeatedCompositeContainer field is cleared we need to:
+//
+// * Release all the Message used as the backing store for the
+// CMessages stored in the container.
+//
+// * Change the owner field of all the released CMessage and all of
+// their children to point to the newly released Messages.
+//
+// * Clear the weak references from the released container to the
+// parent.
+
+struct SetOwnerVisitor : public ChildVisitor {
+ // new_owner must outlive this object.
+ explicit SetOwnerVisitor(const shared_ptr<Message>& new_owner)
+ : new_owner_(new_owner) {}
+
+ int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
+ repeated_composite_container::SetOwner(container, new_owner_);
+ return 0;
+ }
+
+ int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
+ repeated_scalar_container::SetOwner(container, new_owner_);
+ return 0;
+ }
+
+ int VisitCMessage(CMessage* cmessage,
+ const google::protobuf::FieldDescriptor* field_descriptor) {
+ return SetOwner(cmessage, new_owner_);
+ }
+
+ private:
+ const shared_ptr<Message>& new_owner_;
+};
+
+// Change the owner of this CMessage and all its children, recursively.
+int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner) {
+ self->owner = new_owner;
+ if (ForEachCompositeField(self, SetOwnerVisitor(new_owner)) == -1)
+ return -1;
+ return 0;
+}
+
+// Releases the message specified by 'field' and returns the
+// pointer. If the field does not exist a new message is created using
+// 'descriptor'. The caller takes ownership of the returned pointer.
+Message* ReleaseMessage(google::protobuf::Message* message,
+ const google::protobuf::Descriptor* descriptor,
+ const google::protobuf::FieldDescriptor* field_descriptor) {
+ Message* released_message = message->GetReflection()->ReleaseMessage(
+ message, field_descriptor, global_message_factory);
+ // ReleaseMessage will return NULL which differs from
+ // child_cmessage->message, if the field does not exist. In this case,
+ // the latter points to the default instance via a const_cast<>, so we
+ // have to reset it to a new mutable object since we are taking ownership.
+ if (released_message == NULL) {
+ const Message* prototype = global_message_factory->GetPrototype(
+ descriptor);
+ GOOGLE_DCHECK(prototype != NULL);
+ released_message = prototype->New();
+ }
+
+ return released_message;
+}
+
+int ReleaseSubMessage(google::protobuf::Message* message,
+ const google::protobuf::FieldDescriptor* field_descriptor,
+ CMessage* child_cmessage) {
+ // Release the Message
+ shared_ptr<Message> released_message(ReleaseMessage(
+ message, child_cmessage->message->GetDescriptor(), field_descriptor));
+ child_cmessage->message = released_message.get();
+ child_cmessage->owner.swap(released_message);
+ child_cmessage->parent = NULL;
+ child_cmessage->parent_field = NULL;
+ child_cmessage->read_only = false;
+ return ForEachCompositeField(child_cmessage,
+ SetOwnerVisitor(child_cmessage->owner));
+}
+
+struct ReleaseChild : public ChildVisitor {
+ // message must outlive this object.
+ explicit ReleaseChild(google::protobuf::Message* parent_message) :
+ parent_message_(parent_message) {}
+
+ int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
+ return repeated_composite_container::Release(
+ reinterpret_cast<RepeatedCompositeContainer*>(container));
+ }
+
+ int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
+ return repeated_scalar_container::Release(
+ reinterpret_cast<RepeatedScalarContainer*>(container));
+ }
+
+ int VisitCMessage(CMessage* cmessage,
+ const google::protobuf::FieldDescriptor* field_descriptor) {
+ return ReleaseSubMessage(parent_message_, field_descriptor,
+ reinterpret_cast<CMessage*>(cmessage));
+ }
+
+ google::protobuf::Message* parent_message_;
+};
+
+int InternalReleaseFieldByDescriptor(
+ const google::protobuf::FieldDescriptor* field_descriptor,
+ PyObject* composite_field,
+ google::protobuf::Message* parent_message) {
+ return VisitCompositeField(
+ field_descriptor,
+ composite_field,
+ ReleaseChild(parent_message));
+}
+
+int InternalReleaseField(CMessage* self, PyObject* composite_field,
+ PyObject* name) {
+ PyObject* cdescriptor = GetDescriptor(self, name);
+ if (cdescriptor != NULL) {
+ const google::protobuf::FieldDescriptor* descriptor =
+ reinterpret_cast<CFieldDescriptor*>(cdescriptor)->descriptor;
+ return InternalReleaseFieldByDescriptor(
+ descriptor, composite_field, self->message);
+ }
+
+ return 0;
+}
+
+PyObject* ClearFieldByDescriptor(
+ CMessage* self,
+ const google::protobuf::FieldDescriptor* descriptor) {
+ if (!FIELD_BELONGS_TO_MESSAGE(descriptor, self->message)) {
+ PyErr_SetString(PyExc_KeyError,
+ "Field does not belong to message!");
+ return NULL;
+ }
+ AssureWritable(self);
+ self->message->GetReflection()->ClearField(self->message, descriptor);
+ Py_RETURN_NONE;
+}
+
+PyObject* ClearField(CMessage* self, PyObject* arg) {
+ char* field_name;
+ if (!PyString_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError, "field name must be a string");
+ return NULL;
+ }
+#if PY_MAJOR_VERSION < 3
+ if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) {
+ return NULL;
+ }
+#else
+ field_name = PyUnicode_AsUTF8(arg);
+#endif
+ AssureWritable(self);
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Descriptor* descriptor = message->GetDescriptor();
+ ScopedPyObjectPtr arg_in_oneof;
+ bool is_in_oneof;
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ FindFieldWithOneofs(message, field_name, &is_in_oneof);
+ if (field_descriptor == NULL) {
+ if (!is_in_oneof) {
+ PyErr_Format(PyExc_ValueError,
+ "Protocol message has no \"%s\" field.", field_name);
+ return NULL;
+ } else {
+ Py_RETURN_NONE;
+ }
+ } else if (is_in_oneof) {
+ arg_in_oneof.reset(PyString_FromString(field_descriptor->name().c_str()));
+ arg = arg_in_oneof.get();
+ }
+
+ PyObject* composite_field = PyDict_GetItem(self->composite_fields,
+ arg);
+
+ // Only release the field if there's a possibility that there are
+ // references to it.
+ if (composite_field != NULL) {
+ if (InternalReleaseField(self, composite_field, arg) < 0) {
+ return NULL;
+ }
+ PyDict_DelItem(self->composite_fields, arg);
+ }
+ message->GetReflection()->ClearField(message, field_descriptor);
+ if (field_descriptor->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_ENUM) {
+ google::protobuf::UnknownFieldSet* unknown_field_set =
+ message->GetReflection()->MutableUnknownFields(message);
+ unknown_field_set->DeleteByNumber(field_descriptor->number());
+ }
+
+ Py_RETURN_NONE;
+}
+
+PyObject* Clear(CMessage* self) {
+ AssureWritable(self);
+ if (ForEachCompositeField(self, ReleaseChild(self->message)) == -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);
+ PyObject* py_extension_dict = PyObject_CallObject(
+ reinterpret_cast<PyObject*>(&ExtensionDict_Type), NULL);
+ if (py_extension_dict == NULL) {
+ return NULL;
+ }
+ ExtensionDict* extension_dict = reinterpret_cast<ExtensionDict*>(
+ py_extension_dict);
+ extension_dict->parent = self;
+ extension_dict->message = self->message;
+ self->extensions = extension_dict;
+ }
+ PyDict_Clear(self->composite_fields);
+ self->message->Clear();
+ Py_RETURN_NONE;
+}
+
+// ---------------------------------------------------------------------
+
+static string GetMessageName(CMessage* self) {
+ if (self->parent_field != NULL) {
+ return self->parent_field->descriptor->full_name();
+ } else {
+ return self->message->GetDescriptor()->full_name();
+ }
+}
+
+static PyObject* SerializeToString(CMessage* self, PyObject* args) {
+ if (!self->message->IsInitialized()) {
+ ScopedPyObjectPtr errors(FindInitializationErrors(self));
+ if (errors == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr comma(PyString_FromString(","));
+ if (comma == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr joined(
+ PyObject_CallMethod(comma.get(), "join", "O", errors.get()));
+ if (joined == NULL) {
+ return NULL;
+ }
+ PyErr_Format(EncodeError_class, "Message %s is missing required fields: %s",
+ GetMessageName(self).c_str(), PyString_AsString(joined.get()));
+ return NULL;
+ }
+ int size = self->message->ByteSize();
+ if (size <= 0) {
+ return PyBytes_FromString("");
+ }
+ PyObject* result = PyBytes_FromStringAndSize(NULL, size);
+ if (result == NULL) {
+ return NULL;
+ }
+ char* buffer = PyBytes_AS_STRING(result);
+ self->message->SerializeWithCachedSizesToArray(
+ reinterpret_cast<uint8*>(buffer));
+ return result;
+}
+
+static PyObject* SerializePartialToString(CMessage* self) {
+ string contents;
+ self->message->SerializePartialToString(&contents);
+ return PyBytes_FromStringAndSize(contents.c_str(), contents.size());
+}
+
+// Formats proto fields for ascii dumps using python formatting functions where
+// appropriate.
+class PythonFieldValuePrinter : public google::protobuf::TextFormat::FieldValuePrinter {
+ public:
+ PythonFieldValuePrinter() : float_holder_(PyFloat_FromDouble(0)) {}
+
+ // Python has some differences from C++ when printing floating point numbers.
+ //
+ // 1) Trailing .0 is always printed.
+ // 2) Outputted is rounded to 12 digits.
+ //
+ // We override floating point printing with the C-API function for printing
+ // Python floats to ensure consistency.
+ string PrintFloat(float value) const { return PrintDouble(value); }
+ string PrintDouble(double value) const {
+ reinterpret_cast<PyFloatObject*>(float_holder_.get())->ob_fval = value;
+ ScopedPyObjectPtr s(PyObject_Str(float_holder_.get()));
+ if (s == NULL) return string();
+#if PY_MAJOR_VERSION < 3
+ char *cstr = PyBytes_AS_STRING(static_cast<PyObject*>(s));
+#else
+ char *cstr = PyUnicode_AsUTF8(s);
+#endif
+ return string(cstr);
+ }
+
+ private:
+ // Holder for a python float object which we use to allow us to use
+ // the Python API for printing doubles. We initialize once and then
+ // directly modify it for every float printed to save on allocations
+ // and refcounting.
+ ScopedPyObjectPtr float_holder_;
+};
+
+static PyObject* ToStr(CMessage* self) {
+ google::protobuf::TextFormat::Printer printer;
+ // Passes ownership
+ printer.SetDefaultFieldValuePrinter(new PythonFieldValuePrinter());
+ printer.SetHideUnknownFields(true);
+ string output;
+ if (!printer.PrintToString(*self->message, &output)) {
+ PyErr_SetString(PyExc_ValueError, "Unable to convert message to str");
+ return NULL;
+ }
+ return PyString_FromString(output.c_str());
+}
+
+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");
+ return NULL;
+ }
+
+ other_message = reinterpret_cast<CMessage*>(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",
+ self->message->GetDescriptor()->full_name().c_str(),
+ other_message->message->GetDescriptor()->full_name().c_str());
+ return NULL;
+ }
+ AssureWritable(self);
+
+ // TODO(tibell): Message::MergeFrom might turn some child Messages
+ // into mutable messages, invalidating the message field in the
+ // corresponding CMessages. We should run a FixupMessageReferences
+ // pass here.
+
+ self->message->MergeFrom(*other_message->message);
+ Py_RETURN_NONE;
+}
+
+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");
+ return NULL;
+ }
+
+ other_message = reinterpret_cast<CMessage*>(arg);
+
+ if (self == other_message) {
+ Py_RETURN_NONE;
+ }
+
+ 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",
+ self->message->GetDescriptor()->full_name().c_str(),
+ other_message->message->GetDescriptor()->full_name().c_str());
+ return NULL;
+ }
+
+ AssureWritable(self);
+
+ // CopyFrom on the message will not clean up self->composite_fields,
+ // which can leave us in an inconsistent state, so clear it out here.
+ Clear(self);
+
+ self->message->CopyFrom(*other_message->message);
+
+ Py_RETURN_NONE;
+}
+
+static PyObject* MergeFromString(CMessage* self, PyObject* arg) {
+ const void* data;
+ Py_ssize_t data_length;
+ if (PyObject_AsReadBuffer(arg, &data, &data_length) < 0) {
+ return NULL;
+ }
+
+ AssureWritable(self);
+ google::protobuf::io::CodedInputStream input(
+ reinterpret_cast<const uint8*>(data), data_length);
+ input.SetExtensionRegistry(GetDescriptorPool(), global_message_factory);
+ bool success = self->message->MergePartialFromCodedStream(&input);
+ if (success) {
+ return PyInt_FromLong(input.CurrentPosition());
+ } else {
+ PyErr_Format(DecodeError_class, "Error parsing message");
+ return NULL;
+ }
+}
+
+static PyObject* ParseFromString(CMessage* self, PyObject* arg) {
+ if (Clear(self) == NULL) {
+ return NULL;
+ }
+ return MergeFromString(self, arg);
+}
+
+static PyObject* ByteSize(CMessage* self, PyObject* args) {
+ return PyLong_FromLong(self->message->ByteSize());
+}
+
+static PyObject* RegisterExtension(PyObject* cls,
+ PyObject* extension_handle) {
+ ScopedPyObjectPtr message_descriptor(PyObject_GetAttr(cls, kDESCRIPTOR));
+ if (message_descriptor == NULL) {
+ return NULL;
+ }
+ if (PyObject_SetAttrString(extension_handle, "containing_type",
+ message_descriptor) < 0) {
+ return NULL;
+ }
+ ScopedPyObjectPtr extensions_by_name(
+ PyObject_GetAttr(cls, k_extensions_by_name));
+ if (extensions_by_name == NULL) {
+ PyErr_SetString(PyExc_TypeError, "no extensions_by_name on class");
+ return NULL;
+ }
+ ScopedPyObjectPtr full_name(PyObject_GetAttr(extension_handle, kfull_name));
+ if (full_name == NULL) {
+ return NULL;
+ }
+ if (PyDict_SetItem(extensions_by_name, full_name, extension_handle) < 0) {
+ return NULL;
+ }
+
+ // Also store a mapping from extension number to implementing class.
+ ScopedPyObjectPtr extensions_by_number(
+ PyObject_GetAttr(cls, k_extensions_by_number));
+ if (extensions_by_number == NULL) {
+ 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 (PyDict_SetItem(extensions_by_number, number, extension_handle) < 0) {
+ return NULL;
+ }
+
+ CFieldDescriptor* cdescriptor =
+ extension_dict::InternalGetCDescriptorFromExtension(extension_handle);
+ ScopedPyObjectPtr py_cdescriptor(reinterpret_cast<PyObject*>(cdescriptor));
+ if (cdescriptor == NULL) {
+ return NULL;
+ }
+ Py_INCREF(extension_handle);
+ cdescriptor->descriptor_field = extension_handle;
+ const google::protobuf::FieldDescriptor* descriptor = cdescriptor->descriptor;
+ // Check if it's a message set
+ if (descriptor->is_extension() &&
+ descriptor->containing_type()->options().message_set_wire_format() &&
+ descriptor->type() == google::protobuf::FieldDescriptor::TYPE_MESSAGE &&
+ descriptor->message_type() == descriptor->extension_scope() &&
+ descriptor->label() == google::protobuf::FieldDescriptor::LABEL_OPTIONAL) {
+ ScopedPyObjectPtr message_name(PyString_FromStringAndSize(
+ descriptor->message_type()->full_name().c_str(),
+ descriptor->message_type()->full_name().size()));
+ if (message_name == NULL) {
+ return NULL;
+ }
+ PyDict_SetItem(extensions_by_name, message_name, extension_handle);
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject* SetInParent(CMessage* self, PyObject* args) {
+ AssureWritable(self);
+ Py_RETURN_NONE;
+}
+
+static PyObject* WhichOneof(CMessage* self, PyObject* arg) {
+ char* oneof_name;
+ if (!PyString_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError, "field name must be a string");
+ return NULL;
+ }
+ oneof_name = PyString_AsString(arg);
+ if (oneof_name == NULL) {
+ return NULL;
+ }
+ const google::protobuf::OneofDescriptor* oneof_desc =
+ self->message->GetDescriptor()->FindOneofByName(oneof_name);
+ if (oneof_desc == NULL) {
+ PyErr_Format(PyExc_ValueError,
+ "Protocol message has no oneof \"%s\" field.", oneof_name);
+ return NULL;
+ }
+ const google::protobuf::FieldDescriptor* field_in_oneof =
+ self->message->GetReflection()->GetOneofFieldDescriptor(
+ *self->message, oneof_desc);
+ if (field_in_oneof == NULL) {
+ Py_RETURN_NONE;
+ } else {
+ return PyString_FromString(field_in_oneof->name().c_str());
+ }
+}
+
+static PyObject* ListFields(CMessage* self) {
+ vector<const google::protobuf::FieldDescriptor*> fields;
+ self->message->GetReflection()->ListFields(*self->message, &fields);
+
+ PyObject* descriptor = PyDict_GetItem(Py_TYPE(self)->tp_dict, kDESCRIPTOR);
+ if (descriptor == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr fields_by_name(
+ PyObject_GetAttr(descriptor, kfields_by_name));
+ if (fields_by_name == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr extensions_by_name(PyObject_GetAttr(
+ reinterpret_cast<PyObject*>(Py_TYPE(self)), k_extensions_by_name));
+ if (extensions_by_name == NULL) {
+ PyErr_SetString(PyExc_ValueError, "no extensionsbyname");
+ return NULL;
+ }
+ // Normally, the list will be exactly the size of the fields.
+ PyObject* all_fields = PyList_New(fields.size());
+ if (all_fields == NULL) {
+ return NULL;
+ }
+
+ // When there are unknown extensions, the py list will *not* contain
+ // the field information. Thus the actual size of the py list will be
+ // smaller than the size of fields. Set the actual size at the end.
+ Py_ssize_t actual_size = 0;
+ for (Py_ssize_t i = 0; i < fields.size(); ++i) {
+ ScopedPyObjectPtr t(PyTuple_New(2));
+ if (t == NULL) {
+ Py_DECREF(all_fields);
+ return NULL;
+ }
+
+ if (fields[i]->is_extension()) {
+ const string& field_name = fields[i]->full_name();
+ PyObject* extension_field = PyDict_GetItemString(extensions_by_name,
+ field_name.c_str());
+ if (extension_field == NULL) {
+ // If we couldn't fetch extension_field, it means the module that
+ // defines this extension has not been explicitly imported in Python
+ // code, and the extension hasn't been registered. There's nothing much
+ // we can do about this, so just skip it in the output to match the
+ // behavior of the python implementation.
+ continue;
+ }
+ PyObject* extensions = reinterpret_cast<PyObject*>(self->extensions);
+ if (extensions == NULL) {
+ Py_DECREF(all_fields);
+ return NULL;
+ }
+ // 'extension' reference later stolen by PyTuple_SET_ITEM.
+ PyObject* extension = PyObject_GetItem(extensions, extension_field);
+ if (extension == NULL) {
+ Py_DECREF(all_fields);
+ return NULL;
+ }
+ Py_INCREF(extension_field);
+ PyTuple_SET_ITEM(t.get(), 0, extension_field);
+ // Steals reference to 'extension'
+ PyTuple_SET_ITEM(t.get(), 1, extension);
+ } else {
+ const string& field_name = fields[i]->name();
+ ScopedPyObjectPtr py_field_name(PyString_FromStringAndSize(
+ field_name.c_str(), field_name.length()));
+ if (py_field_name == NULL) {
+ PyErr_SetString(PyExc_ValueError, "bad string");
+ Py_DECREF(all_fields);
+ return NULL;
+ }
+ PyObject* field_descriptor =
+ PyDict_GetItem(fields_by_name, py_field_name);
+ if (field_descriptor == NULL) {
+ Py_DECREF(all_fields);
+ return NULL;
+ }
+
+ PyObject* field_value = GetAttr(self, py_field_name);
+ if (field_value == NULL) {
+ PyErr_SetObject(PyExc_ValueError, py_field_name);
+ Py_DECREF(all_fields);
+ return NULL;
+ }
+ Py_INCREF(field_descriptor);
+ PyTuple_SET_ITEM(t.get(), 0, field_descriptor);
+ PyTuple_SET_ITEM(t.get(), 1, field_value);
+ }
+ PyList_SET_ITEM(all_fields, actual_size, t.release());
+ ++actual_size;
+ }
+ Py_SIZE(all_fields) = actual_size;
+ return all_fields;
+}
+
+PyObject* FindInitializationErrors(CMessage* self) {
+ google::protobuf::Message* message = self->message;
+ vector<string> errors;
+ message->FindInitializationErrors(&errors);
+
+ PyObject* error_list = PyList_New(errors.size());
+ if (error_list == NULL) {
+ return NULL;
+ }
+ for (Py_ssize_t i = 0; i < errors.size(); ++i) {
+ const string& error = errors[i];
+ PyObject* error_string = PyString_FromStringAndSize(
+ error.c_str(), error.length());
+ if (error_string == NULL) {
+ Py_DECREF(error_list);
+ return NULL;
+ }
+ PyList_SET_ITEM(error_list, i, error_string);
+ }
+ return error_list;
+}
+
+static PyObject* RichCompare(CMessage* self, PyObject* other, int opid) {
+ if (!PyObject_TypeCheck(other, &CMessage_Type)) {
+ if (opid == Py_EQ) {
+ Py_RETURN_FALSE;
+ } else if (opid == Py_NE) {
+ Py_RETURN_TRUE;
+ }
+ }
+ if (opid == Py_EQ || opid == Py_NE) {
+ ScopedPyObjectPtr self_fields(ListFields(self));
+ ScopedPyObjectPtr other_fields(ListFields(
+ reinterpret_cast<CMessage*>(other)));
+ return PyObject_RichCompare(self_fields, other_fields, opid);
+ } else {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+}
+
+PyObject* InternalGetScalar(
+ CMessage* self,
+ const google::protobuf::FieldDescriptor* field_descriptor) {
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+
+ if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+ PyErr_SetString(
+ PyExc_KeyError, "Field does not belong to message!");
+ return NULL;
+ }
+
+ PyObject* result = NULL;
+ switch (field_descriptor->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+ int32 value = reflection->GetInt32(*message, field_descriptor);
+ result = PyInt_FromLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+ int64 value = reflection->GetInt64(*message, field_descriptor);
+ result = PyLong_FromLongLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+ uint32 value = reflection->GetUInt32(*message, field_descriptor);
+ result = PyInt_FromSize_t(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+ uint64 value = reflection->GetUInt64(*message, field_descriptor);
+ result = PyLong_FromUnsignedLongLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+ float value = reflection->GetFloat(*message, field_descriptor);
+ result = PyFloat_FromDouble(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value = reflection->GetDouble(*message, field_descriptor);
+ result = PyFloat_FromDouble(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+ bool value = reflection->GetBool(*message, field_descriptor);
+ result = PyBool_FromLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+ string value = reflection->GetString(*message, field_descriptor);
+ result = ToStringObject(field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+ if (!message->GetReflection()->HasField(*message, field_descriptor)) {
+ // Look for the value in the unknown fields.
+ google::protobuf::UnknownFieldSet* unknown_field_set =
+ message->GetReflection()->MutableUnknownFields(message);
+ for (int i = 0; i < unknown_field_set->field_count(); ++i) {
+ if (unknown_field_set->field(i).number() ==
+ field_descriptor->number()) {
+ result = PyInt_FromLong(unknown_field_set->field(i).varint());
+ break;
+ }
+ }
+ }
+
+ if (result == NULL) {
+ const google::protobuf::EnumValueDescriptor* enum_value =
+ message->GetReflection()->GetEnum(*message, field_descriptor);
+ result = PyInt_FromLong(enum_value->number());
+ }
+ break;
+ }
+ default:
+ PyErr_Format(
+ PyExc_SystemError, "Getting a value from a field of unknown type %d",
+ field_descriptor->cpp_type());
+ }
+
+ return result;
+}
+
+PyObject* InternalGetSubMessage(CMessage* self,
+ CFieldDescriptor* cfield_descriptor) {
+ PyObject* field = cfield_descriptor->descriptor_field;
+ ScopedPyObjectPtr message_type(PyObject_GetAttr(field, kmessage_type));
+ if (message_type == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr concrete_class(
+ PyObject_GetAttr(message_type, k_concrete_class));
+ if (concrete_class == NULL) {
+ return NULL;
+ }
+ PyObject* py_cmsg = cmessage::NewEmpty(concrete_class);
+ if (py_cmsg == NULL) {
+ return NULL;
+ }
+ if (!PyObject_TypeCheck(py_cmsg, &CMessage_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Not a CMessage!");
+ }
+ CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
+
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ cfield_descriptor->descriptor;
+ const google::protobuf::Reflection* reflection = self->message->GetReflection();
+ const google::protobuf::Message& sub_message = reflection->GetMessage(
+ *self->message, field_descriptor, global_message_factory);
+ cmsg->owner = self->owner;
+ cmsg->parent = self;
+ cmsg->parent_field = cfield_descriptor;
+ cmsg->read_only = !reflection->HasField(*self->message, field_descriptor);
+ cmsg->message = const_cast<google::protobuf::Message*>(&sub_message);
+
+ if (InitAttributes(cmsg, NULL, NULL) < 0) {
+ Py_DECREF(py_cmsg);
+ return NULL;
+ }
+ return py_cmsg;
+}
+
+int InternalSetScalar(
+ CMessage* self,
+ const google::protobuf::FieldDescriptor* field_descriptor,
+ PyObject* arg) {
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+
+ if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+ PyErr_SetString(
+ PyExc_KeyError, "Field does not belong to message!");
+ return -1;
+ }
+
+ if (MaybeReleaseOverlappingOneofField(self, field_descriptor) < 0) {
+ return -1;
+ }
+
+ switch (field_descriptor->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+ GOOGLE_CHECK_GET_INT32(arg, value, -1);
+ reflection->SetInt32(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+ GOOGLE_CHECK_GET_INT64(arg, value, -1);
+ reflection->SetInt64(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+ GOOGLE_CHECK_GET_UINT32(arg, value, -1);
+ reflection->SetUInt32(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+ GOOGLE_CHECK_GET_UINT64(arg, value, -1);
+ reflection->SetUInt64(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+ GOOGLE_CHECK_GET_FLOAT(arg, value, -1);
+ reflection->SetFloat(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+ GOOGLE_CHECK_GET_DOUBLE(arg, value, -1);
+ reflection->SetDouble(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+ GOOGLE_CHECK_GET_BOOL(arg, value, -1);
+ reflection->SetBool(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+ if (!CheckAndSetString(
+ arg, message, field_descriptor, reflection, false, -1)) {
+ return -1;
+ }
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+ GOOGLE_CHECK_GET_INT32(arg, value, -1);
+ const google::protobuf::EnumDescriptor* enum_descriptor =
+ field_descriptor->enum_type();
+ const google::protobuf::EnumValueDescriptor* enum_value =
+ enum_descriptor->FindValueByNumber(value);
+ if (enum_value != NULL) {
+ reflection->SetEnum(message, field_descriptor, enum_value);
+ } else {
+ PyErr_Format(PyExc_ValueError, "Unknown enum value: %d", value);
+ return -1;
+ }
+ break;
+ }
+ default:
+ PyErr_Format(
+ PyExc_SystemError, "Setting value to a field of unknown type %d",
+ field_descriptor->cpp_type());
+ return -1;
+ }
+
+ return 0;
+}
+
+PyObject* FromString(PyTypeObject* cls, PyObject* serialized) {
+ PyObject* py_cmsg = PyObject_CallObject(
+ reinterpret_cast<PyObject*>(cls), NULL);
+ if (py_cmsg == NULL) {
+ return NULL;
+ }
+ CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
+
+ ScopedPyObjectPtr py_length(MergeFromString(cmsg, serialized));
+ if (py_length == NULL) {
+ Py_DECREF(py_cmsg);
+ return NULL;
+ }
+
+ if (InitAttributes(cmsg, NULL, NULL) < 0) {
+ Py_DECREF(py_cmsg);
+ return NULL;
+ }
+ return py_cmsg;
+}
+
+static PyObject* AddDescriptors(PyTypeObject* cls,
+ PyObject* descriptor) {
+ if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+ k_extensions_by_name, PyDict_New()) < 0) {
+ return NULL;
+ }
+ if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+ k_extensions_by_number, PyDict_New()) < 0) {
+ return NULL;
+ }
+
+ ScopedPyObjectPtr field_descriptors(PyDict_New());
+
+ ScopedPyObjectPtr fields(PyObject_GetAttrString(descriptor, "fields"));
+ if (fields == NULL) {
+ return NULL;
+ }
+
+ ScopedPyObjectPtr _NUMBER_string(PyString_FromString("_FIELD_NUMBER"));
+ if (_NUMBER_string == NULL) {
+ return NULL;
+ }
+
+ const Py_ssize_t fields_size = PyList_GET_SIZE(fields.get());
+ for (int i = 0; i < fields_size; ++i) {
+ PyObject* field = PyList_GET_ITEM(fields.get(), i);
+ ScopedPyObjectPtr field_name(PyObject_GetAttr(field, kname));
+ ScopedPyObjectPtr full_field_name(PyObject_GetAttr(field, kfull_name));
+ if (field_name == NULL || full_field_name == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Name is null");
+ return NULL;
+ }
+
+ PyObject* field_descriptor =
+ cdescriptor_pool::FindFieldByName(descriptor_pool, full_field_name);
+ if (field_descriptor == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Couldn't find field");
+ return NULL;
+ }
+ Py_INCREF(field);
+ CFieldDescriptor* cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(
+ field_descriptor);
+ cfield_descriptor->descriptor_field = field;
+ if (PyDict_SetItem(field_descriptors, field_name, field_descriptor) < 0) {
+ return NULL;
+ }
+
+ // The FieldDescriptor's name field might either be of type bytes or
+ // of type unicode, depending on whether the FieldDescriptor was
+ // parsed from a serialized message or read from the
+ // <message>_pb2.py module.
+ ScopedPyObjectPtr field_name_upcased(
+ PyObject_CallMethod(field_name, "upper", NULL));
+ if (field_name_upcased == NULL) {
+ return NULL;
+ }
+
+ ScopedPyObjectPtr field_number_name(PyObject_CallMethod(
+ field_name_upcased, "__add__", "(O)", _NUMBER_string.get()));
+ if (field_number_name == NULL) {
+ return NULL;
+ }
+
+ ScopedPyObjectPtr number(PyInt_FromLong(
+ cfield_descriptor->descriptor->number()));
+ if (number == NULL) {
+ return NULL;
+ }
+ if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+ field_number_name, number) == -1) {
+ return NULL;
+ }
+ }
+
+ PyDict_SetItem(cls->tp_dict, k__descriptors, field_descriptors);
+
+ // Enum Values
+ ScopedPyObjectPtr enum_types(PyObject_GetAttrString(descriptor,
+ "enum_types"));
+ if (enum_types == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr type_iter(PyObject_GetIter(enum_types));
+ if (type_iter == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr enum_type;
+ while ((enum_type.reset(PyIter_Next(type_iter))) != NULL) {
+ ScopedPyObjectPtr wrapped(PyObject_CallFunctionObjArgs(
+ EnumTypeWrapper_class, enum_type.get(), NULL));
+ if (wrapped == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr enum_name(PyObject_GetAttr(enum_type, kname));
+ if (enum_name == NULL) {
+ return NULL;
+ }
+ if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+ enum_name, wrapped) == -1) {
+ return NULL;
+ }
+
+ ScopedPyObjectPtr enum_values(PyObject_GetAttrString(enum_type, "values"));
+ if (enum_values == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr values_iter(PyObject_GetIter(enum_values));
+ if (values_iter == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr enum_value;
+ while ((enum_value.reset(PyIter_Next(values_iter))) != NULL) {
+ ScopedPyObjectPtr value_name(PyObject_GetAttr(enum_value, kname));
+ if (value_name == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr value_number(PyObject_GetAttrString(enum_value,
+ "number"));
+ if (value_number == NULL) {
+ return NULL;
+ }
+ if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+ value_name, value_number) == -1) {
+ return NULL;
+ }
+ }
+ if (PyErr_Occurred()) { // If PyIter_Next failed
+ return NULL;
+ }
+ }
+ if (PyErr_Occurred()) { // If PyIter_Next failed
+ return NULL;
+ }
+
+ ScopedPyObjectPtr extension_dict(
+ PyObject_GetAttr(descriptor, kextensions_by_name));
+ if (extension_dict == NULL || !PyDict_Check(extension_dict)) {
+ PyErr_SetString(PyExc_TypeError, "extensions_by_name not a dict");
+ return NULL;
+ }
+ Py_ssize_t pos = 0;
+ PyObject* extension_name;
+ PyObject* extension_field;
+
+ while (PyDict_Next(extension_dict, &pos, &extension_name, &extension_field)) {
+ if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+ extension_name, extension_field) == -1) {
+ return NULL;
+ }
+ ScopedPyObjectPtr py_cfield_descriptor(
+ PyObject_GetAttrString(extension_field, "_cdescriptor"));
+ if (py_cfield_descriptor == NULL) {
+ return NULL;
+ }
+ CFieldDescriptor* cfield_descriptor =
+ reinterpret_cast<CFieldDescriptor*>(py_cfield_descriptor.get());
+ Py_INCREF(extension_field);
+ cfield_descriptor->descriptor_field = extension_field;
+
+ ScopedPyObjectPtr field_name_upcased(
+ PyObject_CallMethod(extension_name, "upper", NULL));
+ if (field_name_upcased == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr field_number_name(PyObject_CallMethod(
+ field_name_upcased, "__add__", "(O)", _NUMBER_string.get()));
+ if (field_number_name == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr number(PyInt_FromLong(
+ cfield_descriptor->descriptor->number()));
+ if (number == NULL) {
+ return NULL;
+ }
+ if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+ field_number_name, PyInt_FromLong(
+ cfield_descriptor->descriptor->number())) == -1) {
+ return NULL;
+ }
+ }
+
+ Py_RETURN_NONE;
+}
+
+PyObject* DeepCopy(CMessage* self, PyObject* arg) {
+ PyObject* clone = PyObject_CallObject(
+ reinterpret_cast<PyObject*>(Py_TYPE(self)), NULL);
+ if (clone == NULL) {
+ return NULL;
+ }
+ if (!PyObject_TypeCheck(clone, &CMessage_Type)) {
+ Py_DECREF(clone);
+ return NULL;
+ }
+ if (InitAttributes(reinterpret_cast<CMessage*>(clone), NULL, NULL) < 0) {
+ Py_DECREF(clone);
+ return NULL;
+ }
+ if (MergeFrom(reinterpret_cast<CMessage*>(clone),
+ reinterpret_cast<PyObject*>(self)) == NULL) {
+ Py_DECREF(clone);
+ return NULL;
+ }
+ return clone;
+}
+
+PyObject* ToUnicode(CMessage* self) {
+ // Lazy import to prevent circular dependencies
+ ScopedPyObjectPtr text_format(
+ PyImport_ImportModule("google.protobuf.text_format"));
+ if (text_format == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr method_name(PyString_FromString("MessageToString"));
+ if (method_name == NULL) {
+ return NULL;
+ }
+ Py_INCREF(Py_True);
+ ScopedPyObjectPtr encoded(PyObject_CallMethodObjArgs(text_format, method_name,
+ self, Py_True, NULL));
+ Py_DECREF(Py_True);
+ if (encoded == NULL) {
+ return NULL;
+ }
+#if PY_MAJOR_VERSION < 3
+ PyObject* decoded = PyString_AsDecodedObject(encoded, "utf-8", NULL);
+#else
+ PyObject* decoded = PyUnicode_FromEncodedObject(encoded, "utf-8", NULL);
+#endif
+ if (decoded == NULL) {
+ return NULL;
+ }
+ return decoded;
+}
+
+PyObject* Reduce(CMessage* self) {
+ ScopedPyObjectPtr constructor(reinterpret_cast<PyObject*>(Py_TYPE(self)));
+ constructor.inc();
+ ScopedPyObjectPtr args(PyTuple_New(0));
+ if (args == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr state(PyDict_New());
+ if (state == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr serialized(SerializePartialToString(self));
+ if (serialized == NULL) {
+ return NULL;
+ }
+ if (PyDict_SetItemString(state, "serialized", serialized) < 0) {
+ return NULL;
+ }
+ return Py_BuildValue("OOO", constructor.get(), args.get(), state.get());
+}
+
+PyObject* SetState(CMessage* self, PyObject* state) {
+ if (!PyDict_Check(state)) {
+ PyErr_SetString(PyExc_TypeError, "state not a dict");
+ return NULL;
+ }
+ PyObject* serialized = PyDict_GetItemString(state, "serialized");
+ if (serialized == NULL) {
+ return NULL;
+ }
+ if (ParseFromString(self, serialized) == NULL) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+// CMessage static methods:
+PyObject* _GetFieldDescriptor(PyObject* unused, PyObject* arg) {
+ return cdescriptor_pool::FindFieldByName(descriptor_pool, arg);
+}
+
+PyObject* _GetExtensionDescriptor(PyObject* unused, PyObject* arg) {
+ return cdescriptor_pool::FindExtensionByName(descriptor_pool, arg);
+}
+
+static PyMemberDef Members[] = {
+ {"Extensions", T_OBJECT_EX, offsetof(CMessage, extensions), 0,
+ "Extension dict"},
+ {NULL}
+};
+
+static PyMethodDef Methods[] = {
+ { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
+ "Makes a deep copy of the class." },
+ { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
+ "Outputs picklable representation of the message." },
+ { "__setstate__", (PyCFunction)SetState, METH_O,
+ "Inputs picklable representation of the message." },
+ { "__unicode__", (PyCFunction)ToUnicode, METH_NOARGS,
+ "Outputs a unicode representation of the message." },
+ { "AddDescriptors", (PyCFunction)AddDescriptors, METH_O | METH_CLASS,
+ "Adds field descriptors to the class" },
+ { "ByteSize", (PyCFunction)ByteSize, METH_NOARGS,
+ "Returns the size of the message in bytes." },
+ { "Clear", (PyCFunction)Clear, METH_NOARGS,
+ "Clears the message." },
+ { "ClearExtension", (PyCFunction)ClearExtension, METH_O,
+ "Clears a message field." },
+ { "ClearField", (PyCFunction)ClearField, METH_O,
+ "Clears a message field." },
+ { "CopyFrom", (PyCFunction)CopyFrom, METH_O,
+ "Copies a protocol message into the current message." },
+ { "FindInitializationErrors", (PyCFunction)FindInitializationErrors,
+ METH_NOARGS,
+ "Finds unset required fields." },
+ { "FromString", (PyCFunction)FromString, METH_O | METH_CLASS,
+ "Creates new method instance from given serialized data." },
+ { "HasExtension", (PyCFunction)HasExtension, METH_O,
+ "Checks if a message field is set." },
+ { "HasField", (PyCFunction)HasField, METH_O,
+ "Checks if a message field is set." },
+ { "IsInitialized", (PyCFunction)IsInitialized, METH_VARARGS,
+ "Checks if all required fields of a protocol message are set." },
+ { "ListFields", (PyCFunction)ListFields, METH_NOARGS,
+ "Lists all set fields of a message." },
+ { "MergeFrom", (PyCFunction)MergeFrom, METH_O,
+ "Merges a protocol message into the current message." },
+ { "MergeFromString", (PyCFunction)MergeFromString, METH_O,
+ "Merges a serialized message into the current message." },
+ { "ParseFromString", (PyCFunction)ParseFromString, METH_O,
+ "Parses a serialized message into the current message." },
+ { "RegisterExtension", (PyCFunction)RegisterExtension, METH_O | METH_CLASS,
+ "Registers an extension with the current message." },
+ { "SerializePartialToString", (PyCFunction)SerializePartialToString,
+ METH_NOARGS,
+ "Serializes the message to a string, even if it isn't initialized." },
+ { "SerializeToString", (PyCFunction)SerializeToString, METH_NOARGS,
+ "Serializes the message to a string, only for initialized messages." },
+ { "SetInParent", (PyCFunction)SetInParent, METH_NOARGS,
+ "Sets the has bit of the given field in its parent message." },
+ { "WhichOneof", (PyCFunction)WhichOneof, METH_O,
+ "Returns the name of the field set inside a oneof, "
+ "or None if no field is set." },
+
+ // Static Methods.
+ { "_BuildFile", (PyCFunction)Python_BuildFile, METH_O | METH_STATIC,
+ "Registers a new protocol buffer file in the global C++ descriptor pool." },
+ { "_GetFieldDescriptor", (PyCFunction)_GetFieldDescriptor,
+ METH_O | METH_STATIC, "Finds a field descriptor in the message pool." },
+ { "_GetExtensionDescriptor", (PyCFunction)_GetExtensionDescriptor,
+ METH_O | METH_STATIC,
+ "Finds a extension descriptor in the message pool." },
+ { NULL, NULL}
+};
+
+PyObject* GetAttr(CMessage* self, PyObject* name) {
+ PyObject* value = PyDict_GetItem(self->composite_fields, name);
+ if (value != NULL) {
+ Py_INCREF(value);
+ return value;
+ }
+
+ PyObject* descriptor = GetDescriptor(self, name);
+ if (descriptor != NULL) {
+ CFieldDescriptor* cdescriptor =
+ reinterpret_cast<CFieldDescriptor*>(descriptor);
+ const google::protobuf::FieldDescriptor* field_descriptor = cdescriptor->descriptor;
+ if (field_descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+ if (field_descriptor->cpp_type() ==
+ google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+ PyObject* py_container = PyObject_CallObject(
+ reinterpret_cast<PyObject*>(&RepeatedCompositeContainer_Type),
+ NULL);
+ if (py_container == NULL) {
+ return NULL;
+ }
+ RepeatedCompositeContainer* container =
+ reinterpret_cast<RepeatedCompositeContainer*>(py_container);
+ PyObject* field = cdescriptor->descriptor_field;
+ PyObject* message_type = PyObject_GetAttr(field, kmessage_type);
+ if (message_type == NULL) {
+ return NULL;
+ }
+ PyObject* concrete_class =
+ PyObject_GetAttr(message_type, k_concrete_class);
+ if (concrete_class == NULL) {
+ return NULL;
+ }
+ container->parent = self;
+ container->parent_field = cdescriptor;
+ container->message = self->message;
+ container->owner = self->owner;
+ container->subclass_init = concrete_class;
+ Py_DECREF(message_type);
+ if (PyDict_SetItem(self->composite_fields, name, py_container) < 0) {
+ Py_DECREF(py_container);
+ return NULL;
+ }
+ return py_container;
+ } else {
+ ScopedPyObjectPtr init_args(PyTuple_Pack(2, self, cdescriptor));
+ PyObject* py_container = PyObject_CallObject(
+ reinterpret_cast<PyObject*>(&RepeatedScalarContainer_Type),
+ init_args);
+ if (py_container == NULL) {
+ return NULL;
+ }
+ if (PyDict_SetItem(self->composite_fields, name, py_container) < 0) {
+ Py_DECREF(py_container);
+ return NULL;
+ }
+ return py_container;
+ }
+ } else {
+ if (field_descriptor->cpp_type() ==
+ google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+ PyObject* sub_message = InternalGetSubMessage(self, cdescriptor);
+ if (PyDict_SetItem(self->composite_fields, name, sub_message) < 0) {
+ Py_DECREF(sub_message);
+ return NULL;
+ }
+ return sub_message;
+ } else {
+ return InternalGetScalar(self, field_descriptor);
+ }
+ }
+ }
+
+ return CMessage_Type.tp_base->tp_getattro(reinterpret_cast<PyObject*>(self),
+ name);
+}
+
+int SetAttr(CMessage* self, PyObject* name, PyObject* value) {
+ if (PyDict_Contains(self->composite_fields, name)) {
+ PyErr_SetString(PyExc_TypeError, "Can't set composite field");
+ return -1;
+ }
+
+ PyObject* descriptor = GetDescriptor(self, name);
+ if (descriptor != NULL) {
+ AssureWritable(self);
+ CFieldDescriptor* cdescriptor =
+ reinterpret_cast<CFieldDescriptor*>(descriptor);
+ const google::protobuf::FieldDescriptor* field_descriptor = cdescriptor->descriptor;
+ if (field_descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+ PyErr_Format(PyExc_AttributeError, "Assignment not allowed to repeated "
+ "field \"%s\" in protocol message object.",
+ field_descriptor->name().c_str());
+ return -1;
+ } else {
+ if (field_descriptor->cpp_type() ==
+ google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+ PyErr_Format(PyExc_AttributeError, "Assignment not allowed to "
+ "field \"%s\" in protocol message object.",
+ field_descriptor->name().c_str());
+ return -1;
+ } else {
+ return InternalSetScalar(self, field_descriptor, value);
+ }
+ }
+ }
+
+ PyErr_Format(PyExc_AttributeError, "Assignment not allowed");
+ return -1;
+}
+
+} // namespace cmessage
+
+PyTypeObject CMessage_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "google.protobuf.internal."
+ "cpp._message.CMessage", // tp_name
+ sizeof(CMessage), // tp_basicsize
+ 0, // tp_itemsize
+ (destructor)cmessage::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
+ (reprfunc)cmessage::ToStr, // tp_str
+ (getattrofunc)cmessage::GetAttr, // tp_getattro
+ (setattrofunc)cmessage::SetAttr, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags
+ "A ProtocolMessage", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ (richcmpfunc)cmessage::RichCompare, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ cmessage::Methods, // tp_methods
+ cmessage::Members, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ (initproc)cmessage::Init, // tp_init
+ 0, // tp_alloc
+ cmessage::New, // tp_new
+};
+
+// --- Exposing the C proto living inside Python proto to C code:
+
+const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg);
+Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg);
+
+static const google::protobuf::Message* GetCProtoInsidePyProtoImpl(PyObject* msg) {
+ if (!PyObject_TypeCheck(msg, &CMessage_Type)) {
+ return NULL;
+ }
+ CMessage* cmsg = reinterpret_cast<CMessage*>(msg);
+ return cmsg->message;
+}
+
+static google::protobuf::Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) {
+ if (!PyObject_TypeCheck(msg, &CMessage_Type)) {
+ return NULL;
+ }
+ CMessage* cmsg = reinterpret_cast<CMessage*>(msg);
+ if (PyDict_Size(cmsg->composite_fields) != 0 ||
+ (cmsg->extensions != NULL &&
+ PyDict_Size(cmsg->extensions->values) != 0)) {
+ // There is currently no way of accurately syncing arbitrary changes to
+ // the underlying C++ message back to the CMessage (e.g. removed repeated
+ // composite containers). We only allow direct mutation of the underlying
+ // C++ message if there is no child data in the CMessage.
+ return NULL;
+ }
+ cmessage::AssureWritable(cmsg);
+ return cmsg->message;
+}
+
+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.";
+
+void InitGlobals() {
+ // TODO(gps): Check all return values in this function for NULL and propagate
+ // the error (MemoryError) on up to result in an import failure. These should
+ // also be freed and reset to NULL during finalization.
+ kPythonZero = PyInt_FromLong(0);
+ kint32min_py = PyInt_FromLong(kint32min);
+ kint32max_py = PyInt_FromLong(kint32max);
+ kuint32max_py = PyLong_FromLongLong(kuint32max);
+ kint64min_py = PyLong_FromLongLong(kint64min);
+ kint64max_py = PyLong_FromLongLong(kint64max);
+ kuint64max_py = PyLong_FromUnsignedLongLong(kuint64max);
+
+ kDESCRIPTOR = PyString_FromString("DESCRIPTOR");
+ k__descriptors = PyString_FromString("__descriptors");
+ kfull_name = PyString_FromString("full_name");
+ kis_extendable = PyString_FromString("is_extendable");
+ kextensions_by_name = PyString_FromString("extensions_by_name");
+ k_extensions_by_name = PyString_FromString("_extensions_by_name");
+ k_extensions_by_number = PyString_FromString("_extensions_by_number");
+ k_concrete_class = PyString_FromString("_concrete_class");
+ kmessage_type = PyString_FromString("message_type");
+ kname = PyString_FromString("name");
+ kfields_by_name = PyString_FromString("fields_by_name");
+
+ global_message_factory = new DynamicMessageFactory(GetDescriptorPool());
+ global_message_factory->SetDelegateToGeneratedFactory(true);
+
+ descriptor_pool = reinterpret_cast<google::protobuf::python::CDescriptorPool*>(
+ Python_NewCDescriptorPool(NULL, NULL));
+}
+
+bool InitProto2MessageModule(PyObject *m) {
+ InitGlobals();
+
+ google::protobuf::python::CMessage_Type.tp_hash = PyObject_HashNotImplemented;
+ if (PyType_Ready(&google::protobuf::python::CMessage_Type) < 0) {
+ return false;
+ }
+
+ // All three of these are actually set elsewhere, directly onto the child
+ // protocol buffer message class, but set them here as well to document that
+ // subclasses need to set these.
+ PyDict_SetItem(google::protobuf::python::CMessage_Type.tp_dict, kDESCRIPTOR, Py_None);
+ PyDict_SetItem(google::protobuf::python::CMessage_Type.tp_dict,
+ k_extensions_by_name, Py_None);
+ PyDict_SetItem(google::protobuf::python::CMessage_Type.tp_dict,
+ k_extensions_by_number, Py_None);
+
+ PyModule_AddObject(m, "Message", reinterpret_cast<PyObject*>(
+ &google::protobuf::python::CMessage_Type));
+
+ google::protobuf::python::RepeatedScalarContainer_Type.tp_new = PyType_GenericNew;
+ google::protobuf::python::RepeatedScalarContainer_Type.tp_hash =
+ PyObject_HashNotImplemented;
+ if (PyType_Ready(&google::protobuf::python::RepeatedScalarContainer_Type) < 0) {
+ return false;
+ }
+
+ PyModule_AddObject(m, "RepeatedScalarContainer",
+ reinterpret_cast<PyObject*>(
+ &google::protobuf::python::RepeatedScalarContainer_Type));
+
+ google::protobuf::python::RepeatedCompositeContainer_Type.tp_new = PyType_GenericNew;
+ google::protobuf::python::RepeatedCompositeContainer_Type.tp_hash =
+ PyObject_HashNotImplemented;
+ if (PyType_Ready(&google::protobuf::python::RepeatedCompositeContainer_Type) < 0) {
+ return false;
+ }
+
+ PyModule_AddObject(
+ m, "RepeatedCompositeContainer",
+ reinterpret_cast<PyObject*>(
+ &google::protobuf::python::RepeatedCompositeContainer_Type));
+
+ google::protobuf::python::ExtensionDict_Type.tp_new = PyType_GenericNew;
+ google::protobuf::python::ExtensionDict_Type.tp_hash = PyObject_HashNotImplemented;
+ if (PyType_Ready(&google::protobuf::python::ExtensionDict_Type) < 0) {
+ return false;
+ }
+
+ PyModule_AddObject(
+ m, "ExtensionDict",
+ reinterpret_cast<PyObject*>(&google::protobuf::python::ExtensionDict_Type));
+
+ if (!google::protobuf::python::InitDescriptor()) {
+ return false;
+ }
+
+ PyObject* enum_type_wrapper = PyImport_ImportModule(
+ "google.protobuf.internal.enum_type_wrapper");
+ if (enum_type_wrapper == NULL) {
+ return false;
+ }
+ google::protobuf::python::EnumTypeWrapper_class =
+ PyObject_GetAttrString(enum_type_wrapper, "EnumTypeWrapper");
+ Py_DECREF(enum_type_wrapper);
+
+ PyObject* message_module = PyImport_ImportModule(
+ "google.protobuf.message");
+ if (message_module == NULL) {
+ return false;
+ }
+ google::protobuf::python::EncodeError_class = PyObject_GetAttrString(message_module,
+ "EncodeError");
+ google::protobuf::python::DecodeError_class = PyObject_GetAttrString(message_module,
+ "DecodeError");
+ Py_DECREF(message_module);
+
+ PyObject* pickle_module = PyImport_ImportModule("pickle");
+ if (pickle_module == NULL) {
+ return false;
+ }
+ google::protobuf::python::PickleError_class = PyObject_GetAttrString(pickle_module,
+ "PickleError");
+ Py_DECREF(pickle_module);
+
+ // Override {Get,Mutable}CProtoInsidePyProto.
+ google::protobuf::python::GetCProtoInsidePyProtoPtr =
+ google::protobuf::python::GetCProtoInsidePyProtoImpl;
+ google::protobuf::python::MutableCProtoInsidePyProtoPtr =
+ google::protobuf::python::MutableCProtoInsidePyProtoImpl;
+
+ return true;
+}
+
+} // 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
new file mode 100644
index 0000000..9f4978f
--- /dev/null
+++ b/python/google/protobuf/pyext/message.h
@@ -0,0 +1,305 @@
+// 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: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__
+
+#include <Python.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+#include <string>
+
+
+namespace google {
+namespace protobuf {
+
+class Message;
+class Reflection;
+class FieldDescriptor;
+
+using internal::shared_ptr;
+
+namespace python {
+
+struct CFieldDescriptor;
+struct ExtensionDict;
+
+typedef struct CMessage {
+ PyObject_HEAD;
+
+ // This is the top-level C++ Message object that owns the whole
+ // proto tree. Every Python CMessage 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;
+
+ // Weak reference to a parent CMessage object. This is NULL for any top-level
+ // message and is set for any child message (i.e. a child submessage or a
+ // part of a repeated composite field).
+ //
+ // Used to make sure all ancestors are also mutable when first modifying
+ // a child submessage (in other words, turning a default message instance
+ // into a mutable one).
+ //
+ // If a submessage is released (becomes a new top-level message), this field
+ // MUST be set to NULL. The parent may get deallocated and further attempts
+ // to use this pointer will result in a crash.
+ struct CMessage* parent;
+
+ // Weak reference to the parent's descriptor that describes this submessage.
+ // Used together with the parent's message when making a default message
+ // instance mutable.
+ // TODO(anuraag): With a bit of work on the Python/C++ layer, it should be
+ // possible to make this a direct pointer to a C++ FieldDescriptor, this would
+ // be easier if this implementation replaces upstream.
+ CFieldDescriptor* parent_field;
+
+ // Pointer to the C++ Message object for this CMessage. The
+ // CMessage does not own this pointer.
+ Message* message;
+
+ // Indicates this submessage is pointing to a default instance of a message.
+ // Submessages are always first created as read only messages and are then
+ // made writable, at which point this field is set to false.
+ bool read_only;
+
+ // A reference to a Python dictionary containing CMessage,
+ // RepeatedCompositeContainer, and RepeatedScalarContainer
+ // objects. Used as a cache to make sure we don't have to make a
+ // Python wrapper for the C++ Message objects on every access, or
+ // deal with the synchronization nightmare that could create.
+ PyObject* composite_fields;
+
+ // A reference to the dictionary containing the message's extensions.
+ // Similar to composite_fields, acting as a cache, but also contains the
+ // required extension dict logic.
+ ExtensionDict* extensions;
+} CMessage;
+
+extern PyTypeObject CMessage_Type;
+
+namespace cmessage {
+
+// Create a new empty message that can be populated by the parent.
+PyObject* NewEmpty(PyObject* 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.
+//
+// Corresponds to reflection api method ReleaseMessage.
+int ReleaseSubMessage(google::protobuf::Message* message,
+ const google::protobuf::FieldDescriptor* field_descriptor,
+ CMessage* child_cmessage);
+
+// Initializes a new CMessage instance for a submessage. Only called once per
+// submessage as the result is cached in composite_fields.
+//
+// Corresponds to reflection api method GetMessage.
+PyObject* InternalGetSubMessage(CMessage* self,
+ CFieldDescriptor* cfield_descriptor);
+
+// Deletes a range of C++ submessages in a repeated field (following a
+// removal in a RepeatedCompositeContainer).
+//
+// Releases messages to the provided cmessage_list if it is not NULL rather
+// than just removing them from the underlying proto. This cmessage_list must
+// have a CMessage for each underlying submessage. The CMessages refered to
+// by slice will be removed from cmessage_list by this function.
+//
+// Corresponds to reflection api method RemoveLast.
+int InternalDeleteRepeatedField(google::protobuf::Message* message,
+ const google::protobuf::FieldDescriptor* field_descriptor,
+ PyObject* slice, PyObject* cmessage_list);
+
+// Sets the specified scalar value to the message.
+int InternalSetScalar(CMessage* self,
+ const google::protobuf::FieldDescriptor* field_descriptor,
+ PyObject* value);
+
+// Retrieves the specified scalar value from the message.
+//
+// Returns a new python reference.
+PyObject* InternalGetScalar(CMessage* self,
+ const google::protobuf::FieldDescriptor* field_descriptor);
+
+// Clears the message, removing all contained data. Extension dictionary and
+// submessages are released first if there are remaining external references.
+//
+// Corresponds to message api method Clear.
+PyObject* Clear(CMessage* self);
+
+// Clears the data described by the given descriptor. Used to clear extensions
+// (which don't have names). Extension release is handled by ExtensionDict
+// class, not this function.
+// TODO(anuraag): Try to make this discrepancy in release semantics with
+// ClearField less confusing.
+//
+// Corresponds to reflection api method ClearField.
+PyObject* ClearFieldByDescriptor(
+ CMessage* self,
+ const google::protobuf::FieldDescriptor* descriptor);
+
+// Clears the data for the given field name. The message is released if there
+// are any external references.
+//
+// Corresponds to reflection api method ClearField.
+PyObject* ClearField(CMessage* self, PyObject* arg);
+
+// Checks if the message has the field described by the descriptor. Used for
+// extensions (which have no name).
+//
+// Corresponds to reflection api method HasField
+PyObject* HasFieldByDescriptor(
+ CMessage* self, const google::protobuf::FieldDescriptor* field_descriptor);
+
+// Checks if the message has the named field.
+//
+// Corresponds to reflection api method HasField.
+PyObject* HasField(CMessage* self, PyObject* arg);
+
+// Initializes constants/enum values on a message. This is called by
+// RepeatedCompositeContainer and ExtensionDict after calling the constructor.
+// TODO(anuraag): Make it always called from within the constructor since it can
+int InitAttributes(CMessage* self, PyObject* descriptor, PyObject* kwargs);
+
+PyObject* MergeFrom(CMessage* self, PyObject* arg);
+
+// Retrieves an attribute named 'name' from CMessage 'self'. Returns
+// the attribute value on success, or NULL on failure.
+//
+// Returns a new reference.
+PyObject* GetAttr(CMessage* self, PyObject* name);
+
+// Set the value of the attribute named 'name', for CMessage 'self',
+// to the value 'value'. Returns -1 on failure.
+int SetAttr(CMessage* self, PyObject* name, PyObject* value);
+
+PyObject* FindInitializationErrors(CMessage* self);
+
+// Set the owner field of self and any children of self, recursively.
+// Used when self is being released and thus has a new owner (the
+// released Message.)
+int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner);
+
+int AssureWritable(CMessage* self);
+
+} // namespace cmessage
+
+/* Is 64bit */
+#define IS_64BIT (SIZEOF_LONG == 8)
+
+#define FIELD_BELONGS_TO_MESSAGE(field_descriptor, message) \
+ ((message)->GetDescriptor() == (field_descriptor)->containing_type())
+
+#define FIELD_IS_REPEATED(field_descriptor) \
+ ((field_descriptor)->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED)
+
+#define GOOGLE_CHECK_GET_INT32(arg, value, err) \
+ int32 value; \
+ if (!CheckAndGetInteger(arg, &value, kint32min_py, kint32max_py)) { \
+ return err; \
+ }
+
+#define GOOGLE_CHECK_GET_INT64(arg, value, err) \
+ int64 value; \
+ if (!CheckAndGetInteger(arg, &value, kint64min_py, kint64max_py)) { \
+ return err; \
+ }
+
+#define GOOGLE_CHECK_GET_UINT32(arg, value, err) \
+ uint32 value; \
+ if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint32max_py)) { \
+ return err; \
+ }
+
+#define GOOGLE_CHECK_GET_UINT64(arg, value, err) \
+ uint64 value; \
+ if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint64max_py)) { \
+ return err; \
+ }
+
+#define GOOGLE_CHECK_GET_FLOAT(arg, value, err) \
+ float value; \
+ if (!CheckAndGetFloat(arg, &value)) { \
+ return err; \
+ } \
+
+#define GOOGLE_CHECK_GET_DOUBLE(arg, value, err) \
+ double value; \
+ if (!CheckAndGetDouble(arg, &value)) { \
+ return err; \
+ }
+
+#define GOOGLE_CHECK_GET_BOOL(arg, value, err) \
+ bool value; \
+ if (!CheckAndGetBool(arg, &value)) { \
+ return err; \
+ }
+
+
+extern PyObject* kPythonZero;
+extern PyObject* kint32min_py;
+extern PyObject* kint32max_py;
+extern PyObject* kuint32max_py;
+extern PyObject* kint64min_py;
+extern PyObject* kint64max_py;
+extern PyObject* kuint64max_py;
+
+#define C(str) const_cast<char*>(str)
+
+void FormatTypeError(PyObject* arg, char* expected_types);
+template<class T>
+bool CheckAndGetInteger(
+ PyObject* arg, T* value, PyObject* min, PyObject* max);
+bool CheckAndGetDouble(PyObject* arg, double* value);
+bool CheckAndGetFloat(PyObject* arg, float* value);
+bool CheckAndGetBool(PyObject* arg, bool* value);
+bool CheckAndSetString(
+ PyObject* arg, google::protobuf::Message* message,
+ const google::protobuf::FieldDescriptor* descriptor,
+ const google::protobuf::Reflection* reflection,
+ bool append,
+ int index);
+PyObject* ToStringObject(
+ const google::protobuf::FieldDescriptor* descriptor, string value);
+
+extern PyObject* PickleError_class;
+
+} // namespace python
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__
diff --git a/python/google/protobuf/pyext/message_factory_cpp2_test.py b/python/google/protobuf/pyext/message_factory_cpp2_test.py
new file mode 100644
index 0000000..32ab4f8
--- /dev/null
+++ b/python/google/protobuf/pyext/message_factory_cpp2_test.py
@@ -0,0 +1,56 @@
+#! /usr/bin/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.
+
+"""Tests for google.protobuf.message_factory."""
+
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION'] = '2'
+
+# We must set the implementation version above before the google3 imports.
+# pylint: disable=g-import-not-at-top
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+# Run all tests from the original module by putting them in our namespace.
+# pylint: disable=wildcard-import
+from google.protobuf.internal.message_factory_test import *
+
+
+class ConfirmCppApi2Test(basetest.TestCase):
+
+ def testImplementationSetting(self):
+ self.assertEqual('cpp', api_implementation.Type())
+ self.assertEqual(2, api_implementation.Version())
+
+
+if __name__ == '__main__':
+ basetest.main()
diff --git a/python/google/protobuf/pyext/proto2_api_test.proto b/python/google/protobuf/pyext/proto2_api_test.proto
new file mode 100644
index 0000000..72c31b1
--- /dev/null
+++ b/python/google/protobuf/pyext/proto2_api_test.proto
@@ -0,0 +1,38 @@
+// 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 "google/protobuf/internal/cpp/proto1_api_test.proto";
+
+package google.protobuf.python.internal;
+
+message TestNestedProto1APIMessage {
+ optional int32 a = 1;
+ optional TestMessage.NestedMessage b = 2;
+}
diff --git a/python/google/protobuf/pyext/python.proto b/python/google/protobuf/pyext/python.proto
new file mode 100644
index 0000000..d47d402
--- /dev/null
+++ b/python/google/protobuf/pyext/python.proto
@@ -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.
+
+// Author: tibell@google.com (Johan Tibell)
+//
+// These message definitions are used to exercises known corner cases
+// in the C++ implementation of the Python API.
+
+
+package google.protobuf.python.internal;
+
+// 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;
+
+message TestAllTypes {
+ message NestedMessage {
+ optional int32 bb = 1;
+ optional ForeignMessage cc = 2;
+ }
+
+ repeated NestedMessage repeated_nested_message = 1;
+ optional NestedMessage optional_nested_message = 2;
+ optional int32 optional_int32 = 3;
+}
+
+message ForeignMessage {
+ optional int32 c = 1;
+ repeated int32 d = 2;
+}
+
+message TestAllExtensions {
+ extensions 1 to max;
+}
+
+extend TestAllExtensions {
+ optional TestAllTypes.NestedMessage optional_nested_message_extension = 1;
+}
diff --git a/python/google/protobuf/pyext/python_protobuf.h b/python/google/protobuf/pyext/python_protobuf.h
new file mode 100644
index 0000000..beb6e46
--- /dev/null
+++ b/python/google/protobuf/pyext/python_protobuf.h
@@ -0,0 +1,57 @@
+// 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: qrczak@google.com (Marcin Kowalczyk)
+//
+// This module exposes the C proto inside the given Python proto, in
+// case the Python proto is implemented with a C proto.
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
+#define GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
+
+#include <Python.h>
+
+namespace google {
+namespace protobuf {
+
+class Message;
+
+namespace python {
+
+// Return the pointer to the C proto inside the given Python proto,
+// or NULL when this is not a Python proto implemented with a C proto.
+const Message* GetCProtoInsidePyProto(PyObject* msg);
+Message* MutableCProtoInsidePyProto(PyObject* msg);
+
+} // namespace python
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
diff --git a/python/google/protobuf/pyext/reflection_cpp2_generated_test.py b/python/google/protobuf/pyext/reflection_cpp2_generated_test.py
new file mode 100755
index 0000000..552efd4
--- /dev/null
+++ b/python/google/protobuf/pyext/reflection_cpp2_generated_test.py
@@ -0,0 +1,94 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# 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.
+
+"""Unittest for reflection.py, which tests the generated C++ implementation."""
+
+__author__ = 'jasonh@google.com (Jason Hsueh)'
+
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION'] = '2'
+
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import more_extensions_dynamic_pb2
+from google.protobuf.internal import more_extensions_pb2
+from google.protobuf.internal.reflection_test import *
+
+
+class ReflectionCppTest(basetest.TestCase):
+ def testImplementationSetting(self):
+ self.assertEqual('cpp', api_implementation.Type())
+ self.assertEqual(2, api_implementation.Version())
+
+ def testExtensionOfGeneratedTypeInDynamicFile(self):
+ """Tests that a file built dynamically can extend a generated C++ type.
+
+ The C++ implementation uses a DescriptorPool that has the generated
+ DescriptorPool as an underlay. Typically, a type can only find
+ extensions in its own pool. With the python C-extension, the generated C++
+ extendee may be available, but not the extension. This tests that the
+ C-extension implements the correct special handling to make such extensions
+ available.
+ """
+ pb1 = more_extensions_pb2.ExtendedMessage()
+ # Test that basic accessors work.
+ self.assertFalse(
+ pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_int32_extension))
+ self.assertFalse(
+ pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_message_extension))
+ pb1.Extensions[more_extensions_dynamic_pb2.dynamic_int32_extension] = 17
+ pb1.Extensions[more_extensions_dynamic_pb2.dynamic_message_extension].a = 24
+ self.assertTrue(
+ pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_int32_extension))
+ self.assertTrue(
+ pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_message_extension))
+
+ # Now serialize the data and parse to a new message.
+ pb2 = more_extensions_pb2.ExtendedMessage()
+ pb2.MergeFromString(pb1.SerializeToString())
+
+ self.assertTrue(
+ pb2.HasExtension(more_extensions_dynamic_pb2.dynamic_int32_extension))
+ self.assertTrue(
+ pb2.HasExtension(more_extensions_dynamic_pb2.dynamic_message_extension))
+ self.assertEqual(
+ 17, pb2.Extensions[more_extensions_dynamic_pb2.dynamic_int32_extension])
+ self.assertEqual(
+ 24,
+ pb2.Extensions[more_extensions_dynamic_pb2.dynamic_message_extension].a)
+
+
+
+if __name__ == '__main__':
+ basetest.main()
diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc
new file mode 100644
index 0000000..5c05b3d
--- /dev/null
+++ b/python/google/protobuf/pyext/repeated_composite_container.cc
@@ -0,0 +1,763 @@
+// 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: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#include <google/protobuf/pyext/repeated_composite_container.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/pyext/descriptor.h>
+#include <google/protobuf/pyext/message.h>
+#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+
+#if PY_MAJOR_VERSION >= 3
+ #define PyInt_Check PyLong_Check
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_FromLong PyLong_FromLong
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+extern google::protobuf::DynamicMessageFactory* global_message_factory;
+
+namespace repeated_composite_container {
+
+// TODO(tibell): We might also want to check:
+// GOOGLE_CHECK_NOTNULL((self)->owner.get());
+#define GOOGLE_CHECK_ATTACHED(self) \
+ do { \
+ GOOGLE_CHECK_NOTNULL((self)->message); \
+ GOOGLE_CHECK_NOTNULL((self)->parent_field); \
+ } while (0);
+
+#define GOOGLE_CHECK_RELEASED(self) \
+ do { \
+ GOOGLE_CHECK((self)->owner.get() == NULL); \
+ GOOGLE_CHECK((self)->message == NULL); \
+ GOOGLE_CHECK((self)->parent_field == NULL); \
+ GOOGLE_CHECK((self)->parent == NULL); \
+ } while (0);
+
+// Returns a new reference.
+static PyObject* GetKey(PyObject* x) {
+ // Just the identity function.
+ Py_INCREF(x);
+ return x;
+}
+
+#define GET_KEY(keyfunc, value) \
+ ((keyfunc) == NULL ? \
+ GetKey((value)) : \
+ PyObject_CallFunctionObjArgs((keyfunc), (value), NULL))
+
+// Converts a comparison function that returns -1, 0, or 1 into a
+// less-than predicate.
+//
+// Returns -1 on error, 1 if x < y, 0 if x >= y.
+static int islt(PyObject *x, PyObject *y, PyObject *compare) {
+ if (compare == NULL)
+ return PyObject_RichCompareBool(x, y, Py_LT);
+
+ ScopedPyObjectPtr res(PyObject_CallFunctionObjArgs(compare, x, y, NULL));
+ if (res == NULL)
+ return -1;
+ if (!PyInt_Check(res)) {
+ PyErr_Format(PyExc_TypeError,
+ "comparison function must return int, not %.200s",
+ Py_TYPE(res)->tp_name);
+ return -1;
+ }
+ return PyInt_AsLong(res) < 0;
+}
+
+// Copied from uarrsort.c but swaps memcpy swaps with protobuf/python swaps
+// TODO(anuraag): Is there a better way to do this then reinventing the wheel?
+static int InternalQuickSort(RepeatedCompositeContainer* self,
+ Py_ssize_t start,
+ Py_ssize_t limit,
+ PyObject* cmp,
+ PyObject* keyfunc) {
+ if (limit - start <= 1)
+ return 0; // Nothing to sort.
+
+ GOOGLE_CHECK_ATTACHED(self);
+
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ const google::protobuf::FieldDescriptor* descriptor = self->parent_field->descriptor;
+ Py_ssize_t left;
+ Py_ssize_t right;
+
+ PyObject* children = self->child_messages;
+
+ do {
+ left = start;
+ right = limit;
+ ScopedPyObjectPtr mid(
+ GET_KEY(keyfunc, PyList_GET_ITEM(children, (start + limit) / 2)));
+ do {
+ ScopedPyObjectPtr key(GET_KEY(keyfunc, PyList_GET_ITEM(children, left)));
+ int is_lt = islt(key, mid, cmp);
+ if (is_lt == -1)
+ return -1;
+ /* array[left]<x */
+ while (is_lt) {
+ ++left;
+ ScopedPyObjectPtr key(GET_KEY(keyfunc,
+ PyList_GET_ITEM(children, left)));
+ is_lt = islt(key, mid, cmp);
+ if (is_lt == -1)
+ return -1;
+ }
+ key.reset(GET_KEY(keyfunc, PyList_GET_ITEM(children, right - 1)));
+ is_lt = islt(mid, key, cmp);
+ if (is_lt == -1)
+ return -1;
+ while (is_lt) {
+ --right;
+ ScopedPyObjectPtr key(GET_KEY(keyfunc,
+ PyList_GET_ITEM(children, right - 1)));
+ is_lt = islt(mid, key, cmp);
+ if (is_lt == -1)
+ return -1;
+ }
+ if (left < right) {
+ --right;
+ if (left < right) {
+ reflection->SwapElements(message, descriptor, left, right);
+ PyObject* tmp = PyList_GET_ITEM(children, left);
+ PyList_SET_ITEM(children, left, PyList_GET_ITEM(children, right));
+ PyList_SET_ITEM(children, right, tmp);
+ }
+ ++left;
+ }
+ } while (left < right);
+
+ if ((right - start) < (limit - left)) {
+ /* sort [start..right[ */
+ if (start < (right - 1)) {
+ InternalQuickSort(self, start, right, cmp, keyfunc);
+ }
+
+ /* sort [left..limit[ */
+ start = left;
+ } else {
+ /* sort [left..limit[ */
+ if (left < (limit - 1)) {
+ InternalQuickSort(self, left, limit, cmp, keyfunc);
+ }
+
+ /* sort [start..right[ */
+ limit = right;
+ }
+ } while (start < (limit - 1));
+
+ return 0;
+}
+
+#undef GET_KEY
+
+// ---------------------------------------------------------------------
+// len()
+
+static Py_ssize_t Length(RepeatedCompositeContainer* self) {
+ google::protobuf::Message* message = self->message;
+ if (message != NULL) {
+ return message->GetReflection()->FieldSize(*message,
+ self->parent_field->descriptor);
+ } else {
+ // The container has been released (i.e. by a call to Clear() or
+ // ClearField() on the parent) and thus there's no message.
+ return PyList_GET_SIZE(self->child_messages);
+ }
+}
+
+// Returns 0 if successful; returns -1 and sets an exception if
+// unsuccessful.
+static int UpdateChildMessages(RepeatedCompositeContainer* self) {
+ if (self->message == NULL)
+ return 0;
+
+ // A MergeFrom on a parent message could have caused extra messages to be
+ // added in the underlying protobuf so add them to our list. They can never
+ // be removed in such a way so there's no need to worry about that.
+ Py_ssize_t message_length = Length(self);
+ Py_ssize_t child_length = PyList_GET_SIZE(self->child_messages);
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ for (Py_ssize_t i = child_length; i < message_length; ++i) {
+ const Message& sub_message = reflection->GetRepeatedMessage(
+ *(self->message), self->parent_field->descriptor, i);
+ ScopedPyObjectPtr py_cmsg(cmessage::NewEmpty(self->subclass_init));
+ if (py_cmsg == NULL) {
+ return -1;
+ }
+ CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg.get());
+ cmsg->owner = self->owner;
+ cmsg->message = const_cast<google::protobuf::Message*>(&sub_message);
+ cmsg->parent = self->parent;
+ if (cmessage::InitAttributes(cmsg, NULL, NULL) < 0) {
+ return -1;
+ }
+ PyList_Append(self->child_messages, py_cmsg);
+ }
+ return 0;
+}
+
+// ---------------------------------------------------------------------
+// add()
+
+static PyObject* AddToAttached(RepeatedCompositeContainer* self,
+ PyObject* args,
+ PyObject* kwargs) {
+ GOOGLE_CHECK_ATTACHED(self);
+
+ if (UpdateChildMessages(self) < 0) {
+ return NULL;
+ }
+ if (cmessage::AssureWritable(self->parent) == -1)
+ return NULL;
+ google::protobuf::Message* message = self->message;
+ google::protobuf::Message* sub_message =
+ message->GetReflection()->AddMessage(message,
+ self->parent_field->descriptor);
+ PyObject* py_cmsg = cmessage::NewEmpty(self->subclass_init);
+ if (py_cmsg == NULL) {
+ return NULL;
+ }
+ CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
+
+ cmsg->owner = self->owner;
+ cmsg->message = sub_message;
+ cmsg->parent = self->parent;
+ // cmessage::InitAttributes must be called after cmsg->message has
+ // been set.
+ if (cmessage::InitAttributes(cmsg, NULL, kwargs) < 0) {
+ Py_DECREF(py_cmsg);
+ return NULL;
+ }
+ PyList_Append(self->child_messages, py_cmsg);
+ return py_cmsg;
+}
+
+static PyObject* AddToReleased(RepeatedCompositeContainer* self,
+ PyObject* args,
+ PyObject* kwargs) {
+ GOOGLE_CHECK_RELEASED(self);
+
+ // Create the CMessage
+ PyObject* py_cmsg = PyObject_CallObject(self->subclass_init, NULL);
+ if (py_cmsg == NULL)
+ return NULL;
+ CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
+ if (cmessage::InitAttributes(cmsg, NULL, kwargs) < 0) {
+ Py_DECREF(py_cmsg);
+ return NULL;
+ }
+
+ // The Message got created by the call to subclass_init above and
+ // it set self->owner to the newly allocated message.
+
+ PyList_Append(self->child_messages, py_cmsg);
+ return py_cmsg;
+}
+
+PyObject* Add(RepeatedCompositeContainer* self,
+ PyObject* args,
+ PyObject* kwargs) {
+ if (self->message == NULL)
+ return AddToReleased(self, args, kwargs);
+ else
+ return AddToAttached(self, args, kwargs);
+}
+
+// ---------------------------------------------------------------------
+// extend()
+
+PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value) {
+ cmessage::AssureWritable(self->parent);
+ if (UpdateChildMessages(self) < 0) {
+ return NULL;
+ }
+ ScopedPyObjectPtr iter(PyObject_GetIter(value));
+ if (iter == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Value must be iterable");
+ return NULL;
+ }
+ ScopedPyObjectPtr next;
+ while ((next.reset(PyIter_Next(iter))) != NULL) {
+ if (!PyObject_TypeCheck(next, &CMessage_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Not a cmessage");
+ return NULL;
+ }
+ ScopedPyObjectPtr new_message(Add(self, NULL, NULL));
+ if (new_message == NULL) {
+ return NULL;
+ }
+ CMessage* new_cmessage = reinterpret_cast<CMessage*>(new_message.get());
+ if (cmessage::MergeFrom(new_cmessage, next) == NULL) {
+ return NULL;
+ }
+ }
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyObject* MergeFrom(RepeatedCompositeContainer* self, PyObject* other) {
+ if (UpdateChildMessages(self) < 0) {
+ return NULL;
+ }
+ return Extend(self, other);
+}
+
+PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* slice) {
+ if (UpdateChildMessages(self) < 0) {
+ return NULL;
+ }
+ Py_ssize_t from;
+ Py_ssize_t to;
+ Py_ssize_t step;
+ Py_ssize_t length = Length(self);
+ Py_ssize_t slicelength;
+ if (PySlice_Check(slice)) {
+#if PY_MAJOR_VERSION >= 3
+ if (PySlice_GetIndicesEx(slice,
+#else
+ if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice),
+#endif
+ length, &from, &to, &step, &slicelength) == -1) {
+ return NULL;
+ }
+ return PyList_GetSlice(self->child_messages, from, to);
+ } else if (PyInt_Check(slice) || PyLong_Check(slice)) {
+ from = to = PyLong_AsLong(slice);
+ if (from < 0) {
+ from = to = length + from;
+ }
+ PyObject* result = PyList_GetItem(self->child_messages, from);
+ if (result == NULL) {
+ return NULL;
+ }
+ Py_INCREF(result);
+ return result;
+ }
+ PyErr_SetString(PyExc_TypeError, "index must be an integer or slice");
+ return NULL;
+}
+
+int AssignSubscript(RepeatedCompositeContainer* self,
+ PyObject* slice,
+ PyObject* value) {
+ if (UpdateChildMessages(self) < 0) {
+ return -1;
+ }
+ if (value != NULL) {
+ PyErr_SetString(PyExc_TypeError, "does not support assignment");
+ return -1;
+ }
+
+ // Delete from the underlying Message, if any.
+ if (self->message != NULL) {
+ if (cmessage::InternalDeleteRepeatedField(self->message,
+ self->parent_field->descriptor,
+ slice,
+ self->child_messages) < 0) {
+ return -1;
+ }
+ } else {
+ Py_ssize_t from;
+ Py_ssize_t to;
+ Py_ssize_t step;
+ Py_ssize_t length = Length(self);
+ Py_ssize_t slicelength;
+ if (PySlice_Check(slice)) {
+#if PY_MAJOR_VERSION >= 3
+ if (PySlice_GetIndicesEx(slice,
+#else
+ if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice),
+#endif
+ length, &from, &to, &step, &slicelength) == -1) {
+ return -1;
+ }
+ return PySequence_DelSlice(self->child_messages, from, to);
+ } else if (PyInt_Check(slice) || PyLong_Check(slice)) {
+ from = to = PyLong_AsLong(slice);
+ if (from < 0) {
+ from = to = length + from;
+ }
+ return PySequence_DelItem(self->child_messages, from);
+ }
+ }
+
+ return 0;
+}
+
+static PyObject* Remove(RepeatedCompositeContainer* self, PyObject* value) {
+ if (UpdateChildMessages(self) < 0) {
+ return NULL;
+ }
+ Py_ssize_t index = PySequence_Index(self->child_messages, value);
+ if (index == -1) {
+ return NULL;
+ }
+ ScopedPyObjectPtr py_index(PyLong_FromLong(index));
+ if (AssignSubscript(self, py_index, NULL) < 0) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject* RichCompare(RepeatedCompositeContainer* self,
+ PyObject* other,
+ int opid) {
+ if (UpdateChildMessages(self) < 0) {
+ return NULL;
+ }
+ if (!PyObject_TypeCheck(other, &RepeatedCompositeContainer_Type)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Can only compare repeated composite fields "
+ "against other repeated composite fields.");
+ return NULL;
+ }
+ if (opid == Py_EQ || opid == Py_NE) {
+ // TODO(anuraag): Don't make new lists just for this...
+ ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
+ if (full_slice == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr list(Subscript(self, full_slice));
+ if (list == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr other_list(
+ Subscript(
+ reinterpret_cast<RepeatedCompositeContainer*>(other), full_slice));
+ if (other_list == NULL) {
+ return NULL;
+ }
+ return PyObject_RichCompare(list, other_list, opid);
+ } else {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+}
+
+// ---------------------------------------------------------------------
+// sort()
+
+static PyObject* SortAttached(RepeatedCompositeContainer* self,
+ PyObject* args,
+ PyObject* kwds) {
+ // Sort the underlying Message array.
+ PyObject *compare = NULL;
+ int reverse = 0;
+ PyObject *keyfunc = NULL;
+ static char *kwlist[] = {"cmp", "key", "reverse", 0};
+
+ if (args != NULL) {
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi:sort",
+ kwlist, &compare, &keyfunc, &reverse))
+ return NULL;
+ }
+ if (compare == Py_None)
+ compare = NULL;
+ if (keyfunc == Py_None)
+ keyfunc = NULL;
+
+ const Py_ssize_t length = Length(self);
+ if (InternalQuickSort(self, 0, length, compare, keyfunc) < 0)
+ return NULL;
+
+ // Finally reverse the result if requested.
+ if (reverse) {
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ const google::protobuf::FieldDescriptor* descriptor = self->parent_field->descriptor;
+
+ // Reverse the Message array.
+ for (int i = 0; i < length / 2; ++i)
+ reflection->SwapElements(message, descriptor, i, length - i - 1);
+
+ // Reverse the Python list.
+ ScopedPyObjectPtr res(PyObject_CallMethod(self->child_messages,
+ "reverse", NULL));
+ if (res == NULL)
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject* SortReleased(RepeatedCompositeContainer* self,
+ PyObject* args,
+ PyObject* kwds) {
+ ScopedPyObjectPtr m(PyObject_GetAttrString(self->child_messages, "sort"));
+ if (m == NULL)
+ return NULL;
+ if (PyObject_Call(m, args, kwds) == NULL)
+ return NULL;
+ Py_RETURN_NONE;
+}
+
+static PyObject* Sort(RepeatedCompositeContainer* self,
+ PyObject* args,
+ PyObject* kwds) {
+ // Support the old sort_function argument for backwards
+ // compatibility.
+ if (kwds != NULL) {
+ PyObject* sort_func = PyDict_GetItemString(kwds, "sort_function");
+ if (sort_func != NULL) {
+ // Must set before deleting as sort_func is a borrowed reference
+ // and kwds might be the only thing keeping it alive.
+ PyDict_SetItemString(kwds, "cmp", sort_func);
+ PyDict_DelItemString(kwds, "sort_function");
+ }
+ }
+
+ if (UpdateChildMessages(self) < 0)
+ return NULL;
+ if (self->message == NULL) {
+ return SortReleased(self, args, kwds);
+ } else {
+ return SortAttached(self, args, kwds);
+ }
+}
+
+// ---------------------------------------------------------------------
+
+static PyObject* Item(RepeatedCompositeContainer* self, Py_ssize_t index) {
+ if (UpdateChildMessages(self) < 0) {
+ return NULL;
+ }
+ Py_ssize_t length = Length(self);
+ if (index < 0) {
+ index = length + index;
+ }
+ PyObject* item = PyList_GetItem(self->child_messages, index);
+ if (item == NULL) {
+ return NULL;
+ }
+ Py_INCREF(item);
+ return item;
+}
+
+// The caller takes ownership of the returned Message.
+Message* ReleaseLast(const FieldDescriptor* field,
+ const Descriptor* type,
+ Message* message) {
+ GOOGLE_CHECK_NOTNULL(field);
+ GOOGLE_CHECK_NOTNULL(type);
+ GOOGLE_CHECK_NOTNULL(message);
+
+ Message* released_message = message->GetReflection()->ReleaseLast(
+ message, field);
+ // TODO(tibell): Deal with proto1.
+
+ // ReleaseMessage will return NULL which differs from
+ // child_cmessage->message, if the field does not exist. In this case,
+ // the latter points to the default instance via a const_cast<>, so we
+ // have to reset it to a new mutable object since we are taking ownership.
+ if (released_message == NULL) {
+ const Message* prototype = global_message_factory->GetPrototype(type);
+ GOOGLE_CHECK_NOTNULL(prototype);
+ return prototype->New();
+ } else {
+ return released_message;
+ }
+}
+
+// Release field of message and transfer the ownership to cmessage.
+void ReleaseLastTo(const FieldDescriptor* field,
+ Message* message,
+ CMessage* cmessage) {
+ GOOGLE_CHECK_NOTNULL(field);
+ GOOGLE_CHECK_NOTNULL(message);
+ GOOGLE_CHECK_NOTNULL(cmessage);
+
+ shared_ptr<Message> released_message(
+ ReleaseLast(field, cmessage->message->GetDescriptor(), message));
+ cmessage->parent = NULL;
+ cmessage->parent_field = NULL;
+ cmessage->message = released_message.get();
+ cmessage->read_only = false;
+ cmessage::SetOwner(cmessage, released_message);
+}
+
+// Called to release a container using
+// ClearField('container_field_name') on the parent.
+int Release(RepeatedCompositeContainer* self) {
+ if (UpdateChildMessages(self) < 0) {
+ PyErr_WriteUnraisable(PyBytes_FromString("Failed to update released "
+ "messages"));
+ return -1;
+ }
+
+ Message* message = self->message;
+ const FieldDescriptor* field = self->parent_field->descriptor;
+
+ // The reflection API only lets us release the last message in a
+ // repeated field. Therefore we iterate through the children
+ // starting with the last one.
+ const Py_ssize_t size = PyList_GET_SIZE(self->child_messages);
+ GOOGLE_DCHECK_EQ(size, message->GetReflection()->FieldSize(*message, field));
+ for (Py_ssize_t i = size - 1; i >= 0; --i) {
+ CMessage* child_cmessage = reinterpret_cast<CMessage*>(
+ PyList_GET_ITEM(self->child_messages, i));
+ ReleaseLastTo(field, message, child_cmessage);
+ }
+
+ // Detach from containing message.
+ self->parent = NULL;
+ self->parent_field = NULL;
+ self->message = NULL;
+ self->owner.reset();
+
+ return 0;
+}
+
+int SetOwner(RepeatedCompositeContainer* self,
+ const shared_ptr<Message>& new_owner) {
+ GOOGLE_CHECK_ATTACHED(self);
+
+ self->owner = new_owner;
+ const Py_ssize_t n = PyList_GET_SIZE(self->child_messages);
+ for (Py_ssize_t i = 0; i < n; ++i) {
+ PyObject* msg = PyList_GET_ITEM(self->child_messages, i);
+ if (cmessage::SetOwner(reinterpret_cast<CMessage*>(msg), new_owner) == -1) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int Init(RepeatedCompositeContainer* self,
+ PyObject* args,
+ PyObject* kwargs) {
+ self->message = NULL;
+ self->parent = NULL;
+ self->parent_field = NULL;
+ self->subclass_init = NULL;
+ self->child_messages = PyList_New(0);
+ return 0;
+}
+
+static void Dealloc(RepeatedCompositeContainer* self) {
+ Py_CLEAR(self->child_messages);
+ // TODO(tibell): Do we need to call delete on these objects to make
+ // sure their destructors are called?
+ self->owner.reset();
+ Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+static PySequenceMethods SqMethods = {
+ (lenfunc)Length, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ (ssizeargfunc)Item /* sq_item */
+};
+
+static PyMappingMethods MpMethods = {
+ (lenfunc)Length, /* mp_length */
+ (binaryfunc)Subscript, /* mp_subscript */
+ (objobjargproc)AssignSubscript,/* mp_ass_subscript */
+};
+
+static PyMethodDef Methods[] = {
+ { "add", (PyCFunction) Add, METH_VARARGS | METH_KEYWORDS,
+ "Adds an object to the repeated container." },
+ { "extend", (PyCFunction) Extend, METH_O,
+ "Adds objects to the repeated container." },
+ { "remove", (PyCFunction) Remove, METH_O,
+ "Removes an object from the repeated container." },
+ { "sort", (PyCFunction) Sort, METH_VARARGS | METH_KEYWORDS,
+ "Sorts the repeated container." },
+ { "MergeFrom", (PyCFunction) MergeFrom, METH_O,
+ "Adds objects to the repeated container." },
+ { NULL, NULL }
+};
+
+} // namespace repeated_composite_container
+
+PyTypeObject RepeatedCompositeContainer_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "google.protobuf.internal."
+ "cpp._message.RepeatedCompositeContainer", // tp_name
+ sizeof(RepeatedCompositeContainer), // tp_basicsize
+ 0, // tp_itemsize
+ (destructor)repeated_composite_container::Dealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ &repeated_composite_container::SqMethods, // tp_as_sequence
+ &repeated_composite_container::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 Repeated scalar container", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ (richcmpfunc)repeated_composite_container::RichCompare, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ repeated_composite_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
+ (initproc)repeated_composite_container::Init, // tp_init
+};
+
+} // namespace python
+} // namespace protobuf
+} // namespace google
diff --git a/python/google/protobuf/pyext/repeated_composite_container.h b/python/google/protobuf/pyext/repeated_composite_container.h
new file mode 100644
index 0000000..898ef5a
--- /dev/null
+++ b/python/google/protobuf/pyext/repeated_composite_container.h
@@ -0,0 +1,172 @@
+// 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: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__
+
+#include <Python.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+#include <string>
+#include <vector>
+
+
+namespace google {
+namespace protobuf {
+
+class FieldDescriptor;
+class Message;
+
+using internal::shared_ptr;
+
+namespace python {
+
+struct CMessage;
+struct CFieldDescriptor;
+
+// A RepeatedCompositeContainer can be in one of two states: attached
+// or released.
+//
+// When in the attached state all modifications to the container are
+// done both on the 'message' and on the 'child_messages'
+// list. In this state all Messages refered to by the children in
+// 'child_messages' are owner by the 'owner'.
+//
+// When in the released state 'message', 'owner', 'parent', and
+// 'parent_field' are NULL.
+typedef struct RepeatedCompositeContainer {
+ PyObject_HEAD;
+
+ // This is the top-level C++ Message object that owns the whole
+ // proto tree. Every Python RepeatedCompositeContainer 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;
+
+ // Weak reference to parent object. May be NULL. Used to make sure
+ // the parent is writable before modifying the
+ // RepeatedCompositeContainer.
+ CMessage* parent;
+
+ // A descriptor used to modify the underlying 'message'.
+ CFieldDescriptor* parent_field;
+
+ // Pointer to the C++ Message that contains this container. The
+ // RepeatedCompositeContainer does not own this pointer.
+ //
+ // If NULL, this message has been released from its parent (by
+ // calling Clear() or ClearField() on the parent.
+ Message* message;
+
+ // A callable that is used to create new child messages.
+ PyObject* subclass_init;
+
+ // A list of child messages.
+ PyObject* child_messages;
+} RepeatedCompositeContainer;
+
+extern PyTypeObject RepeatedCompositeContainer_Type;
+
+namespace repeated_composite_container {
+
+// Returns the number of items in this repeated composite container.
+static Py_ssize_t Length(RepeatedCompositeContainer* self);
+
+// Appends a new CMessage to the container and returns it. The
+// CMessage is initialized using the content of kwargs.
+//
+// Returns a new reference if successful; returns NULL and sets an
+// exception if unsuccessful.
+PyObject* Add(RepeatedCompositeContainer* self,
+ PyObject* args,
+ PyObject* kwargs);
+
+// Appends all the CMessages in the input iterator to the container.
+//
+// Returns None if successful; returns NULL and sets an exception if
+// unsuccessful.
+PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value);
+
+// Appends a new message to the container for each message in the
+// input iterator, merging each data element in. Equivalent to extend.
+//
+// Returns None if successful; returns NULL and sets an exception if
+// unsuccessful.
+PyObject* MergeFrom(RepeatedCompositeContainer* self, PyObject* other);
+
+// Accesses messages in the container.
+//
+// Returns a new reference to the message for an integer parameter.
+// Returns a new reference to a list of messages for a slice.
+PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* slice);
+
+// Deletes items from the container (cannot be used for assignment).
+//
+// Returns 0 on success, -1 on failure.
+int AssignSubscript(RepeatedCompositeContainer* self,
+ PyObject* slice,
+ PyObject* value);
+
+// Releases the messages in the container to the given message.
+//
+// Returns 0 on success, -1 on failure.
+int ReleaseToMessage(RepeatedCompositeContainer* self,
+ google::protobuf::Message* new_message);
+
+// Releases the messages in the container to a new message.
+//
+// Returns 0 on success, -1 on failure.
+int Release(RepeatedCompositeContainer* self);
+
+// Returns 0 on success, -1 on failure.
+int SetOwner(RepeatedCompositeContainer* self,
+ const shared_ptr<Message>& new_owner);
+
+// Removes the last element of the repeated message field 'field' on
+// the Message 'message', and transfers the ownership of the released
+// Message to 'cmessage'.
+//
+// Corresponds to reflection api method ReleaseMessage.
+void ReleaseLastTo(const FieldDescriptor* field,
+ Message* message,
+ CMessage* cmessage);
+
+} // namespace repeated_composite_container
+} // namespace python
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__
diff --git a/python/google/protobuf/pyext/repeated_scalar_container.cc b/python/google/protobuf/pyext/repeated_scalar_container.cc
new file mode 100644
index 0000000..e627d37
--- /dev/null
+++ b/python/google/protobuf/pyext/repeated_scalar_container.cc
@@ -0,0 +1,825 @@
+// 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: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#include <google/protobuf/pyext/repeated_scalar_container.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/pyext/descriptor.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
+ #if PY_VERSION_HEX < 0x03030000
+ #error "Python 3.0 - 3.2 are not supported."
+ #else
+ #define PyString_AsString(ob) \
+ (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AS_STRING(ob))
+ #endif
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+extern google::protobuf::DynamicMessageFactory* global_message_factory;
+
+namespace repeated_scalar_container {
+
+static int InternalAssignRepeatedField(
+ RepeatedScalarContainer* self, PyObject* list) {
+ self->message->GetReflection()->ClearField(self->message,
+ self->parent_field->descriptor);
+ for (Py_ssize_t i = 0; i < PyList_GET_SIZE(list); ++i) {
+ PyObject* value = PyList_GET_ITEM(list, i);
+ if (Append(self, value) == NULL) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static Py_ssize_t Len(RepeatedScalarContainer* self) {
+ google::protobuf::Message* message = self->message;
+ return message->GetReflection()->FieldSize(*message,
+ self->parent_field->descriptor);
+}
+
+static int AssignItem(RepeatedScalarContainer* self,
+ Py_ssize_t index,
+ PyObject* arg) {
+ cmessage::AssureWritable(self->parent);
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ self->parent_field->descriptor;
+ if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+ PyErr_SetString(
+ PyExc_KeyError, "Field does not belong to message!");
+ return -1;
+ }
+
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ int field_size = reflection->FieldSize(*message, field_descriptor);
+ if (index < 0) {
+ index = field_size + index;
+ }
+ if (index < 0 || index >= field_size) {
+ PyErr_Format(PyExc_IndexError,
+ "list assignment index (%d) out of range",
+ static_cast<int>(index));
+ return -1;
+ }
+
+ if (arg == NULL) {
+ ScopedPyObjectPtr py_index(PyLong_FromLong(index));
+ return cmessage::InternalDeleteRepeatedField(message, field_descriptor,
+ py_index, NULL);
+ }
+
+ if (PySequence_Check(arg) && !(PyBytes_Check(arg) || PyUnicode_Check(arg))) {
+ PyErr_SetString(PyExc_TypeError, "Value must be scalar");
+ return -1;
+ }
+
+ switch (field_descriptor->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+ GOOGLE_CHECK_GET_INT32(arg, value, -1);
+ reflection->SetRepeatedInt32(message, field_descriptor, index, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+ GOOGLE_CHECK_GET_INT64(arg, value, -1);
+ reflection->SetRepeatedInt64(message, field_descriptor, index, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+ GOOGLE_CHECK_GET_UINT32(arg, value, -1);
+ reflection->SetRepeatedUInt32(message, field_descriptor, index, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+ GOOGLE_CHECK_GET_UINT64(arg, value, -1);
+ reflection->SetRepeatedUInt64(message, field_descriptor, index, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+ GOOGLE_CHECK_GET_FLOAT(arg, value, -1);
+ reflection->SetRepeatedFloat(message, field_descriptor, index, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+ GOOGLE_CHECK_GET_DOUBLE(arg, value, -1);
+ reflection->SetRepeatedDouble(message, field_descriptor, index, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+ GOOGLE_CHECK_GET_BOOL(arg, value, -1);
+ reflection->SetRepeatedBool(message, field_descriptor, index, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+ if (!CheckAndSetString(
+ arg, message, field_descriptor, reflection, false, index)) {
+ return -1;
+ }
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+ GOOGLE_CHECK_GET_INT32(arg, value, -1);
+ const google::protobuf::EnumDescriptor* enum_descriptor =
+ field_descriptor->enum_type();
+ const google::protobuf::EnumValueDescriptor* enum_value =
+ enum_descriptor->FindValueByNumber(value);
+ if (enum_value != NULL) {
+ reflection->SetRepeatedEnum(message, field_descriptor, index,
+ enum_value);
+ } else {
+ ScopedPyObjectPtr s(PyObject_Str(arg));
+ if (s != NULL) {
+ PyErr_Format(PyExc_ValueError, "Unknown enum value: %s",
+ PyString_AsString(s.get()));
+ }
+ return -1;
+ }
+ break;
+ }
+ default:
+ PyErr_Format(
+ PyExc_SystemError, "Adding value to a field of unknown type %d",
+ field_descriptor->cpp_type());
+ return -1;
+ }
+ return 0;
+}
+
+static PyObject* Item(RepeatedScalarContainer* self, Py_ssize_t index) {
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ self->parent_field->descriptor;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+
+ int field_size = reflection->FieldSize(*message, field_descriptor);
+ if (index < 0) {
+ index = field_size + index;
+ }
+ if (index < 0 || index >= field_size) {
+ PyErr_Format(PyExc_IndexError,
+ "list assignment index (%d) out of range",
+ static_cast<int>(index));
+ return NULL;
+ }
+
+ PyObject* result = NULL;
+ switch (field_descriptor->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+ int32 value = reflection->GetRepeatedInt32(
+ *message, field_descriptor, index);
+ result = PyInt_FromLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+ int64 value = reflection->GetRepeatedInt64(
+ *message, field_descriptor, index);
+ result = PyLong_FromLongLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+ uint32 value = reflection->GetRepeatedUInt32(
+ *message, field_descriptor, index);
+ result = PyLong_FromLongLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+ uint64 value = reflection->GetRepeatedUInt64(
+ *message, field_descriptor, index);
+ result = PyLong_FromUnsignedLongLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+ float value = reflection->GetRepeatedFloat(
+ *message, field_descriptor, index);
+ result = PyFloat_FromDouble(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value = reflection->GetRepeatedDouble(
+ *message, field_descriptor, index);
+ result = PyFloat_FromDouble(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+ bool value = reflection->GetRepeatedBool(
+ *message, field_descriptor, index);
+ result = PyBool_FromLong(value ? 1 : 0);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+ const google::protobuf::EnumValueDescriptor* enum_value =
+ message->GetReflection()->GetRepeatedEnum(
+ *message, field_descriptor, index);
+ result = PyInt_FromLong(enum_value->number());
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+ string value = reflection->GetRepeatedString(
+ *message, field_descriptor, index);
+ result = ToStringObject(field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
+ PyObject* py_cmsg = PyObject_CallObject(reinterpret_cast<PyObject*>(
+ &CMessage_Type), NULL);
+ if (py_cmsg == NULL) {
+ return NULL;
+ }
+ CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
+ const google::protobuf::Message& msg = reflection->GetRepeatedMessage(
+ *message, field_descriptor, index);
+ cmsg->owner = self->owner;
+ cmsg->parent = self->parent;
+ cmsg->message = const_cast<google::protobuf::Message*>(&msg);
+ cmsg->read_only = false;
+ result = reinterpret_cast<PyObject*>(py_cmsg);
+ break;
+ }
+ default:
+ PyErr_Format(
+ PyExc_SystemError,
+ "Getting value from a repeated field of unknown type %d",
+ field_descriptor->cpp_type());
+ }
+
+ return result;
+}
+
+static PyObject* Subscript(RepeatedScalarContainer* self, PyObject* slice) {
+ Py_ssize_t from;
+ Py_ssize_t to;
+ Py_ssize_t step;
+ Py_ssize_t length;
+ Py_ssize_t slicelength;
+ bool return_list = false;
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(slice)) {
+ from = to = PyInt_AsLong(slice);
+ } else // NOLINT
+#endif
+ if (PyLong_Check(slice)) {
+ from = to = PyLong_AsLong(slice);
+ } else if (PySlice_Check(slice)) {
+ length = Len(self);
+#if PY_MAJOR_VERSION >= 3
+ if (PySlice_GetIndicesEx(slice,
+#else
+ if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice),
+#endif
+ length, &from, &to, &step, &slicelength) == -1) {
+ return NULL;
+ }
+ return_list = true;
+ } else {
+ PyErr_SetString(PyExc_TypeError, "list indices must be integers");
+ return NULL;
+ }
+
+ if (!return_list) {
+ return Item(self, from);
+ }
+
+ PyObject* list = PyList_New(0);
+ if (list == NULL) {
+ return NULL;
+ }
+ if (from <= to) {
+ if (step < 0) {
+ return list;
+ }
+ for (Py_ssize_t index = from; index < to; index += step) {
+ if (index < 0 || index >= length) {
+ break;
+ }
+ ScopedPyObjectPtr s(Item(self, index));
+ PyList_Append(list, s);
+ }
+ } else {
+ if (step > 0) {
+ return list;
+ }
+ for (Py_ssize_t index = from; index > to; index += step) {
+ if (index < 0 || index >= length) {
+ break;
+ }
+ ScopedPyObjectPtr s(Item(self, index));
+ PyList_Append(list, s);
+ }
+ }
+ return list;
+}
+
+PyObject* Append(RepeatedScalarContainer* self, PyObject* item) {
+ cmessage::AssureWritable(self->parent);
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ self->parent_field->descriptor;
+
+ if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+ PyErr_SetString(
+ PyExc_KeyError, "Field does not belong to message!");
+ return NULL;
+ }
+
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ switch (field_descriptor->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+ GOOGLE_CHECK_GET_INT32(item, value, NULL);
+ reflection->AddInt32(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+ GOOGLE_CHECK_GET_INT64(item, value, NULL);
+ reflection->AddInt64(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+ GOOGLE_CHECK_GET_UINT32(item, value, NULL);
+ reflection->AddUInt32(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+ GOOGLE_CHECK_GET_UINT64(item, value, NULL);
+ reflection->AddUInt64(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+ GOOGLE_CHECK_GET_FLOAT(item, value, NULL);
+ reflection->AddFloat(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+ GOOGLE_CHECK_GET_DOUBLE(item, value, NULL);
+ reflection->AddDouble(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+ GOOGLE_CHECK_GET_BOOL(item, value, NULL);
+ reflection->AddBool(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+ if (!CheckAndSetString(
+ item, message, field_descriptor, reflection, true, -1)) {
+ return NULL;
+ }
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+ GOOGLE_CHECK_GET_INT32(item, value, NULL);
+ const google::protobuf::EnumDescriptor* enum_descriptor =
+ field_descriptor->enum_type();
+ const google::protobuf::EnumValueDescriptor* enum_value =
+ enum_descriptor->FindValueByNumber(value);
+ if (enum_value != NULL) {
+ reflection->AddEnum(message, field_descriptor, enum_value);
+ } else {
+ ScopedPyObjectPtr s(PyObject_Str(item));
+ if (s != NULL) {
+ PyErr_Format(PyExc_ValueError, "Unknown enum value: %s",
+ PyString_AsString(s.get()));
+ }
+ return NULL;
+ }
+ break;
+ }
+ default:
+ PyErr_Format(
+ PyExc_SystemError, "Adding value to a field of unknown type %d",
+ field_descriptor->cpp_type());
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+static int AssSubscript(RepeatedScalarContainer* self,
+ PyObject* slice,
+ PyObject* value) {
+ Py_ssize_t from;
+ Py_ssize_t to;
+ Py_ssize_t step;
+ Py_ssize_t length;
+ Py_ssize_t slicelength;
+ bool create_list = false;
+
+ cmessage::AssureWritable(self->parent);
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ self->parent_field->descriptor;
+
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(slice)) {
+ from = to = PyInt_AsLong(slice);
+ } else
+#endif
+ if (PyLong_Check(slice)) {
+ from = to = PyLong_AsLong(slice);
+ } else if (PySlice_Check(slice)) {
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ length = reflection->FieldSize(*message, field_descriptor);
+#if PY_MAJOR_VERSION >= 3
+ if (PySlice_GetIndicesEx(slice,
+#else
+ if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice),
+#endif
+ length, &from, &to, &step, &slicelength) == -1) {
+ return -1;
+ }
+ create_list = true;
+ } else {
+ PyErr_SetString(PyExc_TypeError, "list indices must be integers");
+ return -1;
+ }
+
+ if (value == NULL) {
+ return cmessage::InternalDeleteRepeatedField(
+ message, field_descriptor, slice, NULL);
+ }
+
+ if (!create_list) {
+ return AssignItem(self, from, value);
+ }
+
+ ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
+ if (full_slice == NULL) {
+ return -1;
+ }
+ ScopedPyObjectPtr new_list(Subscript(self, full_slice));
+ if (new_list == NULL) {
+ return -1;
+ }
+ if (PySequence_SetSlice(new_list, from, to, value) < 0) {
+ return -1;
+ }
+
+ return InternalAssignRepeatedField(self, new_list);
+}
+
+PyObject* Extend(RepeatedScalarContainer* self, PyObject* value) {
+ cmessage::AssureWritable(self->parent);
+ if (PyObject_Not(value)) {
+ Py_RETURN_NONE;
+ }
+ ScopedPyObjectPtr iter(PyObject_GetIter(value));
+ if (iter == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Value must be iterable");
+ return NULL;
+ }
+ ScopedPyObjectPtr next;
+ while ((next.reset(PyIter_Next(iter))) != NULL) {
+ if (Append(self, next) == NULL) {
+ return NULL;
+ }
+ }
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject* Insert(RepeatedScalarContainer* self, PyObject* args) {
+ Py_ssize_t index;
+ PyObject* value;
+ if (!PyArg_ParseTuple(args, "lO", &index, &value)) {
+ return NULL;
+ }
+ ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
+ ScopedPyObjectPtr new_list(Subscript(self, full_slice));
+ if (PyList_Insert(new_list, index, value) < 0) {
+ return NULL;
+ }
+ int ret = InternalAssignRepeatedField(self, new_list);
+ if (ret < 0) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject* Remove(RepeatedScalarContainer* self, PyObject* value) {
+ Py_ssize_t match_index = -1;
+ for (Py_ssize_t i = 0; i < Len(self); ++i) {
+ ScopedPyObjectPtr elem(Item(self, i));
+ if (PyObject_RichCompareBool(elem, value, Py_EQ)) {
+ match_index = i;
+ break;
+ }
+ }
+ if (match_index == -1) {
+ PyErr_SetString(PyExc_ValueError, "remove(x): x not in container");
+ return NULL;
+ }
+ if (AssignItem(self, match_index, NULL) < 0) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject* RichCompare(RepeatedScalarContainer* self,
+ PyObject* other,
+ int opid) {
+ if (opid != Py_EQ && opid != Py_NE) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ // Copy the contents of this repeated scalar container, and other if it is
+ // also a repeated scalar container, into Python lists so we can delegate
+ // to the list's compare method.
+
+ ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
+ if (full_slice == NULL) {
+ return NULL;
+ }
+
+ ScopedPyObjectPtr other_list_deleter;
+ if (PyObject_TypeCheck(other, &RepeatedScalarContainer_Type)) {
+ other_list_deleter.reset(Subscript(
+ reinterpret_cast<RepeatedScalarContainer*>(other), full_slice));
+ other = other_list_deleter.get();
+ }
+
+ ScopedPyObjectPtr list(Subscript(self, full_slice));
+ if (list == NULL) {
+ return NULL;
+ }
+ return PyObject_RichCompare(list, other, opid);
+}
+
+PyObject* Reduce(RepeatedScalarContainer* unused_self) {
+ PyErr_Format(
+ PickleError_class,
+ "can't pickle repeated message fields, convert to list first");
+ return NULL;
+}
+
+static PyObject* Sort(RepeatedScalarContainer* self,
+ PyObject* args,
+ PyObject* kwds) {
+ // Support the old sort_function argument for backwards
+ // compatibility.
+ if (kwds != NULL) {
+ PyObject* sort_func = PyDict_GetItemString(kwds, "sort_function");
+ if (sort_func != NULL) {
+ // Must set before deleting as sort_func is a borrowed reference
+ // and kwds might be the only thing keeping it alive.
+ if (PyDict_SetItemString(kwds, "cmp", sort_func) == -1)
+ return NULL;
+ if (PyDict_DelItemString(kwds, "sort_function") == -1)
+ return NULL;
+ }
+ }
+
+ ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
+ if (full_slice == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr list(Subscript(self, full_slice));
+ if (list == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr m(PyObject_GetAttrString(list, "sort"));
+ if (m == NULL) {
+ return NULL;
+ }
+ ScopedPyObjectPtr res(PyObject_Call(m, args, kwds));
+ if (res == NULL) {
+ return NULL;
+ }
+ int ret = InternalAssignRepeatedField(self, list);
+ if (ret < 0) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static int Init(RepeatedScalarContainer* self,
+ PyObject* args,
+ PyObject* kwargs) {
+ PyObject* py_parent;
+ PyObject* py_parent_field;
+ if (!PyArg_UnpackTuple(args, "__init__()", 2, 2, &py_parent,
+ &py_parent_field)) {
+ return -1;
+ }
+
+ if (!PyObject_TypeCheck(py_parent, &CMessage_Type)) {
+ PyErr_Format(PyExc_TypeError,
+ "expect %s, but got %s",
+ CMessage_Type.tp_name,
+ Py_TYPE(py_parent)->tp_name);
+ return -1;
+ }
+
+ if (!PyObject_TypeCheck(py_parent_field, &CFieldDescriptor_Type)) {
+ PyErr_Format(PyExc_TypeError,
+ "expect %s, but got %s",
+ CFieldDescriptor_Type.tp_name,
+ Py_TYPE(py_parent_field)->tp_name);
+ return -1;
+ }
+
+ CMessage* cmessage = reinterpret_cast<CMessage*>(py_parent);
+ CFieldDescriptor* cdescriptor = reinterpret_cast<CFieldDescriptor*>(
+ py_parent_field);
+
+ if (!FIELD_BELONGS_TO_MESSAGE(cdescriptor->descriptor, cmessage->message)) {
+ PyErr_SetString(
+ PyExc_KeyError, "Field does not belong to message!");
+ return -1;
+ }
+
+ self->message = cmessage->message;
+ self->parent = cmessage;
+ self->parent_field = cdescriptor;
+ self->owner = cmessage->owner;
+ return 0;
+}
+
+// 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(
+ RepeatedScalarContainer* from,
+ RepeatedScalarContainer* to) {
+ ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
+ if (full_slice == NULL) {
+ return -1;
+ }
+ ScopedPyObjectPtr values(Subscript(from, full_slice));
+ if (values == NULL) {
+ return -1;
+ }
+ google::protobuf::Message* new_message = global_message_factory->GetPrototype(
+ from->message->GetDescriptor())->New();
+ to->parent = NULL;
+ // TODO(anuraag): Document why it's OK to hang on to parent_field,
+ // even though it's a weak reference. It ought to be enough to
+ // hold on to the FieldDescriptor only.
+ to->parent_field = from->parent_field;
+ to->message = new_message;
+ to->owner.reset(new_message);
+ if (InternalAssignRepeatedField(to, values) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+int Release(RepeatedScalarContainer* self) {
+ return InitializeAndCopyToParentContainer(self, self);
+}
+
+PyObject* DeepCopy(RepeatedScalarContainer* self, PyObject* arg) {
+ ScopedPyObjectPtr init_args(
+ PyTuple_Pack(2, self->parent, self->parent_field));
+ PyObject* clone = PyObject_CallObject(
+ reinterpret_cast<PyObject*>(&RepeatedScalarContainer_Type), init_args);
+ if (clone == NULL) {
+ return NULL;
+ }
+ if (!PyObject_TypeCheck(clone, &RepeatedScalarContainer_Type)) {
+ Py_DECREF(clone);
+ return NULL;
+ }
+ if (InitializeAndCopyToParentContainer(
+ self, reinterpret_cast<RepeatedScalarContainer*>(clone)) < 0) {
+ Py_DECREF(clone);
+ return NULL;
+ }
+ return clone;
+}
+
+static void Dealloc(RepeatedScalarContainer* self) {
+ self->owner.reset();
+ Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+void SetOwner(RepeatedScalarContainer* self,
+ const shared_ptr<Message>& new_owner) {
+ self->owner = new_owner;
+}
+
+static PySequenceMethods SqMethods = {
+ (lenfunc)Len, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ (ssizeargfunc)Item, /* sq_item */
+ 0, /* sq_slice */
+ (ssizeobjargproc)AssignItem /* sq_ass_item */
+};
+
+static PyMappingMethods MpMethods = {
+ (lenfunc)Len, /* mp_length */
+ (binaryfunc)Subscript, /* mp_subscript */
+ (objobjargproc)AssSubscript, /* mp_ass_subscript */
+};
+
+static PyMethodDef Methods[] = {
+ { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
+ "Makes a deep copy of the class." },
+ { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
+ "Outputs picklable representation of the repeated field." },
+ { "append", (PyCFunction)Append, METH_O,
+ "Appends an object to the repeated container." },
+ { "extend", (PyCFunction)Extend, METH_O,
+ "Appends objects to the repeated container." },
+ { "insert", (PyCFunction)Insert, METH_VARARGS,
+ "Appends objects to the repeated container." },
+ { "remove", (PyCFunction)Remove, METH_O,
+ "Removes an object from the repeated container." },
+ { "sort", (PyCFunction)Sort, METH_VARARGS | METH_KEYWORDS,
+ "Sorts the repeated container."},
+ { NULL, NULL }
+};
+
+} // namespace repeated_scalar_container
+
+PyTypeObject RepeatedScalarContainer_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "google.protobuf.internal."
+ "cpp._message.RepeatedScalarContainer", // tp_name
+ sizeof(RepeatedScalarContainer), // tp_basicsize
+ 0, // tp_itemsize
+ (destructor)repeated_scalar_container::Dealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ &repeated_scalar_container::SqMethods, // tp_as_sequence
+ &repeated_scalar_container::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 Repeated scalar container", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ (richcmpfunc)repeated_scalar_container::RichCompare, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ repeated_scalar_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
+ (initproc)repeated_scalar_container::Init, // tp_init
+};
+
+} // namespace python
+} // namespace protobuf
+} // namespace google
diff --git a/python/google/protobuf/pyext/repeated_scalar_container.h b/python/google/protobuf/pyext/repeated_scalar_container.h
new file mode 100644
index 0000000..69d15d5
--- /dev/null
+++ b/python/google/protobuf/pyext/repeated_scalar_container.h
@@ -0,0 +1,112 @@
+// 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: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_SCALAR_CONTAINER_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_SCALAR_CONTAINER_H__
+
+#include <Python.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+
+
+namespace google {
+namespace protobuf {
+
+class Message;
+
+using internal::shared_ptr;
+
+namespace python {
+
+struct CFieldDescriptor;
+struct CMessage;
+
+typedef struct RepeatedScalarContainer {
+ PyObject_HEAD;
+
+ // This is the top-level C++ Message object that owns the whole
+ // proto tree. Every Python RepeatedScalarContainer 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
+ // RepeatedScalarContainer 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;
+
+ // Weak reference to the parent's descriptor that describes this
+ // field. Used together with the parent's message when making a
+ // default message instance mutable.
+ CFieldDescriptor* parent_field;
+} RepeatedScalarContainer;
+
+extern PyTypeObject RepeatedScalarContainer_Type;
+
+namespace repeated_scalar_container {
+
+// Appends the scalar 'item' to the end of the container 'self'.
+//
+// Returns None if successful; returns NULL and sets an exception if
+// unsuccessful.
+PyObject* Append(RepeatedScalarContainer* self, PyObject* item);
+
+// Releases the messages in the container to a new message.
+//
+// Returns 0 on success, -1 on failure.
+int Release(RepeatedScalarContainer* self);
+
+// Appends all the elements in the input iterator to the container.
+//
+// Returns None if successful; returns NULL and sets an exception if
+// unsuccessful.
+PyObject* Extend(RepeatedScalarContainer* self, PyObject* value);
+
+// Set the owner field of self and any children of self.
+void SetOwner(RepeatedScalarContainer* self,
+ const shared_ptr<Message>& new_owner);
+
+} // namespace repeated_scalar_container
+} // namespace python
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_SCALAR_CONTAINER_H__
diff --git a/python/google/protobuf/pyext/scoped_pyobject_ptr.h b/python/google/protobuf/pyext/scoped_pyobject_ptr.h
new file mode 100644
index 0000000..9f337c3
--- /dev/null
+++ b/python/google/protobuf/pyext/scoped_pyobject_ptr.h
@@ -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.
+
+// Author: tibell@google.com (Johan Tibell)
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__
+
+#include <Python.h>
+
+namespace google {
+class ScopedPyObjectPtr {
+ public:
+ // Constructor. Defaults to intializing with NULL.
+ // There is no way to create an uninitialized ScopedPyObjectPtr.
+ explicit ScopedPyObjectPtr(PyObject* p = NULL) : ptr_(p) { }
+
+ // Destructor. If there is a PyObject object, delete it.
+ ~ScopedPyObjectPtr() {
+ Py_XDECREF(ptr_);
+ }
+
+ // Reset. Deletes the current owned object, if any.
+ // Then takes ownership of a new object, if given.
+ // this->reset(this->get()) works.
+ PyObject* reset(PyObject* p = NULL) {
+ if (p != ptr_) {
+ Py_XDECREF(ptr_);
+ ptr_ = p;
+ }
+ return ptr_;
+ }
+
+ // Releases ownership of the object.
+ PyObject* release() {
+ PyObject* p = ptr_;
+ ptr_ = NULL;
+ return p;
+ }
+
+ operator PyObject*() { return ptr_; }
+
+ PyObject* operator->() const {
+ assert(ptr_ != NULL);
+ return ptr_;
+ }
+
+ PyObject* get() const { return ptr_; }
+
+ Py_ssize_t refcnt() const { return Py_REFCNT(ptr_); }
+
+ void inc() const { Py_INCREF(ptr_); }
+
+ // Comparison operators.
+ // These return whether a ScopedPyObjectPtr and a raw pointer
+ // refer to the same object, not just to two different but equal
+ // objects.
+ bool operator==(const PyObject* p) const { return ptr_ == p; }
+ bool operator!=(const PyObject* p) const { return ptr_ != p; }
+
+ private:
+ PyObject* ptr_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedPyObjectPtr);
+};
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__
diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py
index 5b23803..1fc704a 100755
--- a/python/google/protobuf/reflection.py
+++ b/python/google/protobuf/reflection.py
@@ -1,6 +1,6 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -29,9 +29,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This code is meant to work on Python 2.4 and above only.
-#
-# TODO(robinson): Helpers for verbose, common checks like seeing if a
-# descriptor's cpp_type is CPPTYPE_MESSAGE.
"""Contains a metaclass and helper functions used to create
protocol message classes from Descriptor objects at runtime.
@@ -50,27 +47,29 @@ this file*.
__author__ = 'robinson@google.com (Will Robinson)'
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-import struct
-import weakref
-# We use "as" to avoid name collisions with variables.
-from google.protobuf.internal import containers
-from google.protobuf.internal import decoder
-from google.protobuf.internal import encoder
-from google.protobuf.internal import message_listener as message_listener_mod
-from google.protobuf.internal import type_checkers
-from google.protobuf.internal import wire_format
+from google.protobuf.internal import api_implementation
from google.protobuf import descriptor as descriptor_mod
-from google.protobuf import message as message_mod
-from google.protobuf import text_format
+from google.protobuf import message
_FieldDescriptor = descriptor_mod.FieldDescriptor
+if api_implementation.Type() == 'cpp':
+ if api_implementation.Version() == 2:
+ from google.protobuf.pyext import cpp_message
+ _NewMessage = cpp_message.NewMessage
+ _InitMessage = cpp_message.InitMessage
+ else:
+ from google.protobuf.internal import cpp_message
+ _NewMessage = cpp_message.NewMessage
+ _InitMessage = cpp_message.InitMessage
+else:
+ from google.protobuf.internal import python_message
+ _NewMessage = python_message.NewMessage
+ _InitMessage = python_message.InitMessage
+
+
class GeneratedProtocolMessageType(type):
"""Metaclass for protocol message classes created at runtime from Descriptors.
@@ -92,6 +91,10 @@ class GeneratedProtocolMessageType(type):
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
@@ -120,10 +123,12 @@ class GeneratedProtocolMessageType(type):
Newly-allocated class.
"""
descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
- _AddSlots(descriptor, dictionary)
- _AddClassAttributesForNestedExtensions(descriptor, dictionary)
+ bases = _NewMessage(bases, descriptor, dictionary)
superclass = super(GeneratedProtocolMessageType, cls)
- return superclass.__new__(cls, name, bases, dictionary)
+
+ new_class = superclass.__new__(cls, name, bases, dictionary)
+ setattr(descriptor, '_concrete_class', new_class)
+ return new_class
def __init__(cls, name, bases, dictionary):
"""Here we perform the majority of our work on the class.
@@ -143,1006 +148,58 @@ class GeneratedProtocolMessageType(type):
type.
"""
descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
-
- cls._decoders_by_tag = {}
- cls._extensions_by_name = {}
- cls._extensions_by_number = {}
- if (descriptor.has_options and
- descriptor.GetOptions().message_set_wire_format):
- cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = (
- decoder.MessageSetItemDecoder(cls._extensions_by_number))
-
- # We act as a "friend" class of the descriptor, setting
- # its _concrete_class attribute the first time we use a
- # given descriptor to initialize a concrete protocol message
- # class. We also attach stuff to each FieldDescriptor for quick
- # lookup later on.
- concrete_class_attr_name = '_concrete_class'
- if not hasattr(descriptor, concrete_class_attr_name):
- setattr(descriptor, concrete_class_attr_name, cls)
- for field in descriptor.fields:
- _AttachFieldHelpers(cls, field)
-
- _AddEnumValues(descriptor, cls)
- _AddInitMethod(descriptor, cls)
- _AddPropertiesForFields(descriptor, cls)
- _AddPropertiesForExtensions(descriptor, cls)
- _AddStaticMethods(cls)
- _AddMessageMethods(descriptor, cls)
- _AddPrivateHelperMethods(cls)
+ _InitMessage(descriptor, cls)
superclass = super(GeneratedProtocolMessageType, cls)
superclass.__init__(name, bases, dictionary)
-# Stateless helpers for GeneratedProtocolMessageType below.
-# Outside clients should not access these directly.
-#
-# I opted not to make any of these methods on the metaclass, to make it more
-# clear that I'm not really using any state there and to keep clients from
-# thinking that they have direct access to these construction helpers.
-
-
-def _PropertyName(proto_field_name):
- """Returns the name of the public property attribute which
- clients can use to get and (in some cases) set the value
- of a protocol message field.
-
- Args:
- proto_field_name: The protocol message field name, exactly
- as it appears (or would appear) in a .proto file.
- """
- # TODO(robinson): Escape Python keywords (e.g., yield), and test this support.
- # nnorwitz makes my day by writing:
- # """
- # FYI. See the keyword module in the stdlib. This could be as simple as:
- #
- # if keyword.iskeyword(proto_field_name):
- # return proto_field_name + "_"
- # return proto_field_name
- # """
- # Kenton says: The above is a BAD IDEA. People rely on being able to use
- # getattr() and setattr() to reflectively manipulate field values. If we
- # rename the properties, then every such user has to also make sure to apply
- # the same transformation. Note that currently if you name a field "yield",
- # you can still access it just fine using getattr/setattr -- it's not even
- # that cumbersome to do so.
- # TODO(kenton): Remove this method entirely if/when everyone agrees with my
- # position.
- return proto_field_name
-
-
-def _VerifyExtensionHandle(message, extension_handle):
- """Verify that the given extension handle is valid."""
-
- if not isinstance(extension_handle, _FieldDescriptor):
- raise KeyError('HasExtension() expects an extension handle, got: %s' %
- extension_handle)
-
- if not extension_handle.is_extension:
- raise KeyError('"%s" is not an extension.' % extension_handle.full_name)
-
- if extension_handle.containing_type is not message.DESCRIPTOR:
- raise KeyError('Extension "%s" extends message type "%s", but this '
- 'message is of type "%s".' %
- (extension_handle.full_name,
- extension_handle.containing_type.full_name,
- message.DESCRIPTOR.full_name))
-
-
-def _AddSlots(message_descriptor, dictionary):
- """Adds a __slots__ entry to dictionary, containing the names of all valid
- attributes for this message type.
-
- Args:
- message_descriptor: A Descriptor instance describing this message type.
- dictionary: Class dictionary to which we'll add a '__slots__' entry.
- """
- dictionary['__slots__'] = ['_cached_byte_size',
- '_cached_byte_size_dirty',
- '_fields',
- '_is_present_in_parent',
- '_listener',
- '_listener_for_children',
- '__weakref__']
-
-
-def _IsMessageSetExtension(field):
- return (field.is_extension and
- 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)
-
-
-def _AttachFieldHelpers(cls, field_descriptor):
- is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED)
- is_packed = (field_descriptor.has_options and
- field_descriptor.GetOptions().packed)
-
- if _IsMessageSetExtension(field_descriptor):
- field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number)
- sizer = encoder.MessageSetItemSizer(field_descriptor.number)
- else:
- field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type](
- field_descriptor.number, is_repeated, is_packed)
- sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type](
- field_descriptor.number, is_repeated, is_packed)
-
- field_descriptor._encoder = field_encoder
- field_descriptor._sizer = sizer
- field_descriptor._default_constructor = _DefaultValueConstructorForField(
- field_descriptor)
-
- def AddDecoder(wiretype, is_packed):
- tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype)
- cls._decoders_by_tag[tag_bytes] = (
- type_checkers.TYPE_TO_DECODER[field_descriptor.type](
- field_descriptor.number, is_repeated, is_packed,
- field_descriptor, field_descriptor._default_constructor))
-
- AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type],
- False)
-
- if is_repeated and wire_format.IsTypePackable(field_descriptor.type):
- # To support wire compatibility of adding packed = true, add a decoder for
- # packed values regardless of the field's options.
- AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True)
-
-
-def _AddClassAttributesForNestedExtensions(descriptor, dictionary):
- extension_dict = descriptor.extensions_by_name
- for extension_name, extension_field in extension_dict.iteritems():
- assert extension_name not in dictionary
- dictionary[extension_name] = extension_field
-
-
-def _AddEnumValues(descriptor, cls):
- """Sets class-level attributes for all enum fields defined in this message.
-
- Args:
- descriptor: Descriptor object for this message type.
- cls: Class we're constructing for this message type.
- """
- for enum_type in descriptor.enum_types:
- for enum_value in enum_type.values:
- setattr(cls, enum_value.name, enum_value.number)
-
-
-def _DefaultValueConstructorForField(field):
- """Returns a function which returns a default value for a field.
+def ParseMessage(descriptor, byte_str):
+ """Generate a new Message instance from this Descriptor and a byte string.
Args:
- field: FieldDescriptor object for this field.
+ descriptor: Protobuf Descriptor object
+ byte_str: Serialized protocol buffer byte string
- The returned function has one argument:
- message: Message instance containing this field, or a weakref proxy
- of same.
-
- That function in turn returns a default value for this field. The default
- value may refer back to |message| via a weak reference.
- """
-
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- if field.default_value != []:
- raise ValueError('Repeated field default value not empty list: %s' % (
- field.default_value))
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- # We can't look at _concrete_class yet since it might not have
- # been set. (Depends on order in which we initialize the classes).
- message_type = field.message_type
- def MakeRepeatedMessageDefault(message):
- return containers.RepeatedCompositeFieldContainer(
- message._listener_for_children, field.message_type)
- return MakeRepeatedMessageDefault
- else:
- type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type)
- def MakeRepeatedScalarDefault(message):
- return containers.RepeatedScalarFieldContainer(
- message._listener_for_children, type_checker)
- return MakeRepeatedScalarDefault
-
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- # _concrete_class may not yet be initialized.
- message_type = field.message_type
- def MakeSubMessageDefault(message):
- result = message_type._concrete_class()
- result._SetListener(message._listener_for_children)
- return result
- return MakeSubMessageDefault
-
- def MakeScalarDefault(message):
- return field.default_value
- return MakeScalarDefault
-
-
-def _AddInitMethod(message_descriptor, cls):
- """Adds an __init__ method to cls."""
- fields = message_descriptor.fields
- def init(self, **kwargs):
- self._cached_byte_size = 0
- self._cached_byte_size_dirty = False
- self._fields = {}
- self._is_present_in_parent = False
- self._listener = message_listener_mod.NullMessageListener()
- self._listener_for_children = _Listener(self)
- for field_name, field_value in kwargs.iteritems():
- field = _GetFieldByName(message_descriptor, field_name)
- if field is None:
- raise TypeError("%s() got an unexpected keyword argument '%s'" %
- (message_descriptor.name, field_name))
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- copy = field._default_constructor(self)
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite
- for val in field_value:
- copy.add().MergeFrom(val)
- else: # Scalar
- copy.extend(field_value)
- self._fields[field] = copy
- elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- copy = field._default_constructor(self)
- copy.MergeFrom(field_value)
- self._fields[field] = copy
- else:
- self._fields[field] = field_value
-
- init.__module__ = None
- init.__doc__ = None
- cls.__init__ = init
-
-
-def _GetFieldByName(message_descriptor, field_name):
- """Returns a field descriptor by field name.
-
- Args:
- message_descriptor: A Descriptor describing all fields in message.
- field_name: The name of the field to retrieve.
Returns:
- The field descriptor associated with the field name.
- """
- try:
- return message_descriptor.fields_by_name[field_name]
- except KeyError:
- raise ValueError('Protocol message has no "%s" field.' % field_name)
-
-
-def _AddPropertiesForFields(descriptor, cls):
- """Adds properties for all fields in this protocol message type."""
- for field in descriptor.fields:
- _AddPropertiesForField(field, cls)
-
- if descriptor.is_extendable:
- # _ExtensionDict is just an adaptor with no state so we allocate a new one
- # every time it is accessed.
- cls.Extensions = property(lambda self: _ExtensionDict(self))
-
-
-def _AddPropertiesForField(field, cls):
- """Adds a public property for a protocol message field.
- Clients can use this property to get and (in the case
- of non-repeated scalar fields) directly set the value
- of a protocol message field.
-
- Args:
- field: A FieldDescriptor for this field.
- cls: The class we're constructing.
- """
- # Catch it if we add other types that we should
- # handle specially here.
- assert _FieldDescriptor.MAX_CPPTYPE == 10
-
- constant_name = field.name.upper() + "_FIELD_NUMBER"
- setattr(cls, constant_name, field.number)
-
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- _AddPropertiesForRepeatedField(field, cls)
- elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- _AddPropertiesForNonRepeatedCompositeField(field, cls)
- else:
- _AddPropertiesForNonRepeatedScalarField(field, cls)
-
-
-def _AddPropertiesForRepeatedField(field, cls):
- """Adds a public property for a "repeated" protocol message field. Clients
- can use this property to get the value of the field, which will be either a
- _RepeatedScalarFieldContainer or _RepeatedCompositeFieldContainer (see
- below).
-
- Note that when clients add values to these containers, we perform
- type-checking in the case of repeated scalar fields, and we also set any
- necessary "has" bits as a side-effect.
-
- Args:
- field: A FieldDescriptor for this field.
- cls: The class we're constructing.
- """
- proto_field_name = field.name
- property_name = _PropertyName(proto_field_name)
-
- def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
- getter.__module__ = None
- getter.__doc__ = 'Getter for %s.' % proto_field_name
-
- # We define a setter just so we can throw an exception with a more
- # helpful error message.
- def setter(self, new_value):
- raise AttributeError('Assignment not allowed to repeated field '
- '"%s" in protocol message object.' % proto_field_name)
-
- doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
- setattr(cls, property_name, property(getter, setter, doc=doc))
-
-
-def _AddPropertiesForNonRepeatedScalarField(field, cls):
- """Adds a public property for a nonrepeated, scalar protocol message field.
- Clients can use this property to get and directly set the value of the field.
- Note that when the client sets the value of a field by using this property,
- all necessary "has" bits are set as a side-effect, and we also perform
- type-checking.
-
- Args:
- field: A FieldDescriptor for this field.
- cls: The class we're constructing.
- """
- proto_field_name = field.name
- property_name = _PropertyName(proto_field_name)
- type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type)
- default_value = field.default_value
-
- def getter(self):
- return self._fields.get(field, default_value)
- getter.__module__ = None
- getter.__doc__ = 'Getter for %s.' % proto_field_name
- def setter(self, new_value):
- type_checker.CheckValue(new_value)
- self._fields[field] = new_value
- # Check _cached_byte_size_dirty inline to improve performance, since scalar
- # setters are called frequently.
- if not self._cached_byte_size_dirty:
- self._Modified()
- setter.__module__ = None
- setter.__doc__ = 'Setter for %s.' % proto_field_name
-
- # Add a property to encapsulate the getter/setter.
- doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
- setattr(cls, property_name, property(getter, setter, doc=doc))
-
-
-def _AddPropertiesForNonRepeatedCompositeField(field, cls):
- """Adds a public property for a nonrepeated, composite protocol message field.
- A composite field is a "group" or "message" field.
-
- Clients can use this property to get the value of the field, but cannot
- assign to the property directly.
-
- Args:
- field: A FieldDescriptor for this field.
- cls: The class we're constructing.
+ Newly created protobuf Message object.
"""
- # TODO(robinson): Remove duplication with similar method
- # for non-repeated scalars.
- proto_field_name = field.name
- property_name = _PropertyName(proto_field_name)
- message_type = field.message_type
-
- def getter(self):
- field_value = self._fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = message_type._concrete_class()
- field_value._SetListener(self._listener_for_children)
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- field_value = self._fields.setdefault(field, field_value)
- return field_value
- getter.__module__ = None
- getter.__doc__ = 'Getter for %s.' % proto_field_name
-
- # We define a setter just so we can throw an exception with a more
- # helpful error message.
- def setter(self, new_value):
- raise AttributeError('Assignment not allowed to composite field '
- '"%s" in protocol message object.' % proto_field_name)
-
- # Add a property to encapsulate the getter.
- doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
- setattr(cls, property_name, property(getter, setter, doc=doc))
-
-
-def _AddPropertiesForExtensions(descriptor, cls):
- """Adds properties for all fields in this protocol message type."""
- extension_dict = descriptor.extensions_by_name
- for extension_name, extension_field in extension_dict.iteritems():
- constant_name = extension_name.upper() + "_FIELD_NUMBER"
- setattr(cls, constant_name, extension_field.number)
-
-
-def _AddStaticMethods(cls):
- # TODO(robinson): This probably needs to be thread-safe(?)
- def RegisterExtension(extension_handle):
- extension_handle.containing_type = cls.DESCRIPTOR
- _AttachFieldHelpers(cls, extension_handle)
-
- # Try to insert our extension, failing if an extension with the same number
- # already exists.
- actual_handle = cls._extensions_by_number.setdefault(
- extension_handle.number, extension_handle)
- if actual_handle is not extension_handle:
- raise AssertionError(
- 'Extensions "%s" and "%s" both try to extend message type "%s" with '
- 'field number %d.' %
- (extension_handle.full_name, actual_handle.full_name,
- cls.DESCRIPTOR.full_name, extension_handle.number))
-
- cls._extensions_by_name[extension_handle.full_name] = extension_handle
-
- handle = extension_handle # avoid line wrapping
- if _IsMessageSetExtension(handle):
- # MessageSet extension. Also register under type name.
- cls._extensions_by_name[
- extension_handle.message_type.full_name] = extension_handle
-
- cls.RegisterExtension = staticmethod(RegisterExtension)
-
- def FromString(s):
- message = cls()
- message.MergeFromString(s)
- return message
- cls.FromString = staticmethod(FromString)
-
-
-def _IsPresent(item):
- """Given a (FieldDescriptor, value) tuple from _fields, return true if the
- value should be included in the list returned by ListFields()."""
-
- if item[0].label == _FieldDescriptor.LABEL_REPEATED:
- return bool(item[1])
- elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- return item[1]._is_present_in_parent
- else:
- return True
-
-
-def _AddListFieldsMethod(message_descriptor, cls):
- """Helper for _AddMessageMethods()."""
-
- def ListFields(self):
- all_fields = [item for item in self._fields.iteritems() if _IsPresent(item)]
- all_fields.sort(key = lambda item: item[0].number)
- return all_fields
-
- cls.ListFields = ListFields
-
-
-def _AddHasFieldMethod(message_descriptor, cls):
- """Helper for _AddMessageMethods()."""
-
- singular_fields = {}
- for field in message_descriptor.fields:
- if field.label != _FieldDescriptor.LABEL_REPEATED:
- singular_fields[field.name] = field
-
- def HasField(self, field_name):
- try:
- field = singular_fields[field_name]
- except KeyError:
- raise ValueError(
- 'Protocol message has no singular "%s" field.' % field_name)
-
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(field)
- return value is not None and value._is_present_in_parent
- else:
- return field in self._fields
- cls.HasField = HasField
+ result_class = MakeClass(descriptor)
+ new_msg = result_class()
+ new_msg.ParseFromString(byte_str)
+ return new_msg
-def _AddClearFieldMethod(message_descriptor, cls):
- """Helper for _AddMessageMethods()."""
- def ClearField(self, field_name):
- try:
- field = message_descriptor.fields_by_name[field_name]
- except KeyError:
- raise ValueError('Protocol message has no "%s" field.' % field_name)
+def MakeClass(descriptor):
+ """Construct a class object for a protobuf described by descriptor.
- if field in self._fields:
- # 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.
- del self._fields[field]
+ Composite descriptors are handled by defining the new class as a member of the
+ parent class, recursing as deep as necessary.
+ This is the dynamic equivalent to:
- # Always call _Modified() -- even if nothing was changed, this is
- # a mutating method, and thus calling it should cause the field to become
- # present in the parent message.
- self._Modified()
-
- cls.ClearField = ClearField
-
-
-def _AddClearExtensionMethod(cls):
- """Helper for _AddMessageMethods()."""
- def ClearExtension(self, extension_handle):
- _VerifyExtensionHandle(self, extension_handle)
-
- # Similar to ClearField(), above.
- if extension_handle in self._fields:
- del self._fields[extension_handle]
- self._Modified()
- cls.ClearExtension = ClearExtension
-
-
-def _AddClearMethod(message_descriptor, cls):
- """Helper for _AddMessageMethods()."""
- def Clear(self):
- # Clear fields.
- self._fields = {}
- self._Modified()
- cls.Clear = Clear
-
-
-def _AddHasExtensionMethod(cls):
- """Helper for _AddMessageMethods()."""
- def HasExtension(self, extension_handle):
- _VerifyExtensionHandle(self, extension_handle)
- if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
- raise KeyError('"%s" is repeated.' % extension_handle.full_name)
-
- if extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- value = self._fields.get(extension_handle)
- return value is not None and value._is_present_in_parent
- else:
- return extension_handle in self._fields
- cls.HasExtension = HasExtension
-
-
-def _AddEqualsMethod(message_descriptor, cls):
- """Helper for _AddMessageMethods()."""
- def __eq__(self, other):
- if (not isinstance(other, message_mod.Message) or
- other.DESCRIPTOR != self.DESCRIPTOR):
- return False
-
- if self is other:
- return True
-
- return self.ListFields() == other.ListFields()
-
- cls.__eq__ = __eq__
-
-
-def _AddStrMethod(message_descriptor, cls):
- """Helper for _AddMessageMethods()."""
- def __str__(self):
- return text_format.MessageToString(self)
- cls.__str__ = __str__
-
-
-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
- other additional space associated with serializing value.
+ class Parent(message.Message):
+ __metaclass__ = GeneratedProtocolMessageType
+ DESCRIPTOR = descriptor
+ class Child(message.Message):
+ __metaclass__ = GeneratedProtocolMessageType
+ DESCRIPTOR = descriptor.nested_types[0]
+
+ Sample usage:
+ file_descriptor = descriptor_pb2.FileDescriptorProto()
+ file_descriptor.ParseFromString(proto2_string)
+ msg_descriptor = descriptor.MakeDescriptor(file_descriptor.message_type[0])
+ msg_class = reflection.MakeClass(msg_descriptor)
+ msg = msg_class()
Args:
- value: Value we're serializing.
- field_number: Field number of this value. (Since the field number
- is stored as part of a varint-encoded tag, this has an impact
- on the total bytes required to serialize the value).
- field_type: The type of the field. One of the TYPE_* constants
- within FieldDescriptor.
- """
- try:
- fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type]
- return fn(field_number, value)
- except KeyError:
- raise message_mod.EncodeError('Unrecognized field type: %d' % field_type)
-
-
-def _AddByteSizeMethod(message_descriptor, cls):
- """Helper for _AddMessageMethods()."""
-
- def ByteSize(self):
- if not self._cached_byte_size_dirty:
- return self._cached_byte_size
-
- size = 0
- for field_descriptor, field_value in self.ListFields():
- size += field_descriptor._sizer(field_value)
-
- self._cached_byte_size = size
- self._cached_byte_size_dirty = False
- self._listener_for_children.dirty = False
- return size
-
- cls.ByteSize = ByteSize
-
-
-def _AddSerializeToStringMethod(message_descriptor, cls):
- """Helper for _AddMessageMethods()."""
-
- def SerializeToString(self):
- # Check if the message has all of its required fields set.
- errors = []
- if not self.IsInitialized():
- raise message_mod.EncodeError(
- 'Message is missing required fields: ' +
- ','.join(self.FindInitializationErrors()))
- return self.SerializePartialToString()
- cls.SerializeToString = SerializeToString
-
-
-def _AddSerializePartialToStringMethod(message_descriptor, cls):
- """Helper for _AddMessageMethods()."""
-
- def SerializePartialToString(self):
- out = StringIO()
- self._InternalSerialize(out.write)
- return out.getvalue()
- cls.SerializePartialToString = SerializePartialToString
-
- def InternalSerialize(self, write_bytes):
- for field_descriptor, field_value in self.ListFields():
- field_descriptor._encoder(write_bytes, field_value)
- cls._InternalSerialize = InternalSerialize
-
-
-def _AddMergeFromStringMethod(message_descriptor, cls):
- """Helper for _AddMessageMethods()."""
- def MergeFromString(self, serialized):
- length = len(serialized)
- try:
- if self._InternalParse(serialized, 0, length) != length:
- # The only reason _InternalParse would return early is if it
- # encountered an end-group tag.
- raise message_mod.DecodeError('Unexpected end-group tag.')
- except IndexError:
- raise message_mod.DecodeError('Truncated message.')
- except struct.error, e:
- raise message_mod.DecodeError(e)
- return length # Return this for legacy reasons.
- cls.MergeFromString = MergeFromString
-
- local_ReadTag = decoder.ReadTag
- local_SkipField = decoder.SkipField
- decoders_by_tag = cls._decoders_by_tag
-
- def InternalParse(self, buffer, pos, end):
- self._Modified()
- field_dict = self._fields
- while pos != end:
- (tag_bytes, new_pos) = local_ReadTag(buffer, pos)
- field_decoder = decoders_by_tag.get(tag_bytes)
- if field_decoder is None:
- new_pos = local_SkipField(buffer, new_pos, end, tag_bytes)
- if new_pos == -1:
- return pos
- pos = new_pos
- else:
- pos = field_decoder(buffer, new_pos, end, self, field_dict)
- return pos
- cls._InternalParse = InternalParse
-
-
-def _AddIsInitializedMethod(message_descriptor, cls):
- """Adds the IsInitialized and FindInitializationError methods to the
- protocol message class."""
-
- required_fields = [field for field in message_descriptor.fields
- if field.label == _FieldDescriptor.LABEL_REQUIRED]
-
- def IsInitialized(self, errors=None):
- """Checks if all required fields of a message are set.
-
- Args:
- errors: A list which, if provided, will be populated with the field
- paths of all missing required fields.
-
- Returns:
- True iff the specified message has all required fields set.
- """
-
- # Performance is critical so we avoid HasField() and ListFields().
-
- for field in required_fields:
- if (field not in self._fields or
- (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
- not self._fields[field]._is_present_in_parent)):
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- for field, value in self._fields.iteritems():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- for element in value:
- if not element.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
- elif value._is_present_in_parent and not value.IsInitialized():
- if errors is not None:
- errors.extend(self.FindInitializationErrors())
- return False
-
- return True
-
- cls.IsInitialized = IsInitialized
-
- def FindInitializationErrors(self):
- """Finds required fields which are not initialized.
-
- Returns:
- A list of strings. Each string is a path to an uninitialized field from
- the top-level message, e.g. "foo.bar[5].baz".
- """
-
- errors = [] # simplify things
-
- for field in required_fields:
- if not self.HasField(field.name):
- errors.append(field.name)
-
- for field, value in self.ListFields():
- if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- if field.is_extension:
- name = "(%s)" % field.full_name
- else:
- name = field.name
-
- if field.label == _FieldDescriptor.LABEL_REPEATED:
- for i in xrange(len(value)):
- element = value[i]
- prefix = "%s[%d]." % (name, i)
- sub_errors = element.FindInitializationErrors()
- errors += [ prefix + error for error in sub_errors ]
- else:
- prefix = name + "."
- sub_errors = value.FindInitializationErrors()
- errors += [ prefix + error for error in sub_errors ]
-
- return errors
-
- cls.FindInitializationErrors = FindInitializationErrors
-
-
-def _AddMergeFromMethod(cls):
- LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED
- CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE
-
- def MergeFrom(self, msg):
- assert msg is not self
- self._Modified()
-
- fields = self._fields
-
- for field, value in msg._fields.iteritems():
- if field.label == LABEL_REPEATED or field.cpp_type == CPPTYPE_MESSAGE:
- field_value = fields.get(field)
- if field_value is None:
- # Construct a new object to represent this field.
- field_value = field._default_constructor(self)
- fields[field] = field_value
- field_value.MergeFrom(value)
- else:
- self._fields[field] = value
- cls.MergeFrom = MergeFrom
-
-
-def _AddMessageMethods(message_descriptor, cls):
- """Adds implementations of all Message methods to cls."""
- _AddListFieldsMethod(message_descriptor, cls)
- _AddHasFieldMethod(message_descriptor, cls)
- _AddClearFieldMethod(message_descriptor, cls)
- if message_descriptor.is_extendable:
- _AddClearExtensionMethod(cls)
- _AddHasExtensionMethod(cls)
- _AddClearMethod(message_descriptor, cls)
- _AddEqualsMethod(message_descriptor, cls)
- _AddStrMethod(message_descriptor, cls)
- _AddSetListenerMethod(cls)
- _AddByteSizeMethod(message_descriptor, cls)
- _AddSerializeToStringMethod(message_descriptor, cls)
- _AddSerializePartialToStringMethod(message_descriptor, cls)
- _AddMergeFromStringMethod(message_descriptor, cls)
- _AddIsInitializedMethod(message_descriptor, cls)
- _AddMergeFromMethod(cls)
-
-
-def _AddPrivateHelperMethods(cls):
- """Adds implementation of private helper methods to cls."""
-
- def Modified(self):
- """Sets the _cached_byte_size_dirty bit to true,
- and propagates this to our listener iff this was a state change.
- """
-
- # Note: Some callers check _cached_byte_size_dirty before calling
- # _Modified() as an extra optimization. So, if this method is ever
- # changed such that it does stuff even when _cached_byte_size_dirty is
- # already true, the callers need to be updated.
- if not self._cached_byte_size_dirty:
- self._cached_byte_size_dirty = True
- self._listener_for_children.dirty = True
- self._is_present_in_parent = True
- self._listener.Modified()
-
- cls._Modified = Modified
- cls.SetInParent = Modified
-
-
-class _Listener(object):
-
- """MessageListener implementation that a parent message registers with its
- child message.
-
- In order to support semantics like:
-
- foo.bar.baz.qux = 23
- assert foo.HasField('bar')
-
- ...child objects must have back references to their parents.
- This helper class is at the heart of this support.
- """
-
- def __init__(self, parent_message):
- """Args:
- parent_message: The message whose _Modified() method we should call when
- we receive Modified() messages.
- """
- # This listener establishes a back reference from a child (contained) object
- # to its parent (containing) object. We make this a weak reference to avoid
- # creating cyclic garbage when the client finishes with the 'parent' object
- # in the tree.
- if isinstance(parent_message, weakref.ProxyType):
- self._parent_message_weakref = parent_message
- else:
- self._parent_message_weakref = weakref.proxy(parent_message)
-
- # As an optimization, we also indicate directly on the listener whether
- # or not the parent message is dirty. This way we can avoid traversing
- # up the tree in the common case.
- self.dirty = False
-
- def Modified(self):
- if self.dirty:
- return
- try:
- # Propagate the signal to our parents iff this is the first field set.
- self._parent_message_weakref._Modified()
- except ReferenceError:
- # We can get here if a client has kept a reference to a child object,
- # and is now setting a field on it, but the child's parent has been
- # garbage-collected. This is not an error.
- pass
-
-
-# TODO(robinson): Move elsewhere? This file is getting pretty ridiculous...
-# TODO(robinson): Unify error handling of "unknown extension" crap.
-# TODO(robinson): Support iteritems()-style iteration over all
-# extensions with the "has" bits turned on?
-class _ExtensionDict(object):
-
- """Dict-like container for supporting an indexable "Extensions"
- field on proto instances.
-
- Note that in all cases we expect extension handles to be
- FieldDescriptors.
+ descriptor: A descriptor.Descriptor object describing the protobuf.
+ Returns:
+ The Message class object described by the descriptor.
"""
+ attributes = {}
+ for name, nested_type in descriptor.nested_types_by_name.items():
+ attributes[name] = MakeClass(nested_type)
- def __init__(self, extended_message):
- """extended_message: Message instance for which we are the Extensions dict.
- """
-
- self._extended_message = extended_message
-
- def __getitem__(self, extension_handle):
- """Returns the current value of the given extension handle."""
-
- _VerifyExtensionHandle(self._extended_message, extension_handle)
-
- result = self._extended_message._fields.get(extension_handle)
- if result is not None:
- return result
-
- if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
- result = extension_handle._default_constructor(self._extended_message)
- elif extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
- result = extension_handle.message_type._concrete_class()
- try:
- result._SetListener(self._extended_message._listener_for_children)
- except ReferenceError:
- pass
- else:
- # Singular scalar -- just return the default without inserting into the
- # dict.
- return extension_handle.default_value
-
- # Atomically check if another thread has preempted us and, if not, swap
- # in the new object we just created. If someone has preempted us, we
- # take that object and discard ours.
- # WARNING: We are relying on setdefault() being atomic. This is true
- # in CPython but we haven't investigated others. This warning appears
- # in several other locations in this file.
- result = self._extended_message._fields.setdefault(
- extension_handle, result)
-
- return result
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- return False
+ attributes[GeneratedProtocolMessageType._DESCRIPTOR_KEY] = descriptor
- my_fields = self._extended_message.ListFields()
- other_fields = other._extended_message.ListFields()
-
- # Get rid of non-extension fields.
- my_fields = [ field for field in my_fields if field.is_extension ]
- other_fields = [ field for field in other_fields if field.is_extension ]
-
- return my_fields == other_fields
-
- def __ne__(self, other):
- return not self == other
-
- # Note that this is only meaningful for non-repeated, scalar extension
- # fields. Note also that we may have to call _Modified() when we do
- # successfully set a field this way, to set any necssary "has" bits in the
- # ancestors of the extended message.
- def __setitem__(self, extension_handle, value):
- """If extension_handle specifies a non-repeated, scalar extension
- field, sets the value of that field.
- """
-
- _VerifyExtensionHandle(self._extended_message, extension_handle)
-
- if (extension_handle.label == _FieldDescriptor.LABEL_REPEATED or
- extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE):
- raise TypeError(
- 'Cannot assign to extension "%s" because it is a repeated or '
- 'composite type.' % extension_handle.full_name)
-
- # It's slightly wasteful to lookup the type checker each time,
- # but we expect this to be a vanishingly uncommon case anyway.
- type_checker = type_checkers.GetTypeChecker(
- extension_handle.cpp_type, extension_handle.type)
- type_checker.CheckValue(value)
- self._extended_message._fields[extension_handle] = value
- self._extended_message._Modified()
-
- def _FindExtensionByName(self, name):
- """Tries to find a known extension with the specified name.
-
- Args:
- name: Extension full name.
-
- Returns:
- Extension field descriptor.
- """
- return self._extended_message._extensions_by_name.get(name, None)
+ return GeneratedProtocolMessageType(str(descriptor.name), (message.Message,),
+ attributes)
diff --git a/python/google/protobuf/service.py b/python/google/protobuf/service.py
index 180b70e..9e00de7 100755
--- a/python/google/protobuf/service.py
+++ b/python/google/protobuf/service.py
@@ -1,6 +1,6 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
diff --git a/python/google/protobuf/service_reflection.py b/python/google/protobuf/service_reflection.py
index 851e83e..1c3636a 100755
--- a/python/google/protobuf/service_reflection.py
+++ b/python/google/protobuf/service_reflection.py
@@ -1,6 +1,6 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
diff --git a/python/google/protobuf/symbol_database.py b/python/google/protobuf/symbol_database.py
new file mode 100644
index 0000000..4c70b39
--- /dev/null
+++ b/python/google/protobuf/symbol_database.py
@@ -0,0 +1,185 @@
+# 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.
+
+"""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.
+
+Example usage:
+
+ db = symbol_database.SymbolDatabase()
+
+ # Register symbols of interest, from one or multiple files.
+ db.RegisterFileDescriptor(my_proto_pb2.DESCRIPTOR)
+ db.RegisterMessage(my_proto_pb2.MyMessage)
+ db.RegisterEnumDescriptor(my_proto_pb2.MyEnum.DESCRIPTOR)
+
+ # The database can be used as a MessageFactory, to generate types based on
+ # their name:
+ types = db.GetMessages(['my_proto.proto'])
+ my_message_instance = types['MyMessage']()
+
+ # The database's underlying descriptor pool can be queried, so it's not
+ # necessary to know a type's filename to be able to generate it:
+ filename = db.pool.FindFileContainingSymbol('MyMessage')
+ my_message_instance = db.GetMessages([filename])['MyMessage']()
+
+ # This functionality is also provided directly via a convenience method:
+ my_message_instance = db.GetSymbol('MyMessage')()
+"""
+
+
+from google.protobuf import descriptor_pool
+
+
+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.
+ """
+
+ def __init__(self):
+ """Constructor."""
+
+ self._symbols = {}
+ self._symbols_by_file = {}
+ self.pool = descriptor_pool.DescriptorPool()
+
+ def RegisterMessage(self, message):
+ """Registers the given message type in the local database.
+
+ Args:
+ message: a message.Message, to be registered.
+
+ Returns:
+ The provided message.
+ """
+
+ 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.pool.AddDescriptor(desc)
+ return message
+
+ def RegisterEnumDescriptor(self, enum_descriptor):
+ """Registers the given enum descriptor in the local database.
+
+ Args:
+ enum_descriptor: a descriptor.EnumDescriptor.
+
+ Returns:
+ The provided descriptor.
+ """
+ self.pool.AddEnumDescriptor(enum_descriptor)
+ return enum_descriptor
+
+ def RegisterFileDescriptor(self, file_descriptor):
+ """Registers the given file descriptor in the local database.
+
+ Args:
+ file_descriptor: a descriptor.FileDescriptor.
+
+ Returns:
+ The provided descriptor.
+ """
+ self.pool.AddFileDescriptor(file_descriptor)
+
+ def GetSymbol(self, symbol):
+ """Tries to find a symbol in the local database.
+
+ Currently, this method only returns message.Message instances, however, if
+ may be extended in future to support other symbol types.
+
+ Args:
+ symbol: A str, a protocol buffer symbol.
+
+ Returns:
+ A Python class corresponding to the symbol.
+
+ Raises:
+ 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)
+
+ 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.
+
+
+ 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.
+
+ Raises:
+ KeyError: if a file could not be found.
+ """
+
+ result = {}
+ for f in files:
+ result.update(self._symbols_by_file[f])
+ return result
+
+_DEFAULT = SymbolDatabase()
+
+
+def Default():
+ """Returns the default SymbolDatabase."""
+ return _DEFAULT
diff --git a/python/google/protobuf/text_encoding.py b/python/google/protobuf/text_encoding.py
new file mode 100644
index 0000000..2d86a67
--- /dev/null
+++ b/python/google/protobuf/text_encoding.py
@@ -0,0 +1,110 @@
+# 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.
+
+#PY25 compatible for GAE.
+#
+"""Encoding related utilities."""
+
+import re
+import sys ##PY25
+
+# Lookup table for utf8
+_cescape_utf8_to_str = [chr(i) for i in xrange(0, 256)]
+_cescape_utf8_to_str[9] = r'\t' # optional escape
+_cescape_utf8_to_str[10] = r'\n' # optional escape
+_cescape_utf8_to_str[13] = r'\r' # optional escape
+_cescape_utf8_to_str[39] = r"\'" # optional escape
+
+_cescape_utf8_to_str[34] = r'\"' # necessary escape
+_cescape_utf8_to_str[92] = r'\\' # necessary escape
+
+# Lookup table for non-utf8, with necessary escapes at (o >= 127 or o < 32)
+_cescape_byte_to_str = ([r'\%03o' % i for i in xrange(0, 32)] +
+ [chr(i) for i in xrange(32, 127)] +
+ [r'\%03o' % i for i in xrange(127, 256)])
+_cescape_byte_to_str[9] = r'\t' # optional escape
+_cescape_byte_to_str[10] = r'\n' # optional escape
+_cescape_byte_to_str[13] = r'\r' # optional escape
+_cescape_byte_to_str[39] = r"\'" # optional escape
+
+_cescape_byte_to_str[34] = r'\"' # necessary escape
+_cescape_byte_to_str[92] = r'\\' # necessary escape
+
+
+def CEscape(text, as_utf8):
+ """Escape a bytes string for use in an ascii protocol buffer.
+
+ text.encode('string_escape') does not seem to satisfy our needs as it
+ encodes unprintable characters using two-digit hex escapes whereas our
+ C++ unescaping function allows hex escapes to be any length. So,
+ "\0011".encode('string_escape') ends up being "\\x011", which will be
+ decoded in C++ as a single-character string with char code 0x11.
+
+ Args:
+ text: A byte string to be escaped
+ as_utf8: Specifies if result should be returned in UTF-8 encoding
+ Returns:
+ Escaped string
+ """
+ # PY3 hack: make Ord work for str and bytes:
+ # //platforms/networking/data uses unicode here, hence basestring.
+ Ord = ord if isinstance(text, basestring) else lambda x: x
+ if as_utf8:
+ return ''.join(_cescape_utf8_to_str[Ord(c)] for c in text)
+ return ''.join(_cescape_byte_to_str[Ord(c)] for c in text)
+
+
+_CUNESCAPE_HEX = re.compile(r'(\\+)x([0-9a-fA-F])(?![0-9a-fA-F])')
+_cescape_highbit_to_str = ([chr(i) for i in range(0, 127)] +
+ [r'\%03o' % i for i in range(127, 256)])
+
+
+def CUnescape(text):
+ """Unescape a text string with C-style escape sequences to UTF-8 bytes."""
+
+ def ReplaceHex(m):
+ # Only replace the match if the number of leading back slashes is odd. i.e.
+ # the slash itself is not escaped.
+ if len(m.group(1)) & 1:
+ return m.group(1) + 'x0' + m.group(2)
+ return m.group(0)
+
+ # This is required because the 'string_escape' encoding doesn't
+ # allow single-digit hex escapes (like '\xf').
+ result = _CUNESCAPE_HEX.sub(ReplaceHex, text)
+
+ if sys.version_info[0] < 3: ##PY25
+##!PY25 if str is bytes: # PY2
+ return result.decode('string_escape')
+ result = ''.join(_cescape_highbit_to_str[ord(c)] for c in result)
+ return (result.encode('ascii') # Make it bytes to allow decode.
+ .decode('unicode_escape')
+ # Make it bytes again to return the proper type.
+ .encode('raw_unicode_escape'))
diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py
index cc6ac90..2429fa5 100755
--- a/python/google/protobuf/text_format.py
+++ b/python/google/protobuf/text_format.py
@@ -1,6 +1,6 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -28,6 +28,10 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#PY25 compatible for GAE.
+#
+# Copyright 2007 Google Inc. All Rights Reserved.
+
"""Contains routines for printing protocol messages in text format."""
__author__ = 'kenton@google.com (Kenton Varda)'
@@ -35,46 +39,92 @@ __author__ = 'kenton@google.com (Kenton Varda)'
import cStringIO
import re
-from collections import deque
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(),
+ type_checkers.Uint64ValueChecker(),
+ type_checkers.Int64ValueChecker())
+_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])
-# Infinity and NaN are not explicitly supported by Python pre-2.6, and
-# float('inf') does not work on Windows (pre-2.6).
-_INFINITY = 1e10000 # overflows, thus will actually be infinity.
-_NAN = _INFINITY * 0
+class Error(Exception):
+ """Top-level module error for text_format."""
-class ParseError(Exception):
+
+class ParseError(Error):
"""Thrown in case of ASCII parsing error."""
-def MessageToString(message):
+def MessageToString(message, as_utf8=False, as_one_line=False,
+ pointy_brackets=False, use_index_order=False,
+ float_format=None):
+ """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'.
+
+ Args:
+ message: The protocol buffers message.
+ 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.
+
+ Returns:
+ A string of the text formatted protocol buffer message.
+ """
out = cStringIO.StringIO()
- PrintMessage(message, out)
+ 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)
result = out.getvalue()
out.close()
+ if as_one_line:
+ return result.rstrip()
return result
-def PrintMessage(message, out, indent = 0):
- for field, value in message.ListFields():
+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 field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
for element in value:
- PrintField(field, element, out, indent)
+ PrintField(field, element, out, indent, as_utf8, as_one_line,
+ pointy_brackets=pointy_brackets,
+ float_format=float_format)
else:
- PrintField(field, value, out, indent)
+ PrintField(field, value, out, indent, as_utf8, as_one_line,
+ pointy_brackets=pointy_brackets,
+ float_format=float_format)
-def PrintField(field, value, out, indent = 0):
+def PrintField(field, value, out, indent=0, as_utf8=False, as_one_line=False,
+ pointy_brackets=False, float_format=None):
"""Print a single field name/value pair. For repeated fields, the value
should be a single element."""
- out.write(' ' * indent);
+ out.write(' ' * indent)
if field.is_extension:
out.write('[')
if (field.containing_type.GetOptions().message_set_wire_format and
@@ -96,54 +146,168 @@ def PrintField(field, value, out, indent = 0):
# don't include it.
out.write(': ')
- PrintFieldValue(field, value, out, indent)
- out.write('\n')
+ PrintFieldValue(field, value, out, indent, as_utf8, as_one_line,
+ pointy_brackets=pointy_brackets,
+ float_format=float_format)
+ if as_one_line:
+ out.write(' ')
+ else:
+ out.write('\n')
-def PrintFieldValue(field, value, out, indent = 0):
+def PrintFieldValue(field, value, out, indent=0, as_utf8=False,
+ as_one_line=False, pointy_brackets=False,
+ float_format=None):
"""Print a single field value (not including name). For repeated fields,
the value should be a single element."""
+ if pointy_brackets:
+ openb = '<'
+ closeb = '>'
+ else:
+ openb = '{'
+ closeb = '}'
+
if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
- out.write(' {\n')
- PrintMessage(value, out, indent + 2)
- out.write(' ' * indent + '}')
+ if as_one_line:
+ out.write(' %s ' % openb)
+ PrintMessage(value, out, indent, as_utf8, as_one_line,
+ pointy_brackets=pointy_brackets,
+ float_format=float_format)
+ out.write(closeb)
+ else:
+ out.write(' %s\n' % openb)
+ PrintMessage(value, out, indent + 2, as_utf8, as_one_line,
+ pointy_brackets=pointy_brackets,
+ float_format=float_format)
+ out.write(' ' * indent + closeb)
elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
- out.write(field.enum_type.values_by_number[value].name)
+ 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('\"')
- out.write(_CEscape(value))
+ if isinstance(value, unicode):
+ 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 = 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")
+ out.write('true')
else:
- out.write("false")
+ 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))
+def _ParseOrMerge(lines, message, allow_multiple_scalars):
+ """Converts an ASCII representation of a protocol message into a 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".
+
+ Raises:
+ ParseError: On ASCII parsing problems.
+ """
+ tokenizer = _Tokenizer(lines)
+ while not tokenizer.AtEnd():
+ _MergeField(tokenizer, message, allow_multiple_scalars)
+
+
+def Parse(text, message):
+ """Parses an ASCII representation of a protocol message into a message.
+
+ Args:
+ text: Message ASCII representation.
+ message: A protocol buffer message to merge into.
+
+ Returns:
+ The same message passed as argument.
+
+ Raises:
+ ParseError: On ASCII parsing problems.
+ """
+ if not isinstance(text, str): text = text.decode('utf-8')
+ return ParseLines(text.split('\n'), message)
+
+
def Merge(text, message):
- """Merges an ASCII representation of a protocol message into a message.
+ """Parses an ASCII 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.
message: A protocol buffer message to merge into.
+ Returns:
+ The same message passed as argument.
+
Raises:
ParseError: On ASCII parsing problems.
"""
- tokenizer = _Tokenizer(text)
- while not tokenizer.AtEnd():
- _MergeField(tokenizer, message)
+ return MergeLines(text.split('\n'), message)
+
+
+def ParseLines(lines, message):
+ """Parses an ASCII representation of a protocol message into a message.
+
+ Args:
+ lines: An iterable of lines of a message's ASCII representation.
+ message: A protocol buffer message to merge into.
+
+ Returns:
+ The same message passed as argument.
+
+ Raises:
+ ParseError: On ASCII parsing problems.
+ """
+ _ParseOrMerge(lines, message, False)
+ return message
+
+
+def MergeLines(lines, message):
+ """Parses an ASCII representation of a protocol message into a message.
+
+ Args:
+ lines: An iterable of lines of a message's ASCII representation.
+ message: A protocol buffer message to merge into.
+
+ Returns:
+ The same message passed as argument.
+ Raises:
+ ParseError: On ASCII parsing problems.
+ """
+ _ParseOrMerge(lines, message, True)
+ return message
-def _MergeField(tokenizer, message):
+
+def _MergeField(tokenizer, message, allow_multiple_scalars):
"""Merges a single protocol message field into a message.
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".
Raises:
ParseError: In case of ASCII parsing problems.
@@ -159,7 +323,9 @@ def _MergeField(tokenizer, message):
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)
@@ -208,23 +374,31 @@ def _MergeField(tokenizer, message):
sub_message = message.Extensions[field]
else:
sub_message = getattr(message, field.name)
- sub_message.SetInParent()
+ sub_message.SetInParent()
while not tokenizer.TryConsume(end_token):
if tokenizer.AtEnd():
raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token))
- _MergeField(tokenizer, sub_message)
+ _MergeField(tokenizer, sub_message, allow_multiple_scalars)
else:
- _MergeScalarField(tokenizer, message, field)
+ _MergeScalarField(tokenizer, message, field, allow_multiple_scalars)
+
+ # For historical reasons, fields may optionally be separated by commas or
+ # semicolons.
+ if not tokenizer.TryConsume(','):
+ tokenizer.TryConsume(';')
-def _MergeScalarField(tokenizer, message, field):
+def _MergeScalarField(tokenizer, message, field, allow_multiple_scalars):
"""Merges a single protocol message 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.
+ 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".
Raises:
ParseError: In case of ASCII parsing problems.
@@ -257,24 +431,7 @@ def _MergeScalarField(tokenizer, message, field):
elif field.type == descriptor.FieldDescriptor.TYPE_BYTES:
value = tokenizer.ConsumeByteString()
elif field.type == descriptor.FieldDescriptor.TYPE_ENUM:
- # Enum can be specified by a number (the enum value), or by
- # a string literal (the enum name).
- enum_descriptor = field.enum_type
- if tokenizer.LookingAtInteger():
- number = tokenizer.ConsumeInt32()
- enum_value = enum_descriptor.values_by_number.get(number, None)
- if enum_value is None:
- raise tokenizer.ParseErrorPreviousToken(
- 'Enum type "%s" has no value with number %d.' % (
- enum_descriptor.full_name, number))
- else:
- identifier = tokenizer.ConsumeIdentifier()
- enum_value = enum_descriptor.values_by_name.get(identifier, None)
- if enum_value is None:
- raise tokenizer.ParseErrorPreviousToken(
- 'Enum type "%s" has no value named %s.' % (
- enum_descriptor.full_name, identifier))
- value = enum_value.number
+ value = tokenizer.ConsumeEnum(field)
else:
raise RuntimeError('Unknown field type %d' % field.type)
@@ -285,9 +442,19 @@ def _MergeScalarField(tokenizer, message, field):
getattr(message, field.name).append(value)
else:
if field.is_extension:
- message.Extensions[field] = value
+ 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:
- setattr(message, field.name, value)
+ 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)
class _Tokenizer(object):
@@ -305,26 +472,19 @@ class _Tokenizer(object):
'[0-9+-][0-9a-zA-Z_.+-]*|' # a number
'\"([^\"\n\\\\]|\\\\.)*(\"|\\\\?$)|' # a double-quoted string
'\'([^\'\n\\\\]|\\\\.)*(\'|\\\\?$)') # a single-quoted string
- _IDENTIFIER = re.compile('\w+')
- _INTEGER_CHECKERS = [type_checkers.Uint32ValueChecker(),
- type_checkers.Int32ValueChecker(),
- type_checkers.Uint64ValueChecker(),
- type_checkers.Int64ValueChecker()]
- _FLOAT_INFINITY = re.compile('-?inf(inity)?f?', re.IGNORECASE)
- _FLOAT_NAN = re.compile("nanf?", re.IGNORECASE)
-
- def __init__(self, text_message):
- self._text_message = text_message
+ _IDENTIFIER = re.compile(r'\w+')
+ def __init__(self, lines):
self._position = 0
self._line = -1
self._column = 0
self._token_start = None
self.token = ''
- self._lines = deque(text_message.split('\n'))
+ self._lines = iter(lines)
self._current_line = ''
self._previous_line = 0
self._previous_column = 0
+ self._more_lines = True
self._SkipWhitespace()
self.NextToken()
@@ -334,25 +494,27 @@ class _Tokenizer(object):
Returns:
True iff the end was reached.
"""
- return not self._lines and not self._current_line
+ return not self.token
def _PopLine(self):
- while not self._current_line:
- if not self._lines:
+ while len(self._current_line) <= self._column:
+ try:
+ self._current_line = self._lines.next()
+ except StopIteration:
self._current_line = ''
+ self._more_lines = False
return
- self._line += 1
- self._column = 0
- self._current_line = self._lines.popleft()
+ else:
+ self._line += 1
+ self._column = 0
def _SkipWhitespace(self):
while True:
self._PopLine()
- match = re.match(self._WHITESPACE, self._current_line)
+ match = self._WHITESPACE.match(self._current_line, self._column)
if not match:
break
length = len(match.group(0))
- self._current_line = self._current_line[length:]
self._column += length
def TryConsume(self, token):
@@ -381,17 +543,6 @@ class _Tokenizer(object):
if not self.TryConsume(token):
raise self._ParseError('Expected "%s".' % token)
- def LookingAtInteger(self):
- """Checks if the current token is an integer.
-
- Returns:
- True iff the current token is an integer.
- """
- if not self.token:
- return False
- c = self.token[0]
- return (c >= '0' and c <= '9') or c == '-' or c == '+'
-
def ConsumeIdentifier(self):
"""Consumes protocol message field identifier.
@@ -402,7 +553,7 @@ class _Tokenizer(object):
ParseError: If an identifier couldn't be consumed.
"""
result = self.token
- if not re.match(self._IDENTIFIER, result):
+ if not self._IDENTIFIER.match(result):
raise self._ParseError('Expected identifier.')
self.NextToken()
return result
@@ -417,9 +568,9 @@ class _Tokenizer(object):
ParseError: If a signed 32bit integer couldn't be consumed.
"""
try:
- result = self._ParseInteger(self.token, is_signed=True, is_long=False)
+ result = ParseInteger(self.token, is_signed=True, is_long=False)
except ValueError, e:
- raise self._IntegerParseError(e)
+ raise self._ParseError(str(e))
self.NextToken()
return result
@@ -433,9 +584,9 @@ class _Tokenizer(object):
ParseError: If an unsigned 32bit integer couldn't be consumed.
"""
try:
- result = self._ParseInteger(self.token, is_signed=False, is_long=False)
+ result = ParseInteger(self.token, is_signed=False, is_long=False)
except ValueError, e:
- raise self._IntegerParseError(e)
+ raise self._ParseError(str(e))
self.NextToken()
return result
@@ -449,9 +600,9 @@ class _Tokenizer(object):
ParseError: If a signed 64bit integer couldn't be consumed.
"""
try:
- result = self._ParseInteger(self.token, is_signed=True, is_long=True)
+ result = ParseInteger(self.token, is_signed=True, is_long=True)
except ValueError, e:
- raise self._IntegerParseError(e)
+ raise self._ParseError(str(e))
self.NextToken()
return result
@@ -465,9 +616,9 @@ class _Tokenizer(object):
ParseError: If an unsigned 64bit integer couldn't be consumed.
"""
try:
- result = self._ParseInteger(self.token, is_signed=False, is_long=True)
+ result = ParseInteger(self.token, is_signed=False, is_long=True)
except ValueError, e:
- raise self._IntegerParseError(e)
+ raise self._ParseError(str(e))
self.NextToken()
return result
@@ -480,21 +631,10 @@ class _Tokenizer(object):
Raises:
ParseError: If a floating point number couldn't be consumed.
"""
- text = self.token
- if re.match(self._FLOAT_INFINITY, text):
- self.NextToken()
- if text.startswith('-'):
- return -_INFINITY
- return _INFINITY
-
- if re.match(self._FLOAT_NAN, text):
- self.NextToken()
- return _NAN
-
try:
- result = float(text)
+ result = ParseFloat(self.token)
except ValueError, e:
- raise self._FloatParseError(e)
+ raise self._ParseError(str(e))
self.NextToken()
return result
@@ -507,14 +647,12 @@ class _Tokenizer(object):
Raises:
ParseError: If a boolean value couldn't be consumed.
"""
- if self.token == 'true':
- self.NextToken()
- return True
- elif self.token == 'false':
- self.NextToken()
- return False
- else:
- raise self._ParseError('Expected "true" or "false".')
+ try:
+ result = ParseBool(self.token)
+ except ValueError, e:
+ raise self._ParseError(str(e))
+ self.NextToken()
+ return result
def ConsumeString(self):
"""Consumes a string value.
@@ -525,7 +663,11 @@ class _Tokenizer(object):
Raises:
ParseError: If a string value couldn't be consumed.
"""
- return unicode(self.ConsumeByteString(), 'utf-8')
+ the_bytes = self.ConsumeByteString()
+ try:
+ return unicode(the_bytes, 'utf-8')
+ except UnicodeDecodeError, e:
+ raise self._StringParseError(e)
def ConsumeByteString(self):
"""Consumes a byte array value.
@@ -536,10 +678,11 @@ class _Tokenizer(object):
Raises:
ParseError: If a byte array value couldn't be consumed.
"""
- list = [self._ConsumeSingleByteString()]
- while len(self.token) > 0 and self.token[0] in ('\'', '"'):
- list.append(self._ConsumeSingleByteString())
- return "".join(list)
+ the_list = [self._ConsumeSingleByteString()]
+ while self.token and self.token[0] in ('\'', '"'):
+ the_list.append(self._ConsumeSingleByteString())
+ return ''.encode('latin1').join(the_list) ##PY25
+##!PY25 return b''.join(the_list)
def _ConsumeSingleByteString(self):
"""Consume one token of a string literal.
@@ -550,48 +693,24 @@ class _Tokenizer(object):
"""
text = self.token
if len(text) < 1 or text[0] not in ('\'', '"'):
- raise self._ParseError('Exptected string.')
+ raise self._ParseError('Expected string.')
if len(text) < 2 or text[-1] != text[0]:
raise self._ParseError('String missing ending quote.')
try:
- result = _CUnescape(text[1:-1])
+ result = text_encoding.CUnescape(text[1:-1])
except ValueError, e:
raise self._ParseError(str(e))
self.NextToken()
return result
- def _ParseInteger(self, text, is_signed=False, is_long=False):
- """Parses an integer.
-
- Args:
- text: The text to parse.
- is_signed: True if a signed integer must be parsed.
- is_long: True if a long integer must be parsed.
-
- Returns:
- The integer value.
-
- Raises:
- ValueError: Thrown Iff the text is not a valid integer.
- """
- pos = 0
- if text.startswith('-'):
- pos += 1
-
- base = 10
- if text.startswith('0x', pos) or text.startswith('0X', pos):
- base = 16
- elif text.startswith('0', pos):
- base = 8
-
- # Do the actual parsing. Exception handling is propagated to caller.
- result = int(text, base)
-
- # Check if the integer is sane. Exceptions handled by callers.
- checker = self._INTEGER_CHECKERS[2 * int(is_long) + int(is_signed)]
- checker.CheckValue(result)
+ def ConsumeEnum(self, field):
+ try:
+ result = ParseEnum(field, self.token)
+ except ValueError, e:
+ raise self._ParseError(str(e))
+ self.NextToken()
return result
def ParseErrorPreviousToken(self, message):
@@ -611,63 +730,144 @@ class _Tokenizer(object):
return ParseError('%d:%d : %s' % (
self._line + 1, self._column + 1, message))
- def _IntegerParseError(self, e):
- return self._ParseError('Couldn\'t parse integer: ' + str(e))
-
- def _FloatParseError(self, e):
- return self._ParseError('Couldn\'t parse number: ' + str(e))
+ def _StringParseError(self, e):
+ return self._ParseError('Couldn\'t parse string: ' + str(e))
def NextToken(self):
"""Reads the next meaningful token."""
self._previous_line = self._line
self._previous_column = self._column
- if self.AtEnd():
- self.token = ''
- return
+
self._column += len(self.token)
+ self._SkipWhitespace()
- # Make sure there is data to work on.
- self._PopLine()
+ if not self._more_lines:
+ self.token = ''
+ return
- match = re.match(self._TOKEN, self._current_line)
+ match = self._TOKEN.match(self._current_line, self._column)
if match:
token = match.group(0)
- self._current_line = self._current_line[len(token):]
self.token = token
else:
- self.token = self._current_line[0]
- self._current_line = self._current_line[1:]
- self._SkipWhitespace()
+ self.token = self._current_line[self._column]
+
+
+def ParseInteger(text, is_signed=False, is_long=False):
+ """Parses an integer.
+
+ Args:
+ text: The text to parse.
+ is_signed: True if a signed integer must be parsed.
+ is_long: True if a long integer must be parsed.
+
+ 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)
+ else:
+ result = 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.
+
+ Args:
+ text: Text to parse.
+ Returns:
+ The number parsed.
-# text.encode('string_escape') does not seem to satisfy our needs as it
-# encodes unprintable characters using two-digit hex escapes whereas our
-# C++ unescaping function allows hex escapes to be any length. So,
-# "\0011".encode('string_escape') ends up being "\\x011", which will be
-# decoded in C++ as a single-character string with char code 0x11.
-def _CEscape(text):
- def escape(c):
- o = ord(c)
- if o == 10: return r"\n" # optional escape
- if o == 13: return r"\r" # optional escape
- if o == 9: return r"\t" # optional escape
- if o == 39: return r"\'" # optional escape
+ Raises:
+ ValueError: If a floating point number couldn't be parsed.
+ """
+ try:
+ # Assume Python compatible syntax.
+ return float(text)
+ except ValueError:
+ # Check alternative spellings.
+ if _FLOAT_INFINITY.match(text):
+ if text[0] == '-':
+ return float('-inf')
+ else:
+ return float('inf')
+ elif _FLOAT_NAN.match(text):
+ return float('nan')
+ else:
+ # assume '1.0f' format
+ try:
+ return float(text.rstrip('f'))
+ except ValueError:
+ raise ValueError('Couldn\'t parse float: %s' % text)
+
+
+def ParseBool(text):
+ """Parse a boolean value.
+
+ Args:
+ text: Text to parse.
+
+ Returns:
+ Boolean values parsed
- if o == 34: return r'\"' # necessary escape
- if o == 92: return r"\\" # necessary escape
+ Raises:
+ ValueError: If text is not a valid boolean.
+ """
+ if text in ('true', 't', '1'):
+ return True
+ elif text in ('false', 'f', '0'):
+ return False
+ else:
+ raise ValueError('Expected "true" or "false".')
- if o >= 127 or o < 32: return "\\%03o" % o # necessary escapes
- return c
- return "".join([escape(c) for c in text])
+def ParseEnum(field, value):
+ """Parse an enum value.
-_CUNESCAPE_HEX = re.compile('\\\\x([0-9a-fA-F]{2}|[0-9a-f-A-F])')
+ The value can be specified by a number (the enum value), or by
+ a string literal (the enum name).
+ Args:
+ field: Enum field descriptor.
+ value: String value.
-def _CUnescape(text):
- def ReplaceHex(m):
- return chr(int(m.group(0)[2:], 16))
- # This is required because the 'string_escape' encoding doesn't
- # allow single-digit hex escapes (like '\xf').
- result = _CUNESCAPE_HEX.sub(ReplaceHex, text)
- return result.decode('string_escape')
+ Returns:
+ Enum value number.
+
+ Raises:
+ ValueError: If the enum value could not be parsed.
+ """
+ enum_descriptor = field.enum_type
+ try:
+ number = int(value, 0)
+ except ValueError:
+ # 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))
+ 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))
+ return enum_value.number
diff --git a/python/setup.py b/python/setup.py
index 7242dae..2450a77 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -1,25 +1,41 @@
#! /usr/bin/python
#
# See README for usage instructions.
+import sys
+import os
+import subprocess
# We must use setuptools, not distutils, because we need to use the
# namespace_packages option for the "google" package.
-from ez_setup import use_setuptools
-use_setuptools()
-
-from setuptools import setup
+try:
+ from setuptools import setup, Extension
+except ImportError:
+ try:
+ from ez_setup import use_setuptools
+ use_setuptools()
+ from setuptools import setup, Extension
+ except ImportError:
+ sys.stderr.write(
+ "Could not import setuptools; make sure you have setuptools or "
+ "ez_setup installed.\n")
+ raise
+from distutils.command.clean import clean as _clean
+from distutils.command.build_py import build_py as _build_py
from distutils.spawn import find_executable
-import sys
-import os
-import subprocess
maintainer_email = "protobuf@googlegroups.com"
# Find the Protocol Compiler.
-if os.path.exists("../src/protoc"):
+if 'PROTOC' in os.environ and os.path.exists(os.environ['PROTOC']):
+ protoc = os.environ['PROTOC']
+elif os.path.exists("../src/protoc"):
protoc = "../src/protoc"
elif os.path.exists("../src/protoc.exe"):
protoc = "../src/protoc.exe"
+elif os.path.exists("../vsprojects/Debug/protoc.exe"):
+ protoc = "../vsprojects/Debug/protoc.exe"
+elif os.path.exists("../vsprojects/Release/protoc.exe"):
+ protoc = "../vsprojects/Release/protoc.exe"
else:
protoc = find_executable("protoc")
@@ -30,14 +46,14 @@ def generate_proto(source):
output = source.replace(".proto", "_pb2.py").replace("../src/", "")
- if not os.path.exists(source):
- print "Can't find required file: " + source
- sys.exit(-1)
-
if (not os.path.exists(output) or
(os.path.exists(source) and
os.path.getmtime(source) > os.path.getmtime(output))):
- print "Generating %s..." % output
+ print ("Generating %s..." % output)
+
+ if not os.path.exists(source):
+ sys.stderr.write("Can't find required file: %s\n" % source)
+ sys.exit(-1)
if protoc == None:
sys.stderr.write(
@@ -49,75 +65,133 @@ def generate_proto(source):
if subprocess.call(protoc_command) != 0:
sys.exit(-1)
-def MakeTestSuite():
- # This is apparently needed on some systems to make sure that the tests
- # work even if a previous version is already installed.
- if 'google' in sys.modules:
- del sys.modules['google']
-
+def GenerateUnittestProtos():
generate_proto("../src/google/protobuf/unittest.proto")
+ generate_proto("../src/google/protobuf/unittest_custom_options.proto")
generate_proto("../src/google/protobuf/unittest_import.proto")
+ generate_proto("../src/google/protobuf/unittest_import_public.proto")
generate_proto("../src/google/protobuf/unittest_mset.proto")
generate_proto("../src/google/protobuf/unittest_no_generic_services.proto")
+ generate_proto("google/protobuf/internal/descriptor_pool_test1.proto")
+ generate_proto("google/protobuf/internal/descriptor_pool_test2.proto")
+ generate_proto("google/protobuf/internal/test_bad_identifiers.proto")
+ generate_proto("google/protobuf/internal/missing_enum_values.proto")
generate_proto("google/protobuf/internal/more_extensions.proto")
+ generate_proto("google/protobuf/internal/more_extensions_dynamic.proto")
generate_proto("google/protobuf/internal/more_messages.proto")
+ generate_proto("google/protobuf/internal/factory_test1.proto")
+ generate_proto("google/protobuf/internal/factory_test2.proto")
+ generate_proto("google/protobuf/pyext/python.proto")
+def MakeTestSuite():
+ # Test C++ implementation
import unittest
- import google.protobuf.internal.generator_test as generator_test
- import google.protobuf.internal.descriptor_test as descriptor_test
- import google.protobuf.internal.reflection_test as reflection_test
- import google.protobuf.internal.service_reflection_test \
- as service_reflection_test
- import google.protobuf.internal.text_format_test as text_format_test
- import google.protobuf.internal.wire_format_test as wire_format_test
+ import google.protobuf.pyext.descriptor_cpp2_test as descriptor_cpp2_test
+ import google.protobuf.pyext.message_factory_cpp2_test \
+ as message_factory_cpp2_test
+ import google.protobuf.pyext.reflection_cpp2_generated_test \
+ as reflection_cpp2_generated_test
loader = unittest.defaultTestLoader
suite = unittest.TestSuite()
- for test in [ generator_test,
- descriptor_test,
- reflection_test,
- service_reflection_test,
- text_format_test,
- wire_format_test ]:
+ for test in [ descriptor_cpp2_test,
+ message_factory_cpp2_test,
+ reflection_cpp2_generated_test]:
suite.addTest(loader.loadTestsFromModule(test))
-
return suite
-if __name__ == '__main__':
- # TODO(kenton): Integrate this into setuptools somehow?
- if len(sys.argv) >= 2 and sys.argv[1] == "clean":
- # Delete generated _pb2.py files and .pyc files in the code tree.
+class clean(_clean):
+ def run(self):
+ # Delete generated files in the code tree.
for (dirpath, dirnames, filenames) in os.walk("."):
for filename in filenames:
filepath = os.path.join(dirpath, filename)
- if filepath.endswith("_pb2.py") or filepath.endswith(".pyc"):
+ 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'):
os.remove(filepath)
- else:
+ # _clean is an old-style class, so super() doesn't work.
+ _clean.run(self)
+
+class build_py(_build_py):
+ def run(self):
# Generate necessary .proto file if it doesn't exist.
- # TODO(kenton): Maybe we should hook this into a distutils command?
generate_proto("../src/google/protobuf/descriptor.proto")
+ generate_proto("../src/google/protobuf/compiler/plugin.proto")
+ GenerateUnittestProtos()
+
+ # Make sure google.protobuf/** are valid packages.
+ for path in ['', 'internal/', 'compiler/', 'pyext/']:
+ try:
+ open('google/protobuf/%s__init__.py' % path, 'a').close()
+ except EnvironmentError:
+ pass
+ # _build_py is an old-style class, so super() doesn't work.
+ _build_py.run(self)
+ # TODO(mrovner): Subclass to run 2to3 on some files only.
+ # Tracing what https://wiki.python.org/moin/PortingPythonToPy3k's "Approach 2"
+ # section on how to get 2to3 to run on source files during install under
+ # Python 3. This class seems like a good place to put logic that calls
+ # python3's distutils.util.run_2to3 on the subset of the files we have in our
+ # release that are subject to conversion.
+ # See code reference in previous code review.
+
+if __name__ == '__main__':
+ ext_module_list = []
+ cpp_impl = '--cpp_implementation'
+ if cpp_impl in sys.argv:
+ sys.argv.remove(cpp_impl)
+ # C++ implementation extension
+ ext_module_list.append(Extension(
+ "google.protobuf.pyext._message",
+ [ "google/protobuf/pyext/descriptor.cc",
+ "google/protobuf/pyext/message.cc",
+ "google/protobuf/pyext/extension_dict.cc",
+ "google/protobuf/pyext/repeated_scalar_container.cc",
+ "google/protobuf/pyext/repeated_composite_container.cc" ],
+ define_macros=[('GOOGLE_PROTOBUF_HAS_ONEOF', '1')],
+ include_dirs = [ ".", "../src"],
+ libraries = [ "protobuf" ],
+ library_dirs = [ '../src/.libs' ],
+ ))
setup(name = 'protobuf',
- version = '2.3.0',
+ version = '2.6.1',
packages = [ 'google' ],
namespace_packages = [ 'google' ],
test_suite = 'setup.MakeTestSuite',
+ google_test_dir = "google/protobuf/internal",
# Must list modules explicitly so that we don't install tests.
py_modules = [
+ 'google.protobuf.internal.api_implementation',
'google.protobuf.internal.containers',
+ 'google.protobuf.internal.cpp_message',
'google.protobuf.internal.decoder',
'google.protobuf.internal.encoder',
+ 'google.protobuf.internal.enum_type_wrapper',
'google.protobuf.internal.message_listener',
+ 'google.protobuf.internal.python_message',
'google.protobuf.internal.type_checkers',
'google.protobuf.internal.wire_format',
'google.protobuf.descriptor',
'google.protobuf.descriptor_pb2',
+ 'google.protobuf.compiler.plugin_pb2',
'google.protobuf.message',
+ 'google.protobuf.descriptor_database',
+ 'google.protobuf.descriptor_pool',
+ 'google.protobuf.message_factory',
+ 'google.protobuf.pyext.cpp_message',
'google.protobuf.reflection',
'google.protobuf.service',
'google.protobuf.service_reflection',
- 'google.protobuf.text_format' ],
- url = 'http://code.google.com/p/protobuf/',
+ 'google.protobuf.symbol_database',
+ 'google.protobuf.text_encoding',
+ 'google.protobuf.text_format'],
+ cmdclass = { 'clean': clean, 'build_py': build_py },
+ install_requires = ['setuptools'],
+ setup_requires = ['google-apputils'],
+ ext_modules = ext_module_list,
+ url = 'https://developers.google.com/protocol-buffers/',
maintainer = maintainer_email,
maintainer_email = 'protobuf@googlegroups.com',
license = 'New BSD License',
diff --git a/src/Makefile.am b/src/Makefile.am
index 4f82baf..7baabbd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -37,56 +37,77 @@ CLEANFILES = $(protoc_outputs) unittest_proto_middleman \
MAINTAINERCLEANFILES = \
Makefile.in
-nobase_include_HEADERS = \
- google/protobuf/stubs/common.h \
- google/protobuf/stubs/once.h \
- google/protobuf/descriptor.h \
- google/protobuf/descriptor.pb.h \
- google/protobuf/descriptor_database.h \
- google/protobuf/dynamic_message.h \
- google/protobuf/extension_set.h \
- google/protobuf/generated_message_util.h \
- google/protobuf/generated_message_reflection.h \
- google/protobuf/message.h \
- google/protobuf/message_lite.h \
- google/protobuf/reflection_ops.h \
- google/protobuf/repeated_field.h \
- google/protobuf/service.h \
- google/protobuf/text_format.h \
- google/protobuf/unknown_field_set.h \
- google/protobuf/wire_format.h \
- google/protobuf/wire_format_lite.h \
- google/protobuf/wire_format_lite_inl.h \
- google/protobuf/io/coded_stream.h \
- $(GZHEADERS) \
- google/protobuf/io/printer.h \
- google/protobuf/io/tokenizer.h \
- google/protobuf/io/zero_copy_stream.h \
- google/protobuf/io/zero_copy_stream_impl.h \
- google/protobuf/io/zero_copy_stream_impl_lite.h \
- google/protobuf/compiler/code_generator.h \
- google/protobuf/compiler/command_line_interface.h \
- google/protobuf/compiler/importer.h \
- google/protobuf/compiler/parser.h \
- google/protobuf/compiler/plugin.h \
- google/protobuf/compiler/plugin.pb.h \
- google/protobuf/compiler/cpp/cpp_generator.h \
- google/protobuf/compiler/java/java_generator.h \
- google/protobuf/compiler/javamicro/javamicro_generator.h \
- google/protobuf/compiler/javanano/javanano_generator.h \
+nobase_include_HEADERS = \
+ google/protobuf/stubs/atomicops.h \
+ google/protobuf/stubs/atomicops_internals_arm_gcc.h \
+ google/protobuf/stubs/atomicops_internals_arm64_gcc.h \
+ google/protobuf/stubs/atomicops_internals_arm_qnx.h \
+ google/protobuf/stubs/atomicops_internals_atomicword_compat.h \
+ google/protobuf/stubs/atomicops_internals_generic_gcc.h \
+ google/protobuf/stubs/atomicops_internals_macosx.h \
+ google/protobuf/stubs/atomicops_internals_mips_gcc.h \
+ google/protobuf/stubs/atomicops_internals_pnacl.h \
+ google/protobuf/stubs/atomicops_internals_tsan.h \
+ google/protobuf/stubs/atomicops_internals_x86_gcc.h \
+ google/protobuf/stubs/atomicops_internals_x86_msvc.h \
+ google/protobuf/stubs/common.h \
+ google/protobuf/stubs/platform_macros.h \
+ google/protobuf/stubs/once.h \
+ google/protobuf/stubs/stl_util.h \
+ google/protobuf/stubs/template_util.h \
+ google/protobuf/stubs/type_traits.h \
+ google/protobuf/descriptor.h \
+ google/protobuf/descriptor.pb.h \
+ google/protobuf/descriptor_database.h \
+ google/protobuf/dynamic_message.h \
+ google/protobuf/extension_set.h \
+ google/protobuf/generated_enum_reflection.h \
+ google/protobuf/generated_message_util.h \
+ google/protobuf/generated_message_reflection.h \
+ google/protobuf/message.h \
+ google/protobuf/message_lite.h \
+ google/protobuf/reflection_ops.h \
+ google/protobuf/repeated_field.h \
+ google/protobuf/service.h \
+ google/protobuf/text_format.h \
+ google/protobuf/unknown_field_set.h \
+ google/protobuf/wire_format.h \
+ google/protobuf/wire_format_lite.h \
+ google/protobuf/wire_format_lite_inl.h \
+ google/protobuf/io/coded_stream.h \
+ $(GZHEADERS) \
+ google/protobuf/io/printer.h \
+ google/protobuf/io/strtod.h \
+ google/protobuf/io/tokenizer.h \
+ google/protobuf/io/zero_copy_stream.h \
+ google/protobuf/io/zero_copy_stream_impl.h \
+ google/protobuf/io/zero_copy_stream_impl_lite.h \
+ google/protobuf/compiler/code_generator.h \
+ google/protobuf/compiler/command_line_interface.h \
+ google/protobuf/compiler/importer.h \
+ google/protobuf/compiler/parser.h \
+ google/protobuf/compiler/plugin.h \
+ google/protobuf/compiler/plugin.pb.h \
+ google/protobuf/compiler/cpp/cpp_generator.h \
+ google/protobuf/compiler/java/java_generator.h \
+ google/protobuf/compiler/javamicro/javamicro_generator.h \
+ google/protobuf/compiler/javanano/javanano_generator.h \
google/protobuf/compiler/python/python_generator.h
lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la
libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS)
-libprotobuf_lite_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined
+libprotobuf_lite_la_LDFLAGS = -version-info 9:1:0 -export-dynamic -no-undefined
libprotobuf_lite_la_SOURCES = \
+ google/protobuf/stubs/atomicops_internals_x86_gcc.cc \
+ google/protobuf/stubs/atomicops_internals_x86_msvc.cc \
google/protobuf/stubs/common.cc \
google/protobuf/stubs/once.cc \
- google/protobuf/stubs/hash.cc \
google/protobuf/stubs/hash.h \
- google/protobuf/stubs/map-util.h \
- google/protobuf/stubs/stl_util-inl.h \
+ google/protobuf/stubs/map_util.h \
+ google/protobuf/stubs/shared_ptr.h \
+ google/protobuf/stubs/stringprintf.cc \
+ google/protobuf/stubs/stringprintf.h \
google/protobuf/extension_set.cc \
google/protobuf/generated_message_util.cc \
google/protobuf/message_lite.cc \
@@ -98,7 +119,7 @@ libprotobuf_lite_la_SOURCES = \
google/protobuf/io/zero_copy_stream_impl_lite.cc
libprotobuf_la_LIBADD = $(PTHREAD_LIBS)
-libprotobuf_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined
+libprotobuf_la_LDFLAGS = -version-info 9:1:0 -export-dynamic -no-undefined
libprotobuf_la_SOURCES = \
$(libprotobuf_lite_la_SOURCES) \
google/protobuf/stubs/strutil.cc \
@@ -120,13 +141,14 @@ libprotobuf_la_SOURCES = \
google/protobuf/wire_format.cc \
google/protobuf/io/gzip_stream.cc \
google/protobuf/io/printer.cc \
+ google/protobuf/io/strtod.cc \
google/protobuf/io/tokenizer.cc \
google/protobuf/io/zero_copy_stream_impl.cc \
google/protobuf/compiler/importer.cc \
google/protobuf/compiler/parser.cc
libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la
-libprotoc_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined
+libprotoc_la_LDFLAGS = -version-info 9:1:0 -export-dynamic -no-undefined
libprotoc_la_SOURCES = \
google/protobuf/compiler/code_generator.cc \
google/protobuf/compiler/command_line_interface.cc \
@@ -153,12 +175,15 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/cpp/cpp_message.h \
google/protobuf/compiler/cpp/cpp_message_field.cc \
google/protobuf/compiler/cpp/cpp_message_field.h \
+ google/protobuf/compiler/cpp/cpp_options.h \
google/protobuf/compiler/cpp/cpp_primitive_field.cc \
google/protobuf/compiler/cpp/cpp_primitive_field.h \
google/protobuf/compiler/cpp/cpp_service.cc \
google/protobuf/compiler/cpp/cpp_service.h \
google/protobuf/compiler/cpp/cpp_string_field.cc \
google/protobuf/compiler/cpp/cpp_string_field.h \
+ google/protobuf/compiler/java/java_context.cc \
+ google/protobuf/compiler/java/java_context.h \
google/protobuf/compiler/java/java_enum.cc \
google/protobuf/compiler/java/java_enum.h \
google/protobuf/compiler/java/java_enum_field.cc \
@@ -170,16 +195,28 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/java/java_file.cc \
google/protobuf/compiler/java/java_file.h \
google/protobuf/compiler/java/java_generator.cc \
+ google/protobuf/compiler/java/java_generator_factory.cc \
+ google/protobuf/compiler/java/java_generator_factory.h \
google/protobuf/compiler/java/java_helpers.cc \
google/protobuf/compiler/java/java_helpers.h \
+ google/protobuf/compiler/java/java_lazy_message_field.cc \
+ google/protobuf/compiler/java/java_lazy_message_field.h \
google/protobuf/compiler/java/java_message.cc \
google/protobuf/compiler/java/java_message.h \
google/protobuf/compiler/java/java_message_field.cc \
google/protobuf/compiler/java/java_message_field.h \
+ google/protobuf/compiler/java/java_name_resolver.cc \
+ google/protobuf/compiler/java/java_name_resolver.h \
google/protobuf/compiler/java/java_primitive_field.cc \
google/protobuf/compiler/java/java_primitive_field.h \
+ google/protobuf/compiler/java/java_shared_code_generator.cc \
+ google/protobuf/compiler/java/java_shared_code_generator.h \
google/protobuf/compiler/java/java_service.cc \
google/protobuf/compiler/java/java_service.h \
+ google/protobuf/compiler/java/java_string_field.cc \
+ google/protobuf/compiler/java/java_string_field.h \
+ google/protobuf/compiler/java/java_doc_comment.cc \
+ google/protobuf/compiler/java/java_doc_comment.h \
google/protobuf/compiler/javamicro/javamicro_enum.cc \
google/protobuf/compiler/javamicro/javamicro_enum.h \
google/protobuf/compiler/javamicro/javamicro_enum_field.cc \
@@ -228,12 +265,14 @@ protoc_inputs = \
google/protobuf/unittest.proto \
google/protobuf/unittest_empty.proto \
google/protobuf/unittest_import.proto \
+ google/protobuf/unittest_import_public.proto \
google/protobuf/unittest_mset.proto \
google/protobuf/unittest_optimize_for.proto \
google/protobuf/unittest_embed_optimize_for.proto \
google/protobuf/unittest_custom_options.proto \
google/protobuf/unittest_lite.proto \
google/protobuf/unittest_import_lite.proto \
+ google/protobuf/unittest_import_public_lite.proto \
google/protobuf/unittest_lite_imports_nonlite.proto \
google/protobuf/unittest_no_generic_services.proto \
google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
@@ -244,9 +283,15 @@ 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_oneof_implemented \
google/protobuf/testdata/golden_packed_fields_message \
+ google/protobuf/testdata/bad_utf8_string \
google/protobuf/testdata/text_format_unittest_data.txt \
- google/protobuf/testdata/text_format_unittest_extensions_data.txt \
+ google/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt \
+ google/protobuf/testdata/text_format_unittest_data_pointy.txt \
+ google/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt \
+ google/protobuf/testdata/text_format_unittest_extensions_data.txt \
+ google/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt \
google/protobuf/package_info.h \
google/protobuf/io/package_info.h \
google/protobuf/compiler/package_info.h \
@@ -257,7 +302,9 @@ protoc_lite_outputs = \
google/protobuf/unittest_lite.pb.cc \
google/protobuf/unittest_lite.pb.h \
google/protobuf/unittest_import_lite.pb.cc \
- google/protobuf/unittest_import_lite.pb.h
+ google/protobuf/unittest_import_lite.pb.h \
+ google/protobuf/unittest_import_public_lite.pb.cc \
+ google/protobuf/unittest_import_public_lite.pb.h
protoc_outputs = \
$(protoc_lite_outputs) \
@@ -267,6 +314,8 @@ protoc_outputs = \
google/protobuf/unittest_empty.pb.h \
google/protobuf/unittest_import.pb.cc \
google/protobuf/unittest_import.pb.h \
+ google/protobuf/unittest_import_public.pb.cc \
+ google/protobuf/unittest_import_public.pb.h \
google/protobuf/unittest_mset.pb.cc \
google/protobuf/unittest_mset.pb.h \
google/protobuf/unittest_optimize_for.pb.cc \
@@ -327,6 +376,9 @@ protobuf_test_SOURCES = \
google/protobuf/stubs/once_unittest.cc \
google/protobuf/stubs/strutil_unittest.cc \
google/protobuf/stubs/structurally_valid_unittest.cc \
+ google/protobuf/stubs/stringprintf_unittest.cc \
+ google/protobuf/stubs/template_util_unittest.cc \
+ google/protobuf/stubs/type_traits_unittest.cc \
google/protobuf/descriptor_database_unittest.cc \
google/protobuf/descriptor_unittest.cc \
google/protobuf/dynamic_message_unittest.cc \
@@ -335,6 +387,7 @@ protobuf_test_SOURCES = \
google/protobuf/message_unittest.cc \
google/protobuf/reflection_ops_unittest.cc \
google/protobuf/repeated_field_unittest.cc \
+ google/protobuf/repeated_field_reflection_unittest.cc \
google/protobuf/text_format_unittest.cc \
google/protobuf/unknown_field_set_unittest.cc \
google/protobuf/wire_format_unittest.cc \
@@ -348,16 +401,19 @@ protobuf_test_SOURCES = \
google/protobuf/compiler/mock_code_generator.h \
google/protobuf/compiler/parser_unittest.cc \
google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc \
+ 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/java/java_plugin_unittest.cc \
+ google/protobuf/compiler/java/java_doc_comment_unittest.cc \
google/protobuf/compiler/python/python_plugin_unittest.cc \
$(COMMON_TEST_SOURCES)
nodist_protobuf_test_SOURCES = $(protoc_outputs)
# Run cpp_unittest again with PROTOBUF_TEST_NO_DESCRIPTORS defined.
protobuf_lazy_descriptor_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la \
- $(top_builddir)/gtest/lib/libgtest.la \
+ libprotoc.la \
+ $(top_builddir)/gtest/lib/libgtest.la \
$(top_builddir)/gtest/lib/libgtest_main.la
protobuf_lazy_descriptor_test_CPPFLAGS = -I$(top_srcdir)/gtest/include \
-I$(top_builddir)/gtest/include \
diff --git a/src/Makefile.in b/src/Makefile.in
index 3896427..c6703bb 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -19,6 +18,51 @@
VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -48,9 +92,9 @@ TESTS = protobuf-test$(EXEEXT) protobuf-lazy-descriptor-test$(EXEEXT) \
google/protobuf/compiler/zip_output_unittest.sh \
$(am__EXEEXT_2)
subdir = src
-DIST_COMMON = $(am__nobase_include_HEADERS_DIST) \
- $(nobase_dist_proto_DATA) $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp $(nobase_dist_proto_DATA) \
+ $(am__nobase_include_HEADERS_DIST) $(top_srcdir)/test-driver
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ac_system_extensions.m4 \
$(top_srcdir)/m4/acx_check_suncc.m4 \
@@ -96,193 +140,315 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
libprotobuf_lite_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
-am_libprotobuf_lite_la_OBJECTS = common.lo once.lo hash.lo \
- extension_set.lo generated_message_util.lo message_lite.lo \
- repeated_field.lo wire_format_lite.lo coded_stream.lo \
- zero_copy_stream.lo zero_copy_stream_impl_lite.lo
+am__dirstamp = $(am__leading_dot)dirstamp
+am_libprotobuf_lite_la_OBJECTS = \
+ google/protobuf/stubs/atomicops_internals_x86_gcc.lo \
+ google/protobuf/stubs/atomicops_internals_x86_msvc.lo \
+ google/protobuf/stubs/common.lo google/protobuf/stubs/once.lo \
+ google/protobuf/stubs/stringprintf.lo \
+ google/protobuf/extension_set.lo \
+ google/protobuf/generated_message_util.lo \
+ google/protobuf/message_lite.lo \
+ google/protobuf/repeated_field.lo \
+ google/protobuf/wire_format_lite.lo \
+ google/protobuf/io/coded_stream.lo \
+ google/protobuf/io/zero_copy_stream.lo \
+ google/protobuf/io/zero_copy_stream_impl_lite.lo
libprotobuf_lite_la_OBJECTS = $(am_libprotobuf_lite_la_OBJECTS)
-libprotobuf_lite_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
- $(CXXFLAGS) $(libprotobuf_lite_la_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libprotobuf_lite_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+ $(AM_CXXFLAGS) $(CXXFLAGS) $(libprotobuf_lite_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
libprotobuf_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
-am__objects_1 = common.lo once.lo hash.lo extension_set.lo \
- generated_message_util.lo message_lite.lo repeated_field.lo \
- wire_format_lite.lo coded_stream.lo zero_copy_stream.lo \
- zero_copy_stream_impl_lite.lo
-am_libprotobuf_la_OBJECTS = $(am__objects_1) strutil.lo substitute.lo \
- structurally_valid.lo descriptor.lo descriptor.pb.lo \
- descriptor_database.lo dynamic_message.lo \
- extension_set_heavy.lo generated_message_reflection.lo \
- message.lo reflection_ops.lo service.lo text_format.lo \
- unknown_field_set.lo wire_format.lo gzip_stream.lo printer.lo \
- tokenizer.lo zero_copy_stream_impl.lo importer.lo parser.lo
+am__objects_1 = google/protobuf/stubs/atomicops_internals_x86_gcc.lo \
+ google/protobuf/stubs/atomicops_internals_x86_msvc.lo \
+ google/protobuf/stubs/common.lo google/protobuf/stubs/once.lo \
+ google/protobuf/stubs/stringprintf.lo \
+ google/protobuf/extension_set.lo \
+ google/protobuf/generated_message_util.lo \
+ google/protobuf/message_lite.lo \
+ google/protobuf/repeated_field.lo \
+ google/protobuf/wire_format_lite.lo \
+ google/protobuf/io/coded_stream.lo \
+ google/protobuf/io/zero_copy_stream.lo \
+ google/protobuf/io/zero_copy_stream_impl_lite.lo
+am_libprotobuf_la_OBJECTS = $(am__objects_1) \
+ google/protobuf/stubs/strutil.lo \
+ google/protobuf/stubs/substitute.lo \
+ google/protobuf/stubs/structurally_valid.lo \
+ google/protobuf/descriptor.lo google/protobuf/descriptor.pb.lo \
+ google/protobuf/descriptor_database.lo \
+ google/protobuf/dynamic_message.lo \
+ google/protobuf/extension_set_heavy.lo \
+ google/protobuf/generated_message_reflection.lo \
+ google/protobuf/message.lo google/protobuf/reflection_ops.lo \
+ google/protobuf/service.lo google/protobuf/text_format.lo \
+ google/protobuf/unknown_field_set.lo \
+ google/protobuf/wire_format.lo \
+ google/protobuf/io/gzip_stream.lo \
+ google/protobuf/io/printer.lo google/protobuf/io/strtod.lo \
+ google/protobuf/io/tokenizer.lo \
+ google/protobuf/io/zero_copy_stream_impl.lo \
+ google/protobuf/compiler/importer.lo \
+ google/protobuf/compiler/parser.lo
libprotobuf_la_OBJECTS = $(am_libprotobuf_la_OBJECTS)
-libprotobuf_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
- $(CXXFLAGS) $(libprotobuf_la_LDFLAGS) $(LDFLAGS) -o $@
+libprotobuf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+ $(AM_CXXFLAGS) $(CXXFLAGS) $(libprotobuf_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
libprotoc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la
-am_libprotoc_la_OBJECTS = code_generator.lo command_line_interface.lo \
- plugin.lo plugin.pb.lo subprocess.lo zip_writer.lo cpp_enum.lo \
- cpp_enum_field.lo cpp_extension.lo cpp_field.lo cpp_file.lo \
- cpp_generator.lo cpp_helpers.lo cpp_message.lo \
- cpp_message_field.lo cpp_primitive_field.lo cpp_service.lo \
- cpp_string_field.lo java_enum.lo java_enum_field.lo \
- java_extension.lo java_field.lo java_file.lo java_generator.lo \
- java_helpers.lo java_message.lo java_message_field.lo \
- java_primitive_field.lo java_service.lo javamicro_enum.lo \
- javamicro_enum_field.lo javamicro_field.lo javamicro_file.lo \
- javamicro_generator.lo javamicro_helpers.lo \
- javamicro_message.lo javamicro_message_field.lo \
- javamicro_primitive_field.lo javanano_enum.lo \
- javanano_enum_field.lo javanano_extension.lo javanano_field.lo \
- javanano_file.lo javanano_generator.lo javanano_helpers.lo \
- javanano_message.lo javanano_message_field.lo \
- javanano_primitive_field.lo python_generator.lo
+am_libprotoc_la_OBJECTS = google/protobuf/compiler/code_generator.lo \
+ google/protobuf/compiler/command_line_interface.lo \
+ google/protobuf/compiler/plugin.lo \
+ google/protobuf/compiler/plugin.pb.lo \
+ google/protobuf/compiler/subprocess.lo \
+ google/protobuf/compiler/zip_writer.lo \
+ google/protobuf/compiler/cpp/cpp_enum.lo \
+ google/protobuf/compiler/cpp/cpp_enum_field.lo \
+ google/protobuf/compiler/cpp/cpp_extension.lo \
+ google/protobuf/compiler/cpp/cpp_field.lo \
+ google/protobuf/compiler/cpp/cpp_file.lo \
+ google/protobuf/compiler/cpp/cpp_generator.lo \
+ google/protobuf/compiler/cpp/cpp_helpers.lo \
+ google/protobuf/compiler/cpp/cpp_message.lo \
+ google/protobuf/compiler/cpp/cpp_message_field.lo \
+ google/protobuf/compiler/cpp/cpp_primitive_field.lo \
+ google/protobuf/compiler/cpp/cpp_service.lo \
+ google/protobuf/compiler/cpp/cpp_string_field.lo \
+ google/protobuf/compiler/java/java_context.lo \
+ google/protobuf/compiler/java/java_enum.lo \
+ google/protobuf/compiler/java/java_enum_field.lo \
+ google/protobuf/compiler/java/java_extension.lo \
+ google/protobuf/compiler/java/java_field.lo \
+ google/protobuf/compiler/java/java_file.lo \
+ google/protobuf/compiler/java/java_generator.lo \
+ google/protobuf/compiler/java/java_generator_factory.lo \
+ google/protobuf/compiler/java/java_helpers.lo \
+ google/protobuf/compiler/java/java_lazy_message_field.lo \
+ google/protobuf/compiler/java/java_message.lo \
+ google/protobuf/compiler/java/java_message_field.lo \
+ google/protobuf/compiler/java/java_name_resolver.lo \
+ google/protobuf/compiler/java/java_primitive_field.lo \
+ google/protobuf/compiler/java/java_shared_code_generator.lo \
+ google/protobuf/compiler/java/java_service.lo \
+ google/protobuf/compiler/java/java_string_field.lo \
+ google/protobuf/compiler/java/java_doc_comment.lo \
+ google/protobuf/compiler/javamicro/javamicro_enum.lo \
+ google/protobuf/compiler/javamicro/javamicro_enum_field.lo \
+ google/protobuf/compiler/javamicro/javamicro_field.lo \
+ google/protobuf/compiler/javamicro/javamicro_file.lo \
+ google/protobuf/compiler/javamicro/javamicro_generator.lo \
+ google/protobuf/compiler/javamicro/javamicro_helpers.lo \
+ google/protobuf/compiler/javamicro/javamicro_message.lo \
+ google/protobuf/compiler/javamicro/javamicro_message_field.lo \
+ google/protobuf/compiler/javamicro/javamicro_primitive_field.lo \
+ google/protobuf/compiler/javanano/javanano_enum.lo \
+ google/protobuf/compiler/javanano/javanano_enum_field.lo \
+ google/protobuf/compiler/javanano/javanano_extension.lo \
+ google/protobuf/compiler/javanano/javanano_field.lo \
+ google/protobuf/compiler/javanano/javanano_file.lo \
+ google/protobuf/compiler/javanano/javanano_generator.lo \
+ google/protobuf/compiler/javanano/javanano_helpers.lo \
+ google/protobuf/compiler/javanano/javanano_message.lo \
+ google/protobuf/compiler/javanano/javanano_message_field.lo \
+ google/protobuf/compiler/javanano/javanano_primitive_field.lo \
+ google/protobuf/compiler/python/python_generator.lo
libprotoc_la_OBJECTS = $(am_libprotoc_la_OBJECTS)
-libprotoc_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+libprotoc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(libprotoc_la_LDFLAGS) $(LDFLAGS) -o $@
@HAVE_ZLIB_TRUE@am__EXEEXT_1 = zcgzip$(EXEEXT) zcgunzip$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS)
-am__objects_2 = protobuf_lazy_descriptor_test-test_util.$(OBJEXT) \
- protobuf_lazy_descriptor_test-googletest.$(OBJEXT) \
- protobuf_lazy_descriptor_test-file.$(OBJEXT)
-am_protobuf_lazy_descriptor_test_OBJECTS = \
- protobuf_lazy_descriptor_test-cpp_unittest.$(OBJEXT) \
+am__objects_2 = google/protobuf/protobuf_lazy_descriptor_test-test_util.$(OBJEXT) \
+ google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.$(OBJEXT) \
+ google/protobuf/testing/protobuf_lazy_descriptor_test-file.$(OBJEXT)
+am_protobuf_lazy_descriptor_test_OBJECTS = google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.$(OBJEXT) \
$(am__objects_2)
-am__objects_3 = \
- protobuf_lazy_descriptor_test-unittest_lite.pb.$(OBJEXT) \
- protobuf_lazy_descriptor_test-unittest_import_lite.pb.$(OBJEXT)
+am__objects_3 = google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.$(OBJEXT) \
+ google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.$(OBJEXT) \
+ google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.$(OBJEXT)
am__objects_4 = $(am__objects_3) \
- protobuf_lazy_descriptor_test-unittest.pb.$(OBJEXT) \
- protobuf_lazy_descriptor_test-unittest_empty.pb.$(OBJEXT) \
- protobuf_lazy_descriptor_test-unittest_import.pb.$(OBJEXT) \
- protobuf_lazy_descriptor_test-unittest_mset.pb.$(OBJEXT) \
- protobuf_lazy_descriptor_test-unittest_optimize_for.pb.$(OBJEXT) \
- protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.$(OBJEXT) \
- protobuf_lazy_descriptor_test-unittest_custom_options.pb.$(OBJEXT) \
- protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.$(OBJEXT) \
- protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.$(OBJEXT) \
- protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.$(OBJEXT)
+ google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.$(OBJEXT) \
+ google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.$(OBJEXT) \
+ google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.$(OBJEXT) \
+ google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.$(OBJEXT) \
+ google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.$(OBJEXT) \
+ google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.$(OBJEXT) \
+ google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.$(OBJEXT) \
+ google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.$(OBJEXT) \
+ google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.$(OBJEXT) \
+ google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.$(OBJEXT) \
+ google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.$(OBJEXT)
nodist_protobuf_lazy_descriptor_test_OBJECTS = $(am__objects_4)
protobuf_lazy_descriptor_test_OBJECTS = \
$(am_protobuf_lazy_descriptor_test_OBJECTS) \
$(nodist_protobuf_lazy_descriptor_test_OBJECTS)
protobuf_lazy_descriptor_test_DEPENDENCIES = $(am__DEPENDENCIES_1) \
- libprotobuf.la $(top_builddir)/gtest/lib/libgtest.la \
+ libprotobuf.la libprotoc.la \
+ $(top_builddir)/gtest/lib/libgtest.la \
$(top_builddir)/gtest/lib/libgtest_main.la
-protobuf_lazy_descriptor_test_LINK = $(LIBTOOL) --tag=CXX \
+protobuf_lazy_descriptor_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
am_protobuf_lite_test_OBJECTS = \
- protobuf_lite_test-lite_unittest.$(OBJEXT) \
- protobuf_lite_test-test_util_lite.$(OBJEXT)
-am__objects_5 = protobuf_lite_test-unittest_lite.pb.$(OBJEXT) \
- protobuf_lite_test-unittest_import_lite.pb.$(OBJEXT)
+ google/protobuf/protobuf_lite_test-lite_unittest.$(OBJEXT) \
+ google/protobuf/protobuf_lite_test-test_util_lite.$(OBJEXT)
+am__objects_5 = \
+ google/protobuf/protobuf_lite_test-unittest_lite.pb.$(OBJEXT) \
+ google/protobuf/protobuf_lite_test-unittest_import_lite.pb.$(OBJEXT) \
+ google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.$(OBJEXT)
nodist_protobuf_lite_test_OBJECTS = $(am__objects_5)
protobuf_lite_test_OBJECTS = $(am_protobuf_lite_test_OBJECTS) \
$(nodist_protobuf_lite_test_OBJECTS)
protobuf_lite_test_DEPENDENCIES = $(am__DEPENDENCIES_1) \
libprotobuf-lite.la
-protobuf_lite_test_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+protobuf_lite_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-am__objects_6 = protobuf_test-test_util.$(OBJEXT) \
- protobuf_test-googletest.$(OBJEXT) \
- protobuf_test-file.$(OBJEXT)
-am_protobuf_test_OBJECTS = protobuf_test-common_unittest.$(OBJEXT) \
- protobuf_test-once_unittest.$(OBJEXT) \
- protobuf_test-strutil_unittest.$(OBJEXT) \
- protobuf_test-structurally_valid_unittest.$(OBJEXT) \
- protobuf_test-descriptor_database_unittest.$(OBJEXT) \
- protobuf_test-descriptor_unittest.$(OBJEXT) \
- protobuf_test-dynamic_message_unittest.$(OBJEXT) \
- protobuf_test-extension_set_unittest.$(OBJEXT) \
- protobuf_test-generated_message_reflection_unittest.$(OBJEXT) \
- protobuf_test-message_unittest.$(OBJEXT) \
- protobuf_test-reflection_ops_unittest.$(OBJEXT) \
- protobuf_test-repeated_field_unittest.$(OBJEXT) \
- protobuf_test-text_format_unittest.$(OBJEXT) \
- protobuf_test-unknown_field_set_unittest.$(OBJEXT) \
- protobuf_test-wire_format_unittest.$(OBJEXT) \
- protobuf_test-coded_stream_unittest.$(OBJEXT) \
- protobuf_test-printer_unittest.$(OBJEXT) \
- protobuf_test-tokenizer_unittest.$(OBJEXT) \
- protobuf_test-zero_copy_stream_unittest.$(OBJEXT) \
- protobuf_test-command_line_interface_unittest.$(OBJEXT) \
- protobuf_test-importer_unittest.$(OBJEXT) \
- protobuf_test-mock_code_generator.$(OBJEXT) \
- protobuf_test-parser_unittest.$(OBJEXT) \
- protobuf_test-cpp_bootstrap_unittest.$(OBJEXT) \
- protobuf_test-cpp_unittest.$(OBJEXT) \
- protobuf_test-cpp_plugin_unittest.$(OBJEXT) \
- protobuf_test-java_plugin_unittest.$(OBJEXT) \
- protobuf_test-python_plugin_unittest.$(OBJEXT) \
+am__objects_6 = google/protobuf/protobuf_test-test_util.$(OBJEXT) \
+ google/protobuf/testing/protobuf_test-googletest.$(OBJEXT) \
+ google/protobuf/testing/protobuf_test-file.$(OBJEXT)
+am_protobuf_test_OBJECTS = \
+ google/protobuf/stubs/protobuf_test-common_unittest.$(OBJEXT) \
+ google/protobuf/stubs/protobuf_test-once_unittest.$(OBJEXT) \
+ google/protobuf/stubs/protobuf_test-strutil_unittest.$(OBJEXT) \
+ google/protobuf/stubs/protobuf_test-structurally_valid_unittest.$(OBJEXT) \
+ google/protobuf/stubs/protobuf_test-stringprintf_unittest.$(OBJEXT) \
+ google/protobuf/stubs/protobuf_test-template_util_unittest.$(OBJEXT) \
+ google/protobuf/stubs/protobuf_test-type_traits_unittest.$(OBJEXT) \
+ google/protobuf/protobuf_test-descriptor_database_unittest.$(OBJEXT) \
+ google/protobuf/protobuf_test-descriptor_unittest.$(OBJEXT) \
+ google/protobuf/protobuf_test-dynamic_message_unittest.$(OBJEXT) \
+ google/protobuf/protobuf_test-extension_set_unittest.$(OBJEXT) \
+ google/protobuf/protobuf_test-generated_message_reflection_unittest.$(OBJEXT) \
+ google/protobuf/protobuf_test-message_unittest.$(OBJEXT) \
+ google/protobuf/protobuf_test-reflection_ops_unittest.$(OBJEXT) \
+ google/protobuf/protobuf_test-repeated_field_unittest.$(OBJEXT) \
+ google/protobuf/protobuf_test-repeated_field_reflection_unittest.$(OBJEXT) \
+ google/protobuf/protobuf_test-text_format_unittest.$(OBJEXT) \
+ google/protobuf/protobuf_test-unknown_field_set_unittest.$(OBJEXT) \
+ google/protobuf/protobuf_test-wire_format_unittest.$(OBJEXT) \
+ google/protobuf/io/protobuf_test-coded_stream_unittest.$(OBJEXT) \
+ google/protobuf/io/protobuf_test-printer_unittest.$(OBJEXT) \
+ google/protobuf/io/protobuf_test-tokenizer_unittest.$(OBJEXT) \
+ google/protobuf/io/protobuf_test-zero_copy_stream_unittest.$(OBJEXT) \
+ google/protobuf/compiler/protobuf_test-command_line_interface_unittest.$(OBJEXT) \
+ google/protobuf/compiler/protobuf_test-importer_unittest.$(OBJEXT) \
+ google/protobuf/compiler/protobuf_test-mock_code_generator.$(OBJEXT) \
+ google/protobuf/compiler/protobuf_test-parser_unittest.$(OBJEXT) \
+ google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.$(OBJEXT) \
+ google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.$(OBJEXT) \
+ google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.$(OBJEXT) \
+ google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.$(OBJEXT) \
+ google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.$(OBJEXT) \
+ google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.$(OBJEXT) \
$(am__objects_6)
-am__objects_7 = protobuf_test-unittest_lite.pb.$(OBJEXT) \
- protobuf_test-unittest_import_lite.pb.$(OBJEXT)
-am__objects_8 = $(am__objects_7) protobuf_test-unittest.pb.$(OBJEXT) \
- protobuf_test-unittest_empty.pb.$(OBJEXT) \
- protobuf_test-unittest_import.pb.$(OBJEXT) \
- protobuf_test-unittest_mset.pb.$(OBJEXT) \
- protobuf_test-unittest_optimize_for.pb.$(OBJEXT) \
- protobuf_test-unittest_embed_optimize_for.pb.$(OBJEXT) \
- protobuf_test-unittest_custom_options.pb.$(OBJEXT) \
- protobuf_test-unittest_lite_imports_nonlite.pb.$(OBJEXT) \
- protobuf_test-unittest_no_generic_services.pb.$(OBJEXT) \
- protobuf_test-cpp_test_bad_identifiers.pb.$(OBJEXT)
+am__objects_7 = \
+ google/protobuf/protobuf_test-unittest_lite.pb.$(OBJEXT) \
+ google/protobuf/protobuf_test-unittest_import_lite.pb.$(OBJEXT) \
+ google/protobuf/protobuf_test-unittest_import_public_lite.pb.$(OBJEXT)
+am__objects_8 = $(am__objects_7) \
+ google/protobuf/protobuf_test-unittest.pb.$(OBJEXT) \
+ google/protobuf/protobuf_test-unittest_empty.pb.$(OBJEXT) \
+ google/protobuf/protobuf_test-unittest_import.pb.$(OBJEXT) \
+ google/protobuf/protobuf_test-unittest_import_public.pb.$(OBJEXT) \
+ google/protobuf/protobuf_test-unittest_mset.pb.$(OBJEXT) \
+ google/protobuf/protobuf_test-unittest_optimize_for.pb.$(OBJEXT) \
+ google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.$(OBJEXT) \
+ google/protobuf/protobuf_test-unittest_custom_options.pb.$(OBJEXT) \
+ google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.$(OBJEXT) \
+ google/protobuf/protobuf_test-unittest_no_generic_services.pb.$(OBJEXT) \
+ google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.$(OBJEXT)
nodist_protobuf_test_OBJECTS = $(am__objects_8)
protobuf_test_OBJECTS = $(am_protobuf_test_OBJECTS) \
$(nodist_protobuf_test_OBJECTS)
protobuf_test_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la \
libprotoc.la $(top_builddir)/gtest/lib/libgtest.la \
$(top_builddir)/gtest/lib/libgtest_main.la
-protobuf_test_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(protobuf_test_CXXFLAGS) \
- $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-am_protoc_OBJECTS = main.$(OBJEXT)
+protobuf_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+ $(protobuf_test_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+ -o $@
+am_protoc_OBJECTS = google/protobuf/compiler/main.$(OBJEXT)
protoc_OBJECTS = $(am_protoc_OBJECTS)
protoc_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la \
libprotoc.la
-am_test_plugin_OBJECTS = test_plugin-mock_code_generator.$(OBJEXT) \
- test_plugin-file.$(OBJEXT) test_plugin-test_plugin.$(OBJEXT)
+am_test_plugin_OBJECTS = google/protobuf/compiler/test_plugin-mock_code_generator.$(OBJEXT) \
+ google/protobuf/testing/test_plugin-file.$(OBJEXT) \
+ google/protobuf/compiler/test_plugin-test_plugin.$(OBJEXT)
test_plugin_OBJECTS = $(am_test_plugin_OBJECTS)
test_plugin_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la \
libprotoc.la $(top_builddir)/gtest/lib/libgtest.la
am__zcgunzip_SOURCES_DIST = google/protobuf/testing/zcgunzip.cc
-@HAVE_ZLIB_TRUE@am_zcgunzip_OBJECTS = zcgunzip.$(OBJEXT)
+@HAVE_ZLIB_TRUE@am_zcgunzip_OBJECTS = \
+@HAVE_ZLIB_TRUE@ google/protobuf/testing/zcgunzip.$(OBJEXT)
zcgunzip_OBJECTS = $(am_zcgunzip_OBJECTS)
@HAVE_ZLIB_TRUE@zcgunzip_DEPENDENCIES = $(am__DEPENDENCIES_1) \
@HAVE_ZLIB_TRUE@ libprotobuf.la
am__zcgzip_SOURCES_DIST = google/protobuf/testing/zcgzip.cc
-@HAVE_ZLIB_TRUE@am_zcgzip_OBJECTS = zcgzip.$(OBJEXT)
+@HAVE_ZLIB_TRUE@am_zcgzip_OBJECTS = \
+@HAVE_ZLIB_TRUE@ google/protobuf/testing/zcgzip.$(OBJEXT)
zcgzip_OBJECTS = $(am_zcgzip_OBJECTS)
@HAVE_ZLIB_TRUE@zcgzip_DEPENDENCIES = $(am__DEPENDENCIES_1) \
@HAVE_ZLIB_TRUE@ libprotobuf.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
SOURCES = $(libprotobuf_lite_la_SOURCES) $(libprotobuf_la_SOURCES) \
$(libprotoc_la_SOURCES) \
$(protobuf_lazy_descriptor_test_SOURCES) \
@@ -297,13 +463,34 @@ DIST_SOURCES = $(libprotobuf_lite_la_SOURCES) \
$(protobuf_lite_test_SOURCES) $(protobuf_test_SOURCES) \
$(protoc_SOURCES) $(test_plugin_SOURCES) \
$(am__zcgunzip_SOURCES_DIST) $(am__zcgzip_SOURCES_DIST)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
DATA = $(nobase_dist_proto_DATA)
-am__nobase_include_HEADERS_DIST = google/protobuf/stubs/common.h \
- google/protobuf/stubs/once.h google/protobuf/descriptor.h \
- google/protobuf/descriptor.pb.h \
+am__nobase_include_HEADERS_DIST = google/protobuf/stubs/atomicops.h \
+ google/protobuf/stubs/atomicops_internals_arm_gcc.h \
+ google/protobuf/stubs/atomicops_internals_arm64_gcc.h \
+ google/protobuf/stubs/atomicops_internals_arm_qnx.h \
+ google/protobuf/stubs/atomicops_internals_atomicword_compat.h \
+ google/protobuf/stubs/atomicops_internals_generic_gcc.h \
+ google/protobuf/stubs/atomicops_internals_macosx.h \
+ google/protobuf/stubs/atomicops_internals_mips_gcc.h \
+ google/protobuf/stubs/atomicops_internals_pnacl.h \
+ google/protobuf/stubs/atomicops_internals_tsan.h \
+ google/protobuf/stubs/atomicops_internals_x86_gcc.h \
+ google/protobuf/stubs/atomicops_internals_x86_msvc.h \
+ google/protobuf/stubs/common.h \
+ google/protobuf/stubs/platform_macros.h \
+ google/protobuf/stubs/once.h google/protobuf/stubs/stl_util.h \
+ google/protobuf/stubs/template_util.h \
+ google/protobuf/stubs/type_traits.h \
+ google/protobuf/descriptor.h google/protobuf/descriptor.pb.h \
google/protobuf/descriptor_database.h \
google/protobuf/dynamic_message.h \
google/protobuf/extension_set.h \
+ google/protobuf/generated_enum_reflection.h \
google/protobuf/generated_message_util.h \
google/protobuf/generated_message_reflection.h \
google/protobuf/message.h google/protobuf/message_lite.h \
@@ -316,7 +503,7 @@ am__nobase_include_HEADERS_DIST = google/protobuf/stubs/common.h \
google/protobuf/wire_format_lite_inl.h \
google/protobuf/io/coded_stream.h \
google/protobuf/io/gzip_stream.h google/protobuf/io/printer.h \
- google/protobuf/io/tokenizer.h \
+ google/protobuf/io/strtod.h google/protobuf/io/tokenizer.h \
google/protobuf/io/zero_copy_stream.h \
google/protobuf/io/zero_copy_stream_impl.h \
google/protobuf/io/zero_copy_stream_impl_lite.h \
@@ -332,15 +519,208 @@ am__nobase_include_HEADERS_DIST = google/protobuf/stubs/common.h \
google/protobuf/compiler/javanano/javanano_generator.h \
google/protobuf/compiler/python/python_generator.h
HEADERS = $(nobase_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
-am__tty_colors = \
-red=; grn=; lgn=; blu=; std=
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
@HAVE_ZLIB_TRUE@am__EXEEXT_2 = \
@HAVE_ZLIB_TRUE@ google/protobuf/io/gzip_stream_unittest.sh
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
@@ -357,6 +737,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -380,10 +761,13 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -411,6 +795,7 @@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
@@ -445,7 +830,6 @@ libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
@@ -492,54 +876,75 @@ MAINTAINERCLEANFILES = \
Makefile.in
nobase_include_HEADERS = \
- google/protobuf/stubs/common.h \
- google/protobuf/stubs/once.h \
- google/protobuf/descriptor.h \
- google/protobuf/descriptor.pb.h \
- google/protobuf/descriptor_database.h \
- google/protobuf/dynamic_message.h \
- google/protobuf/extension_set.h \
- google/protobuf/generated_message_util.h \
- google/protobuf/generated_message_reflection.h \
- google/protobuf/message.h \
- google/protobuf/message_lite.h \
- google/protobuf/reflection_ops.h \
- google/protobuf/repeated_field.h \
- google/protobuf/service.h \
- google/protobuf/text_format.h \
- google/protobuf/unknown_field_set.h \
- google/protobuf/wire_format.h \
- google/protobuf/wire_format_lite.h \
- google/protobuf/wire_format_lite_inl.h \
- google/protobuf/io/coded_stream.h \
- $(GZHEADERS) \
- google/protobuf/io/printer.h \
- google/protobuf/io/tokenizer.h \
- google/protobuf/io/zero_copy_stream.h \
- google/protobuf/io/zero_copy_stream_impl.h \
- google/protobuf/io/zero_copy_stream_impl_lite.h \
- google/protobuf/compiler/code_generator.h \
- google/protobuf/compiler/command_line_interface.h \
- google/protobuf/compiler/importer.h \
- google/protobuf/compiler/parser.h \
- google/protobuf/compiler/plugin.h \
- google/protobuf/compiler/plugin.pb.h \
- google/protobuf/compiler/cpp/cpp_generator.h \
- google/protobuf/compiler/java/java_generator.h \
- google/protobuf/compiler/javamicro/javamicro_generator.h \
- google/protobuf/compiler/javanano/javanano_generator.h \
+ google/protobuf/stubs/atomicops.h \
+ google/protobuf/stubs/atomicops_internals_arm_gcc.h \
+ google/protobuf/stubs/atomicops_internals_arm64_gcc.h \
+ google/protobuf/stubs/atomicops_internals_arm_qnx.h \
+ google/protobuf/stubs/atomicops_internals_atomicword_compat.h \
+ google/protobuf/stubs/atomicops_internals_generic_gcc.h \
+ google/protobuf/stubs/atomicops_internals_macosx.h \
+ google/protobuf/stubs/atomicops_internals_mips_gcc.h \
+ google/protobuf/stubs/atomicops_internals_pnacl.h \
+ google/protobuf/stubs/atomicops_internals_tsan.h \
+ google/protobuf/stubs/atomicops_internals_x86_gcc.h \
+ google/protobuf/stubs/atomicops_internals_x86_msvc.h \
+ google/protobuf/stubs/common.h \
+ google/protobuf/stubs/platform_macros.h \
+ google/protobuf/stubs/once.h \
+ google/protobuf/stubs/stl_util.h \
+ google/protobuf/stubs/template_util.h \
+ google/protobuf/stubs/type_traits.h \
+ google/protobuf/descriptor.h \
+ google/protobuf/descriptor.pb.h \
+ google/protobuf/descriptor_database.h \
+ google/protobuf/dynamic_message.h \
+ google/protobuf/extension_set.h \
+ google/protobuf/generated_enum_reflection.h \
+ google/protobuf/generated_message_util.h \
+ google/protobuf/generated_message_reflection.h \
+ google/protobuf/message.h \
+ google/protobuf/message_lite.h \
+ google/protobuf/reflection_ops.h \
+ google/protobuf/repeated_field.h \
+ google/protobuf/service.h \
+ google/protobuf/text_format.h \
+ google/protobuf/unknown_field_set.h \
+ google/protobuf/wire_format.h \
+ google/protobuf/wire_format_lite.h \
+ google/protobuf/wire_format_lite_inl.h \
+ google/protobuf/io/coded_stream.h \
+ $(GZHEADERS) \
+ google/protobuf/io/printer.h \
+ google/protobuf/io/strtod.h \
+ google/protobuf/io/tokenizer.h \
+ google/protobuf/io/zero_copy_stream.h \
+ google/protobuf/io/zero_copy_stream_impl.h \
+ google/protobuf/io/zero_copy_stream_impl_lite.h \
+ google/protobuf/compiler/code_generator.h \
+ google/protobuf/compiler/command_line_interface.h \
+ google/protobuf/compiler/importer.h \
+ google/protobuf/compiler/parser.h \
+ google/protobuf/compiler/plugin.h \
+ google/protobuf/compiler/plugin.pb.h \
+ google/protobuf/compiler/cpp/cpp_generator.h \
+ google/protobuf/compiler/java/java_generator.h \
+ google/protobuf/compiler/javamicro/javamicro_generator.h \
+ google/protobuf/compiler/javanano/javanano_generator.h \
google/protobuf/compiler/python/python_generator.h
lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la
libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS)
-libprotobuf_lite_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined
+libprotobuf_lite_la_LDFLAGS = -version-info 9:1:0 -export-dynamic -no-undefined
libprotobuf_lite_la_SOURCES = \
+ google/protobuf/stubs/atomicops_internals_x86_gcc.cc \
+ google/protobuf/stubs/atomicops_internals_x86_msvc.cc \
google/protobuf/stubs/common.cc \
google/protobuf/stubs/once.cc \
- google/protobuf/stubs/hash.cc \
google/protobuf/stubs/hash.h \
- google/protobuf/stubs/map-util.h \
- google/protobuf/stubs/stl_util-inl.h \
+ google/protobuf/stubs/map_util.h \
+ google/protobuf/stubs/shared_ptr.h \
+ google/protobuf/stubs/stringprintf.cc \
+ google/protobuf/stubs/stringprintf.h \
google/protobuf/extension_set.cc \
google/protobuf/generated_message_util.cc \
google/protobuf/message_lite.cc \
@@ -551,7 +956,7 @@ libprotobuf_lite_la_SOURCES = \
google/protobuf/io/zero_copy_stream_impl_lite.cc
libprotobuf_la_LIBADD = $(PTHREAD_LIBS)
-libprotobuf_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined
+libprotobuf_la_LDFLAGS = -version-info 9:1:0 -export-dynamic -no-undefined
libprotobuf_la_SOURCES = \
$(libprotobuf_lite_la_SOURCES) \
google/protobuf/stubs/strutil.cc \
@@ -573,13 +978,14 @@ libprotobuf_la_SOURCES = \
google/protobuf/wire_format.cc \
google/protobuf/io/gzip_stream.cc \
google/protobuf/io/printer.cc \
+ google/protobuf/io/strtod.cc \
google/protobuf/io/tokenizer.cc \
google/protobuf/io/zero_copy_stream_impl.cc \
google/protobuf/compiler/importer.cc \
google/protobuf/compiler/parser.cc
libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la
-libprotoc_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined
+libprotoc_la_LDFLAGS = -version-info 9:1:0 -export-dynamic -no-undefined
libprotoc_la_SOURCES = \
google/protobuf/compiler/code_generator.cc \
google/protobuf/compiler/command_line_interface.cc \
@@ -606,12 +1012,15 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/cpp/cpp_message.h \
google/protobuf/compiler/cpp/cpp_message_field.cc \
google/protobuf/compiler/cpp/cpp_message_field.h \
+ google/protobuf/compiler/cpp/cpp_options.h \
google/protobuf/compiler/cpp/cpp_primitive_field.cc \
google/protobuf/compiler/cpp/cpp_primitive_field.h \
google/protobuf/compiler/cpp/cpp_service.cc \
google/protobuf/compiler/cpp/cpp_service.h \
google/protobuf/compiler/cpp/cpp_string_field.cc \
google/protobuf/compiler/cpp/cpp_string_field.h \
+ google/protobuf/compiler/java/java_context.cc \
+ google/protobuf/compiler/java/java_context.h \
google/protobuf/compiler/java/java_enum.cc \
google/protobuf/compiler/java/java_enum.h \
google/protobuf/compiler/java/java_enum_field.cc \
@@ -623,16 +1032,28 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/java/java_file.cc \
google/protobuf/compiler/java/java_file.h \
google/protobuf/compiler/java/java_generator.cc \
+ google/protobuf/compiler/java/java_generator_factory.cc \
+ google/protobuf/compiler/java/java_generator_factory.h \
google/protobuf/compiler/java/java_helpers.cc \
google/protobuf/compiler/java/java_helpers.h \
+ google/protobuf/compiler/java/java_lazy_message_field.cc \
+ google/protobuf/compiler/java/java_lazy_message_field.h \
google/protobuf/compiler/java/java_message.cc \
google/protobuf/compiler/java/java_message.h \
google/protobuf/compiler/java/java_message_field.cc \
google/protobuf/compiler/java/java_message_field.h \
+ google/protobuf/compiler/java/java_name_resolver.cc \
+ google/protobuf/compiler/java/java_name_resolver.h \
google/protobuf/compiler/java/java_primitive_field.cc \
google/protobuf/compiler/java/java_primitive_field.h \
+ google/protobuf/compiler/java/java_shared_code_generator.cc \
+ google/protobuf/compiler/java/java_shared_code_generator.h \
google/protobuf/compiler/java/java_service.cc \
google/protobuf/compiler/java/java_service.h \
+ google/protobuf/compiler/java/java_string_field.cc \
+ google/protobuf/compiler/java/java_string_field.h \
+ google/protobuf/compiler/java/java_doc_comment.cc \
+ google/protobuf/compiler/java/java_doc_comment.h \
google/protobuf/compiler/javamicro/javamicro_enum.cc \
google/protobuf/compiler/javamicro/javamicro_enum.h \
google/protobuf/compiler/javamicro/javamicro_enum_field.cc \
@@ -679,12 +1100,14 @@ protoc_inputs = \
google/protobuf/unittest.proto \
google/protobuf/unittest_empty.proto \
google/protobuf/unittest_import.proto \
+ google/protobuf/unittest_import_public.proto \
google/protobuf/unittest_mset.proto \
google/protobuf/unittest_optimize_for.proto \
google/protobuf/unittest_embed_optimize_for.proto \
google/protobuf/unittest_custom_options.proto \
google/protobuf/unittest_lite.proto \
google/protobuf/unittest_import_lite.proto \
+ google/protobuf/unittest_import_public_lite.proto \
google/protobuf/unittest_lite_imports_nonlite.proto \
google/protobuf/unittest_no_generic_services.proto \
google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
@@ -695,9 +1118,15 @@ 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_oneof_implemented \
google/protobuf/testdata/golden_packed_fields_message \
+ google/protobuf/testdata/bad_utf8_string \
google/protobuf/testdata/text_format_unittest_data.txt \
- google/protobuf/testdata/text_format_unittest_extensions_data.txt \
+ google/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt \
+ google/protobuf/testdata/text_format_unittest_data_pointy.txt \
+ google/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt \
+ google/protobuf/testdata/text_format_unittest_extensions_data.txt \
+ google/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt \
google/protobuf/package_info.h \
google/protobuf/io/package_info.h \
google/protobuf/compiler/package_info.h \
@@ -708,7 +1137,9 @@ protoc_lite_outputs = \
google/protobuf/unittest_lite.pb.cc \
google/protobuf/unittest_lite.pb.h \
google/protobuf/unittest_import_lite.pb.cc \
- google/protobuf/unittest_import_lite.pb.h
+ google/protobuf/unittest_import_lite.pb.h \
+ google/protobuf/unittest_import_public_lite.pb.cc \
+ google/protobuf/unittest_import_public_lite.pb.h
protoc_outputs = \
$(protoc_lite_outputs) \
@@ -718,6 +1149,8 @@ protoc_outputs = \
google/protobuf/unittest_empty.pb.h \
google/protobuf/unittest_import.pb.cc \
google/protobuf/unittest_import.pb.h \
+ google/protobuf/unittest_import_public.pb.cc \
+ google/protobuf/unittest_import_public.pb.h \
google/protobuf/unittest_mset.pb.cc \
google/protobuf/unittest_mset.pb.h \
google/protobuf/unittest_optimize_for.pb.cc \
@@ -758,6 +1191,9 @@ protobuf_test_SOURCES = \
google/protobuf/stubs/once_unittest.cc \
google/protobuf/stubs/strutil_unittest.cc \
google/protobuf/stubs/structurally_valid_unittest.cc \
+ google/protobuf/stubs/stringprintf_unittest.cc \
+ google/protobuf/stubs/template_util_unittest.cc \
+ google/protobuf/stubs/type_traits_unittest.cc \
google/protobuf/descriptor_database_unittest.cc \
google/protobuf/descriptor_unittest.cc \
google/protobuf/dynamic_message_unittest.cc \
@@ -766,6 +1202,7 @@ protobuf_test_SOURCES = \
google/protobuf/message_unittest.cc \
google/protobuf/reflection_ops_unittest.cc \
google/protobuf/repeated_field_unittest.cc \
+ google/protobuf/repeated_field_reflection_unittest.cc \
google/protobuf/text_format_unittest.cc \
google/protobuf/unknown_field_set_unittest.cc \
google/protobuf/wire_format_unittest.cc \
@@ -779,9 +1216,11 @@ protobuf_test_SOURCES = \
google/protobuf/compiler/mock_code_generator.h \
google/protobuf/compiler/parser_unittest.cc \
google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc \
+ 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/java/java_plugin_unittest.cc \
+ google/protobuf/compiler/java/java_doc_comment_unittest.cc \
google/protobuf/compiler/python/python_plugin_unittest.cc \
$(COMMON_TEST_SOURCES)
@@ -789,7 +1228,8 @@ nodist_protobuf_test_SOURCES = $(protoc_outputs)
# Run cpp_unittest again with PROTOBUF_TEST_NO_DESCRIPTORS defined.
protobuf_lazy_descriptor_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la \
- $(top_builddir)/gtest/lib/libgtest.la \
+ libprotoc.la \
+ $(top_builddir)/gtest/lib/libgtest.la \
$(top_builddir)/gtest/lib/libgtest_main.la
protobuf_lazy_descriptor_test_CPPFLAGS = -I$(top_srcdir)/gtest/include \
@@ -834,8 +1274,8 @@ all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
-.SUFFIXES: .cc .lo .o .obj
-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -844,9 +1284,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/Makefile
+ $(AUTOMAKE) --foreign src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -860,14 +1300,14 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(top_srcdir)/configure: $(am__configure_deps)
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
+
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
@@ -875,6 +1315,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES)
else :; fi; \
done; \
test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
@@ -890,28 +1332,347 @@ uninstall-libLTLIBRARIES:
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
- test "$$dir" != "$$p" || dir=.; \
- echo "rm -f \"$${dir}/so_locations\""; \
- rm -f "$${dir}/so_locations"; \
- done
+ @list='$(lib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+google/protobuf/stubs/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/stubs
+ @: > google/protobuf/stubs/$(am__dirstamp)
+google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/stubs/$(DEPDIR)
+ @: > google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/atomicops_internals_x86_gcc.lo: \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/atomicops_internals_x86_msvc.lo: \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/common.lo: \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/once.lo: google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/stringprintf.lo: \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf
+ @: > google/protobuf/$(am__dirstamp)
+google/protobuf/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/$(DEPDIR)
+ @: > google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/extension_set.lo: google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/generated_message_util.lo: \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/message_lite.lo: google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/repeated_field.lo: google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/wire_format_lite.lo: google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/io
+ @: > google/protobuf/io/$(am__dirstamp)
+google/protobuf/io/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/io/$(DEPDIR)
+ @: > google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/coded_stream.lo: \
+ google/protobuf/io/$(am__dirstamp) \
+ google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/zero_copy_stream.lo: \
+ google/protobuf/io/$(am__dirstamp) \
+ google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/zero_copy_stream_impl_lite.lo: \
+ google/protobuf/io/$(am__dirstamp) \
+ google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+
libprotobuf-lite.la: $(libprotobuf_lite_la_OBJECTS) $(libprotobuf_lite_la_DEPENDENCIES) $(EXTRA_libprotobuf_lite_la_DEPENDENCIES)
- $(libprotobuf_lite_la_LINK) -rpath $(libdir) $(libprotobuf_lite_la_OBJECTS) $(libprotobuf_lite_la_LIBADD) $(LIBS)
+ $(AM_V_CXXLD)$(libprotobuf_lite_la_LINK) -rpath $(libdir) $(libprotobuf_lite_la_OBJECTS) $(libprotobuf_lite_la_LIBADD) $(LIBS)
+google/protobuf/stubs/strutil.lo: \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/substitute.lo: \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/structurally_valid.lo: \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/descriptor.lo: google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/descriptor.pb.lo: google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/descriptor_database.lo: \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/dynamic_message.lo: google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/extension_set_heavy.lo: \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/generated_message_reflection.lo: \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/message.lo: google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/reflection_ops.lo: google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/service.lo: google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/text_format.lo: google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/unknown_field_set.lo: google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/wire_format.lo: google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/gzip_stream.lo: google/protobuf/io/$(am__dirstamp) \
+ google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/printer.lo: google/protobuf/io/$(am__dirstamp) \
+ google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/strtod.lo: google/protobuf/io/$(am__dirstamp) \
+ google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/tokenizer.lo: google/protobuf/io/$(am__dirstamp) \
+ google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/zero_copy_stream_impl.lo: \
+ google/protobuf/io/$(am__dirstamp) \
+ google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/compiler
+ @: > google/protobuf/compiler/$(am__dirstamp)
+google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/compiler/$(DEPDIR)
+ @: > google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/importer.lo: \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/parser.lo: \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+
libprotobuf.la: $(libprotobuf_la_OBJECTS) $(libprotobuf_la_DEPENDENCIES) $(EXTRA_libprotobuf_la_DEPENDENCIES)
- $(libprotobuf_la_LINK) -rpath $(libdir) $(libprotobuf_la_OBJECTS) $(libprotobuf_la_LIBADD) $(LIBS)
+ $(AM_V_CXXLD)$(libprotobuf_la_LINK) -rpath $(libdir) $(libprotobuf_la_OBJECTS) $(libprotobuf_la_LIBADD) $(LIBS)
+google/protobuf/compiler/code_generator.lo: \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/command_line_interface.lo: \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/plugin.lo: \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/plugin.pb.lo: \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/subprocess.lo: \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/zip_writer.lo: \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/compiler/cpp
+ @: > google/protobuf/compiler/cpp/$(am__dirstamp)
+google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/compiler/cpp/$(DEPDIR)
+ @: > google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_enum.lo: \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_enum_field.lo: \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_extension.lo: \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_field.lo: \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_file.lo: \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_generator.lo: \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_helpers.lo: \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_message.lo: \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_message_field.lo: \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_primitive_field.lo: \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_service.lo: \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_string_field.lo: \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/compiler/java
+ @: > google/protobuf/compiler/java/$(am__dirstamp)
+google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/compiler/java/$(DEPDIR)
+ @: > google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_context.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_enum.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_enum_field.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_extension.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_field.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_file.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_generator.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_generator_factory.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_helpers.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_lazy_message_field.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_message.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_message_field.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_name_resolver.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_primitive_field.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_shared_code_generator.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_service.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_string_field.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_doc_comment.lo: \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/compiler/javamicro
+ @: > google/protobuf/compiler/javamicro/$(am__dirstamp)
+google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/compiler/javamicro/$(DEPDIR)
+ @: > google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_enum.lo: \
+ google/protobuf/compiler/javamicro/$(am__dirstamp) \
+ google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_enum_field.lo: \
+ google/protobuf/compiler/javamicro/$(am__dirstamp) \
+ google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_field.lo: \
+ google/protobuf/compiler/javamicro/$(am__dirstamp) \
+ google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_file.lo: \
+ google/protobuf/compiler/javamicro/$(am__dirstamp) \
+ google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_generator.lo: \
+ google/protobuf/compiler/javamicro/$(am__dirstamp) \
+ google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_helpers.lo: \
+ google/protobuf/compiler/javamicro/$(am__dirstamp) \
+ google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_message.lo: \
+ google/protobuf/compiler/javamicro/$(am__dirstamp) \
+ google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_message_field.lo: \
+ google/protobuf/compiler/javamicro/$(am__dirstamp) \
+ google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_primitive_field.lo: \
+ google/protobuf/compiler/javamicro/$(am__dirstamp) \
+ google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/compiler/javanano
+ @: > google/protobuf/compiler/javanano/$(am__dirstamp)
+google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/compiler/javanano/$(DEPDIR)
+ @: > google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_enum.lo: \
+ google/protobuf/compiler/javanano/$(am__dirstamp) \
+ google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_enum_field.lo: \
+ google/protobuf/compiler/javanano/$(am__dirstamp) \
+ google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_extension.lo: \
+ google/protobuf/compiler/javanano/$(am__dirstamp) \
+ google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_field.lo: \
+ google/protobuf/compiler/javanano/$(am__dirstamp) \
+ google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_file.lo: \
+ google/protobuf/compiler/javanano/$(am__dirstamp) \
+ google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_generator.lo: \
+ google/protobuf/compiler/javanano/$(am__dirstamp) \
+ google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_helpers.lo: \
+ google/protobuf/compiler/javanano/$(am__dirstamp) \
+ google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_message.lo: \
+ google/protobuf/compiler/javanano/$(am__dirstamp) \
+ google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_message_field.lo: \
+ google/protobuf/compiler/javanano/$(am__dirstamp) \
+ google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_primitive_field.lo: \
+ google/protobuf/compiler/javanano/$(am__dirstamp) \
+ google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/python/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/compiler/python
+ @: > google/protobuf/compiler/python/$(am__dirstamp)
+google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/compiler/python/$(DEPDIR)
+ @: > google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/python/python_generator.lo: \
+ google/protobuf/compiler/python/$(am__dirstamp) \
+ google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp)
+
libprotoc.la: $(libprotoc_la_OBJECTS) $(libprotoc_la_DEPENDENCIES) $(EXTRA_libprotoc_la_DEPENDENCIES)
- $(libprotoc_la_LINK) -rpath $(libdir) $(libprotoc_la_OBJECTS) $(libprotoc_la_LIBADD) $(LIBS)
+ $(AM_V_CXXLD)$(libprotoc_la_LINK) -rpath $(libdir) $(libprotoc_la_OBJECTS) $(libprotoc_la_LIBADD) $(LIBS)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
- test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
- while read p p1; do if test -f $$p || test -f $$p1; \
- then echo "$$p"; echo "$$p"; else :; fi; \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
done | \
- sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
@@ -932,7 +1693,8 @@ uninstall-binPROGRAMS:
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
- -e 's/$$/$(EXEEXT)/' `; \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
@@ -954,1755 +1716,1590 @@ clean-checkPROGRAMS:
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
+google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.$(OBJEXT): \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-test_util.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/testing/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/testing
+ @: > google/protobuf/testing/$(am__dirstamp)
+google/protobuf/testing/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) google/protobuf/testing/$(DEPDIR)
+ @: > google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.$(OBJEXT): \
+ google/protobuf/testing/$(am__dirstamp) \
+ google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/testing/protobuf_lazy_descriptor_test-file.$(OBJEXT): \
+ google/protobuf/testing/$(am__dirstamp) \
+ google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.$(OBJEXT): \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+
protobuf-lazy-descriptor-test$(EXEEXT): $(protobuf_lazy_descriptor_test_OBJECTS) $(protobuf_lazy_descriptor_test_DEPENDENCIES) $(EXTRA_protobuf_lazy_descriptor_test_DEPENDENCIES)
@rm -f protobuf-lazy-descriptor-test$(EXEEXT)
- $(protobuf_lazy_descriptor_test_LINK) $(protobuf_lazy_descriptor_test_OBJECTS) $(protobuf_lazy_descriptor_test_LDADD) $(LIBS)
+ $(AM_V_CXXLD)$(protobuf_lazy_descriptor_test_LINK) $(protobuf_lazy_descriptor_test_OBJECTS) $(protobuf_lazy_descriptor_test_LDADD) $(LIBS)
+google/protobuf/protobuf_lite_test-lite_unittest.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lite_test-test_util_lite.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lite_test-unittest_lite.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lite_test-unittest_import_lite.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+
protobuf-lite-test$(EXEEXT): $(protobuf_lite_test_OBJECTS) $(protobuf_lite_test_DEPENDENCIES) $(EXTRA_protobuf_lite_test_DEPENDENCIES)
@rm -f protobuf-lite-test$(EXEEXT)
- $(protobuf_lite_test_LINK) $(protobuf_lite_test_OBJECTS) $(protobuf_lite_test_LDADD) $(LIBS)
+ $(AM_V_CXXLD)$(protobuf_lite_test_LINK) $(protobuf_lite_test_OBJECTS) $(protobuf_lite_test_LDADD) $(LIBS)
+google/protobuf/stubs/protobuf_test-common_unittest.$(OBJEXT): \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/protobuf_test-once_unittest.$(OBJEXT): \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/protobuf_test-strutil_unittest.$(OBJEXT): \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/protobuf_test-structurally_valid_unittest.$(OBJEXT): \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/protobuf_test-stringprintf_unittest.$(OBJEXT): \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/protobuf_test-template_util_unittest.$(OBJEXT): \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/protobuf_test-type_traits_unittest.$(OBJEXT): \
+ google/protobuf/stubs/$(am__dirstamp) \
+ google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-descriptor_database_unittest.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-descriptor_unittest.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-dynamic_message_unittest.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-extension_set_unittest.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-generated_message_reflection_unittest.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-message_unittest.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-reflection_ops_unittest.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-repeated_field_unittest.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-repeated_field_reflection_unittest.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-text_format_unittest.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unknown_field_set_unittest.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-wire_format_unittest.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/protobuf_test-coded_stream_unittest.$(OBJEXT): \
+ google/protobuf/io/$(am__dirstamp) \
+ google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/protobuf_test-printer_unittest.$(OBJEXT): \
+ google/protobuf/io/$(am__dirstamp) \
+ google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/protobuf_test-tokenizer_unittest.$(OBJEXT): \
+ google/protobuf/io/$(am__dirstamp) \
+ google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/protobuf_test-zero_copy_stream_unittest.$(OBJEXT): \
+ google/protobuf/io/$(am__dirstamp) \
+ google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/protobuf_test-command_line_interface_unittest.$(OBJEXT): \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/protobuf_test-importer_unittest.$(OBJEXT): \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/protobuf_test-mock_code_generator.$(OBJEXT): \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/protobuf_test-parser_unittest.$(OBJEXT): \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.$(OBJEXT): \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.$(OBJEXT): \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.$(OBJEXT): \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.$(OBJEXT): \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.$(OBJEXT): \
+ google/protobuf/compiler/java/$(am__dirstamp) \
+ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.$(OBJEXT): \
+ google/protobuf/compiler/python/$(am__dirstamp) \
+ google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-test_util.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/testing/protobuf_test-googletest.$(OBJEXT): \
+ google/protobuf/testing/$(am__dirstamp) \
+ google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/testing/protobuf_test-file.$(OBJEXT): \
+ google/protobuf/testing/$(am__dirstamp) \
+ google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_lite.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_import_lite.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_import_public_lite.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_empty.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_import.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_import_public.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_mset.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_optimize_for.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_custom_options.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_no_generic_services.pb.$(OBJEXT): \
+ google/protobuf/$(am__dirstamp) \
+ google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.$(OBJEXT): \
+ google/protobuf/compiler/cpp/$(am__dirstamp) \
+ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+
protobuf-test$(EXEEXT): $(protobuf_test_OBJECTS) $(protobuf_test_DEPENDENCIES) $(EXTRA_protobuf_test_DEPENDENCIES)
@rm -f protobuf-test$(EXEEXT)
- $(protobuf_test_LINK) $(protobuf_test_OBJECTS) $(protobuf_test_LDADD) $(LIBS)
+ $(AM_V_CXXLD)$(protobuf_test_LINK) $(protobuf_test_OBJECTS) $(protobuf_test_LDADD) $(LIBS)
+google/protobuf/compiler/main.$(OBJEXT): \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+
protoc$(EXEEXT): $(protoc_OBJECTS) $(protoc_DEPENDENCIES) $(EXTRA_protoc_DEPENDENCIES)
@rm -f protoc$(EXEEXT)
- $(CXXLINK) $(protoc_OBJECTS) $(protoc_LDADD) $(LIBS)
+ $(AM_V_CXXLD)$(CXXLINK) $(protoc_OBJECTS) $(protoc_LDADD) $(LIBS)
+google/protobuf/compiler/test_plugin-mock_code_generator.$(OBJEXT): \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/testing/test_plugin-file.$(OBJEXT): \
+ google/protobuf/testing/$(am__dirstamp) \
+ google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/test_plugin-test_plugin.$(OBJEXT): \
+ google/protobuf/compiler/$(am__dirstamp) \
+ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+
test_plugin$(EXEEXT): $(test_plugin_OBJECTS) $(test_plugin_DEPENDENCIES) $(EXTRA_test_plugin_DEPENDENCIES)
@rm -f test_plugin$(EXEEXT)
- $(CXXLINK) $(test_plugin_OBJECTS) $(test_plugin_LDADD) $(LIBS)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_plugin_OBJECTS) $(test_plugin_LDADD) $(LIBS)
+google/protobuf/testing/zcgunzip.$(OBJEXT): \
+ google/protobuf/testing/$(am__dirstamp) \
+ google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+
zcgunzip$(EXEEXT): $(zcgunzip_OBJECTS) $(zcgunzip_DEPENDENCIES) $(EXTRA_zcgunzip_DEPENDENCIES)
@rm -f zcgunzip$(EXEEXT)
- $(CXXLINK) $(zcgunzip_OBJECTS) $(zcgunzip_LDADD) $(LIBS)
+ $(AM_V_CXXLD)$(CXXLINK) $(zcgunzip_OBJECTS) $(zcgunzip_LDADD) $(LIBS)
+google/protobuf/testing/zcgzip.$(OBJEXT): \
+ google/protobuf/testing/$(am__dirstamp) \
+ google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+
zcgzip$(EXEEXT): $(zcgzip_OBJECTS) $(zcgzip_DEPENDENCIES) $(EXTRA_zcgzip_DEPENDENCIES)
@rm -f zcgzip$(EXEEXT)
- $(CXXLINK) $(zcgzip_OBJECTS) $(zcgzip_LDADD) $(LIBS)
+ $(AM_V_CXXLD)$(CXXLINK) $(zcgzip_OBJECTS) $(zcgzip_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
+ -rm -f google/protobuf/*.$(OBJEXT)
+ -rm -f google/protobuf/*.lo
+ -rm -f google/protobuf/compiler/*.$(OBJEXT)
+ -rm -f google/protobuf/compiler/*.lo
+ -rm -f google/protobuf/compiler/cpp/*.$(OBJEXT)
+ -rm -f google/protobuf/compiler/cpp/*.lo
+ -rm -f google/protobuf/compiler/java/*.$(OBJEXT)
+ -rm -f google/protobuf/compiler/java/*.lo
+ -rm -f google/protobuf/compiler/javamicro/*.$(OBJEXT)
+ -rm -f google/protobuf/compiler/javamicro/*.lo
+ -rm -f google/protobuf/compiler/javanano/*.$(OBJEXT)
+ -rm -f google/protobuf/compiler/javanano/*.lo
+ -rm -f google/protobuf/compiler/python/*.$(OBJEXT)
+ -rm -f google/protobuf/compiler/python/*.lo
+ -rm -f google/protobuf/io/*.$(OBJEXT)
+ -rm -f google/protobuf/io/*.lo
+ -rm -f google/protobuf/stubs/*.$(OBJEXT)
+ -rm -f google/protobuf/stubs/*.lo
+ -rm -f google/protobuf/testing/*.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/code_generator.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coded_stream.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/command_line_interface.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_enum.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_enum_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_extension.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_file.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_generator.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_helpers.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_message.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_message_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_primitive_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_service.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpp_string_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/descriptor.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/descriptor.pb.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/descriptor_database.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynamic_message.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extension_set.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extension_set_heavy.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generated_message_reflection.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generated_message_util.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gzip_stream.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/importer.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_enum.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_enum_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_extension.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_file.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_generator.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_helpers.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_message.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_message_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_primitive_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_service.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_enum.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_enum_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_file.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_generator.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_helpers.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_message.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_message_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_primitive_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javanano_enum.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javanano_enum_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javanano_extension.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javanano_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javanano_file.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javanano_generator.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javanano_helpers.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javanano_message.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javanano_message_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javanano_primitive_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message_lite.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/once.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.pb.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printer.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-file.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-lite_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-test_util_lite.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-coded_stream_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-command_line_interface_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-common_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-cpp_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-descriptor_database_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-descriptor_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-dynamic_message_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-extension_set_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-file.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-googletest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-importer_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-java_plugin_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-message_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-mock_code_generator.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-once_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-parser_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-printer_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-python_plugin_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-reflection_ops_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-repeated_field_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-structurally_valid_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-strutil_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-test_util.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-text_format_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-tokenizer_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_empty.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_import.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_lite.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_mset.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-wire_format_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/python_generator.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reflection_ops.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repeated_field.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/service.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/structurally_valid.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strutil.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subprocess.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/substitute.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin-file.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin-mock_code_generator.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin-test_plugin.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/text_format.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tokenizer.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unknown_field_set.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wire_format.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wire_format_lite.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zcgunzip.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zcgzip.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zero_copy_stream.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zero_copy_stream_impl.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zero_copy_stream_impl_lite.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zip_writer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/descriptor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/descriptor.pb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/descriptor_database.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/dynamic_message.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/extension_set.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/extension_set_heavy.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/generated_message_reflection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/generated_message_util.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/message.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/message_lite.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-test_util.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/reflection_ops.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/repeated_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/service.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/text_format.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/unknown_field_set.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/wire_format.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/wire_format_lite.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/code_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/command_line_interface.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/importer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/parser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/plugin.pb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/subprocess.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/zip_writer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_enum.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_enum_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_extension.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_helpers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_message.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_message_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_primitive_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_service.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_string_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_doc_comment.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_enum.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_enum_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_extension.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_generator_factory.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_helpers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_lazy_message_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_message.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_message_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_name_resolver.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_primitive_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_service.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_shared_code_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_string_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_enum.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_enum_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_helpers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_message.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_message_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_primitive_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_enum.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_enum_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_extension.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_helpers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_message.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_message_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_primitive_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/python/$(DEPDIR)/python_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/coded_stream.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/gzip_stream.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/printer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/strtod.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/tokenizer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/zero_copy_stream.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/zero_copy_stream_impl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/zero_copy_stream_impl_lite.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/atomicops_internals_x86_gcc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/atomicops_internals_x86_msvc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/common.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/once.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/stringprintf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/structurally_valid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/strutil.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/substitute.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/test_plugin-file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/zcgunzip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/zcgzip.Po@am__quote@
.cc.o:
-@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cc.obj:
-@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cc.lo:
-@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
-
-common.lo: google/protobuf/stubs/common.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT common.lo -MD -MP -MF $(DEPDIR)/common.Tpo -c -o common.lo `test -f 'google/protobuf/stubs/common.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/common.Tpo $(DEPDIR)/common.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/common.cc' object='common.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o common.lo `test -f 'google/protobuf/stubs/common.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common.cc
-
-once.lo: google/protobuf/stubs/once.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT once.lo -MD -MP -MF $(DEPDIR)/once.Tpo -c -o once.lo `test -f 'google/protobuf/stubs/once.cc' || echo '$(srcdir)/'`google/protobuf/stubs/once.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/once.Tpo $(DEPDIR)/once.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/once.cc' object='once.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o once.lo `test -f 'google/protobuf/stubs/once.cc' || echo '$(srcdir)/'`google/protobuf/stubs/once.cc
-
-hash.lo: google/protobuf/stubs/hash.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hash.lo -MD -MP -MF $(DEPDIR)/hash.Tpo -c -o hash.lo `test -f 'google/protobuf/stubs/hash.cc' || echo '$(srcdir)/'`google/protobuf/stubs/hash.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/hash.Tpo $(DEPDIR)/hash.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/hash.cc' object='hash.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hash.lo `test -f 'google/protobuf/stubs/hash.cc' || echo '$(srcdir)/'`google/protobuf/stubs/hash.cc
-
-extension_set.lo: google/protobuf/extension_set.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT extension_set.lo -MD -MP -MF $(DEPDIR)/extension_set.Tpo -c -o extension_set.lo `test -f 'google/protobuf/extension_set.cc' || echo '$(srcdir)/'`google/protobuf/extension_set.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/extension_set.Tpo $(DEPDIR)/extension_set.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/extension_set.cc' object='extension_set.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o extension_set.lo `test -f 'google/protobuf/extension_set.cc' || echo '$(srcdir)/'`google/protobuf/extension_set.cc
-
-generated_message_util.lo: google/protobuf/generated_message_util.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT generated_message_util.lo -MD -MP -MF $(DEPDIR)/generated_message_util.Tpo -c -o generated_message_util.lo `test -f 'google/protobuf/generated_message_util.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_util.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/generated_message_util.Tpo $(DEPDIR)/generated_message_util.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/generated_message_util.cc' object='generated_message_util.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o generated_message_util.lo `test -f 'google/protobuf/generated_message_util.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_util.cc
-
-message_lite.lo: google/protobuf/message_lite.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT message_lite.lo -MD -MP -MF $(DEPDIR)/message_lite.Tpo -c -o message_lite.lo `test -f 'google/protobuf/message_lite.cc' || echo '$(srcdir)/'`google/protobuf/message_lite.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/message_lite.Tpo $(DEPDIR)/message_lite.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/message_lite.cc' object='message_lite.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o message_lite.lo `test -f 'google/protobuf/message_lite.cc' || echo '$(srcdir)/'`google/protobuf/message_lite.cc
-
-repeated_field.lo: google/protobuf/repeated_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT repeated_field.lo -MD -MP -MF $(DEPDIR)/repeated_field.Tpo -c -o repeated_field.lo `test -f 'google/protobuf/repeated_field.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/repeated_field.Tpo $(DEPDIR)/repeated_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/repeated_field.cc' object='repeated_field.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o repeated_field.lo `test -f 'google/protobuf/repeated_field.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field.cc
-
-wire_format_lite.lo: google/protobuf/wire_format_lite.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wire_format_lite.lo -MD -MP -MF $(DEPDIR)/wire_format_lite.Tpo -c -o wire_format_lite.lo `test -f 'google/protobuf/wire_format_lite.cc' || echo '$(srcdir)/'`google/protobuf/wire_format_lite.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wire_format_lite.Tpo $(DEPDIR)/wire_format_lite.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/wire_format_lite.cc' object='wire_format_lite.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wire_format_lite.lo `test -f 'google/protobuf/wire_format_lite.cc' || echo '$(srcdir)/'`google/protobuf/wire_format_lite.cc
-
-coded_stream.lo: google/protobuf/io/coded_stream.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT coded_stream.lo -MD -MP -MF $(DEPDIR)/coded_stream.Tpo -c -o coded_stream.lo `test -f 'google/protobuf/io/coded_stream.cc' || echo '$(srcdir)/'`google/protobuf/io/coded_stream.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/coded_stream.Tpo $(DEPDIR)/coded_stream.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/coded_stream.cc' object='coded_stream.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o coded_stream.lo `test -f 'google/protobuf/io/coded_stream.cc' || echo '$(srcdir)/'`google/protobuf/io/coded_stream.cc
-
-zero_copy_stream.lo: google/protobuf/io/zero_copy_stream.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zero_copy_stream.lo -MD -MP -MF $(DEPDIR)/zero_copy_stream.Tpo -c -o zero_copy_stream.lo `test -f 'google/protobuf/io/zero_copy_stream.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zero_copy_stream.Tpo $(DEPDIR)/zero_copy_stream.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/zero_copy_stream.cc' object='zero_copy_stream.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zero_copy_stream.lo `test -f 'google/protobuf/io/zero_copy_stream.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream.cc
-
-zero_copy_stream_impl_lite.lo: google/protobuf/io/zero_copy_stream_impl_lite.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zero_copy_stream_impl_lite.lo -MD -MP -MF $(DEPDIR)/zero_copy_stream_impl_lite.Tpo -c -o zero_copy_stream_impl_lite.lo `test -f 'google/protobuf/io/zero_copy_stream_impl_lite.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_impl_lite.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zero_copy_stream_impl_lite.Tpo $(DEPDIR)/zero_copy_stream_impl_lite.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/zero_copy_stream_impl_lite.cc' object='zero_copy_stream_impl_lite.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zero_copy_stream_impl_lite.lo `test -f 'google/protobuf/io/zero_copy_stream_impl_lite.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_impl_lite.cc
-
-strutil.lo: google/protobuf/stubs/strutil.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT strutil.lo -MD -MP -MF $(DEPDIR)/strutil.Tpo -c -o strutil.lo `test -f 'google/protobuf/stubs/strutil.cc' || echo '$(srcdir)/'`google/protobuf/stubs/strutil.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/strutil.Tpo $(DEPDIR)/strutil.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/strutil.cc' object='strutil.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o strutil.lo `test -f 'google/protobuf/stubs/strutil.cc' || echo '$(srcdir)/'`google/protobuf/stubs/strutil.cc
-
-substitute.lo: google/protobuf/stubs/substitute.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT substitute.lo -MD -MP -MF $(DEPDIR)/substitute.Tpo -c -o substitute.lo `test -f 'google/protobuf/stubs/substitute.cc' || echo '$(srcdir)/'`google/protobuf/stubs/substitute.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/substitute.Tpo $(DEPDIR)/substitute.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/substitute.cc' object='substitute.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o substitute.lo `test -f 'google/protobuf/stubs/substitute.cc' || echo '$(srcdir)/'`google/protobuf/stubs/substitute.cc
-
-structurally_valid.lo: google/protobuf/stubs/structurally_valid.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT structurally_valid.lo -MD -MP -MF $(DEPDIR)/structurally_valid.Tpo -c -o structurally_valid.lo `test -f 'google/protobuf/stubs/structurally_valid.cc' || echo '$(srcdir)/'`google/protobuf/stubs/structurally_valid.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/structurally_valid.Tpo $(DEPDIR)/structurally_valid.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/structurally_valid.cc' object='structurally_valid.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o structurally_valid.lo `test -f 'google/protobuf/stubs/structurally_valid.cc' || echo '$(srcdir)/'`google/protobuf/stubs/structurally_valid.cc
-
-descriptor.lo: google/protobuf/descriptor.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT descriptor.lo -MD -MP -MF $(DEPDIR)/descriptor.Tpo -c -o descriptor.lo `test -f 'google/protobuf/descriptor.cc' || echo '$(srcdir)/'`google/protobuf/descriptor.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/descriptor.Tpo $(DEPDIR)/descriptor.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor.cc' object='descriptor.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o descriptor.lo `test -f 'google/protobuf/descriptor.cc' || echo '$(srcdir)/'`google/protobuf/descriptor.cc
-
-descriptor.pb.lo: google/protobuf/descriptor.pb.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT descriptor.pb.lo -MD -MP -MF $(DEPDIR)/descriptor.pb.Tpo -c -o descriptor.pb.lo `test -f 'google/protobuf/descriptor.pb.cc' || echo '$(srcdir)/'`google/protobuf/descriptor.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/descriptor.pb.Tpo $(DEPDIR)/descriptor.pb.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor.pb.cc' object='descriptor.pb.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o descriptor.pb.lo `test -f 'google/protobuf/descriptor.pb.cc' || echo '$(srcdir)/'`google/protobuf/descriptor.pb.cc
-
-descriptor_database.lo: google/protobuf/descriptor_database.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT descriptor_database.lo -MD -MP -MF $(DEPDIR)/descriptor_database.Tpo -c -o descriptor_database.lo `test -f 'google/protobuf/descriptor_database.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_database.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/descriptor_database.Tpo $(DEPDIR)/descriptor_database.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor_database.cc' object='descriptor_database.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o descriptor_database.lo `test -f 'google/protobuf/descriptor_database.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_database.cc
-
-dynamic_message.lo: google/protobuf/dynamic_message.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dynamic_message.lo -MD -MP -MF $(DEPDIR)/dynamic_message.Tpo -c -o dynamic_message.lo `test -f 'google/protobuf/dynamic_message.cc' || echo '$(srcdir)/'`google/protobuf/dynamic_message.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/dynamic_message.Tpo $(DEPDIR)/dynamic_message.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/dynamic_message.cc' object='dynamic_message.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dynamic_message.lo `test -f 'google/protobuf/dynamic_message.cc' || echo '$(srcdir)/'`google/protobuf/dynamic_message.cc
-
-extension_set_heavy.lo: google/protobuf/extension_set_heavy.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT extension_set_heavy.lo -MD -MP -MF $(DEPDIR)/extension_set_heavy.Tpo -c -o extension_set_heavy.lo `test -f 'google/protobuf/extension_set_heavy.cc' || echo '$(srcdir)/'`google/protobuf/extension_set_heavy.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/extension_set_heavy.Tpo $(DEPDIR)/extension_set_heavy.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/extension_set_heavy.cc' object='extension_set_heavy.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o extension_set_heavy.lo `test -f 'google/protobuf/extension_set_heavy.cc' || echo '$(srcdir)/'`google/protobuf/extension_set_heavy.cc
-
-generated_message_reflection.lo: google/protobuf/generated_message_reflection.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT generated_message_reflection.lo -MD -MP -MF $(DEPDIR)/generated_message_reflection.Tpo -c -o generated_message_reflection.lo `test -f 'google/protobuf/generated_message_reflection.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_reflection.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/generated_message_reflection.Tpo $(DEPDIR)/generated_message_reflection.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/generated_message_reflection.cc' object='generated_message_reflection.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o generated_message_reflection.lo `test -f 'google/protobuf/generated_message_reflection.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_reflection.cc
-
-message.lo: google/protobuf/message.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT message.lo -MD -MP -MF $(DEPDIR)/message.Tpo -c -o message.lo `test -f 'google/protobuf/message.cc' || echo '$(srcdir)/'`google/protobuf/message.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/message.Tpo $(DEPDIR)/message.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/message.cc' object='message.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o message.lo `test -f 'google/protobuf/message.cc' || echo '$(srcdir)/'`google/protobuf/message.cc
-
-reflection_ops.lo: google/protobuf/reflection_ops.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT reflection_ops.lo -MD -MP -MF $(DEPDIR)/reflection_ops.Tpo -c -o reflection_ops.lo `test -f 'google/protobuf/reflection_ops.cc' || echo '$(srcdir)/'`google/protobuf/reflection_ops.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/reflection_ops.Tpo $(DEPDIR)/reflection_ops.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/reflection_ops.cc' object='reflection_ops.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o reflection_ops.lo `test -f 'google/protobuf/reflection_ops.cc' || echo '$(srcdir)/'`google/protobuf/reflection_ops.cc
-
-service.lo: google/protobuf/service.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT service.lo -MD -MP -MF $(DEPDIR)/service.Tpo -c -o service.lo `test -f 'google/protobuf/service.cc' || echo '$(srcdir)/'`google/protobuf/service.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/service.Tpo $(DEPDIR)/service.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/service.cc' object='service.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o service.lo `test -f 'google/protobuf/service.cc' || echo '$(srcdir)/'`google/protobuf/service.cc
-
-text_format.lo: google/protobuf/text_format.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT text_format.lo -MD -MP -MF $(DEPDIR)/text_format.Tpo -c -o text_format.lo `test -f 'google/protobuf/text_format.cc' || echo '$(srcdir)/'`google/protobuf/text_format.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/text_format.Tpo $(DEPDIR)/text_format.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/text_format.cc' object='text_format.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o text_format.lo `test -f 'google/protobuf/text_format.cc' || echo '$(srcdir)/'`google/protobuf/text_format.cc
-
-unknown_field_set.lo: google/protobuf/unknown_field_set.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unknown_field_set.lo -MD -MP -MF $(DEPDIR)/unknown_field_set.Tpo -c -o unknown_field_set.lo `test -f 'google/protobuf/unknown_field_set.cc' || echo '$(srcdir)/'`google/protobuf/unknown_field_set.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/unknown_field_set.Tpo $(DEPDIR)/unknown_field_set.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unknown_field_set.cc' object='unknown_field_set.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unknown_field_set.lo `test -f 'google/protobuf/unknown_field_set.cc' || echo '$(srcdir)/'`google/protobuf/unknown_field_set.cc
-
-wire_format.lo: google/protobuf/wire_format.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wire_format.lo -MD -MP -MF $(DEPDIR)/wire_format.Tpo -c -o wire_format.lo `test -f 'google/protobuf/wire_format.cc' || echo '$(srcdir)/'`google/protobuf/wire_format.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wire_format.Tpo $(DEPDIR)/wire_format.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/wire_format.cc' object='wire_format.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wire_format.lo `test -f 'google/protobuf/wire_format.cc' || echo '$(srcdir)/'`google/protobuf/wire_format.cc
-
-gzip_stream.lo: google/protobuf/io/gzip_stream.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gzip_stream.lo -MD -MP -MF $(DEPDIR)/gzip_stream.Tpo -c -o gzip_stream.lo `test -f 'google/protobuf/io/gzip_stream.cc' || echo '$(srcdir)/'`google/protobuf/io/gzip_stream.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/gzip_stream.Tpo $(DEPDIR)/gzip_stream.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/gzip_stream.cc' object='gzip_stream.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gzip_stream.lo `test -f 'google/protobuf/io/gzip_stream.cc' || echo '$(srcdir)/'`google/protobuf/io/gzip_stream.cc
-
-printer.lo: google/protobuf/io/printer.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT printer.lo -MD -MP -MF $(DEPDIR)/printer.Tpo -c -o printer.lo `test -f 'google/protobuf/io/printer.cc' || echo '$(srcdir)/'`google/protobuf/io/printer.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/printer.Tpo $(DEPDIR)/printer.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/printer.cc' object='printer.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o printer.lo `test -f 'google/protobuf/io/printer.cc' || echo '$(srcdir)/'`google/protobuf/io/printer.cc
-
-tokenizer.lo: google/protobuf/io/tokenizer.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT tokenizer.lo -MD -MP -MF $(DEPDIR)/tokenizer.Tpo -c -o tokenizer.lo `test -f 'google/protobuf/io/tokenizer.cc' || echo '$(srcdir)/'`google/protobuf/io/tokenizer.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/tokenizer.Tpo $(DEPDIR)/tokenizer.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/tokenizer.cc' object='tokenizer.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o tokenizer.lo `test -f 'google/protobuf/io/tokenizer.cc' || echo '$(srcdir)/'`google/protobuf/io/tokenizer.cc
-
-zero_copy_stream_impl.lo: google/protobuf/io/zero_copy_stream_impl.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zero_copy_stream_impl.lo -MD -MP -MF $(DEPDIR)/zero_copy_stream_impl.Tpo -c -o zero_copy_stream_impl.lo `test -f 'google/protobuf/io/zero_copy_stream_impl.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_impl.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zero_copy_stream_impl.Tpo $(DEPDIR)/zero_copy_stream_impl.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/zero_copy_stream_impl.cc' object='zero_copy_stream_impl.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zero_copy_stream_impl.lo `test -f 'google/protobuf/io/zero_copy_stream_impl.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_impl.cc
-
-importer.lo: google/protobuf/compiler/importer.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT importer.lo -MD -MP -MF $(DEPDIR)/importer.Tpo -c -o importer.lo `test -f 'google/protobuf/compiler/importer.cc' || echo '$(srcdir)/'`google/protobuf/compiler/importer.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/importer.Tpo $(DEPDIR)/importer.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/importer.cc' object='importer.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o importer.lo `test -f 'google/protobuf/compiler/importer.cc' || echo '$(srcdir)/'`google/protobuf/compiler/importer.cc
-
-parser.lo: google/protobuf/compiler/parser.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT parser.lo -MD -MP -MF $(DEPDIR)/parser.Tpo -c -o parser.lo `test -f 'google/protobuf/compiler/parser.cc' || echo '$(srcdir)/'`google/protobuf/compiler/parser.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/parser.Tpo $(DEPDIR)/parser.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/parser.cc' object='parser.lo' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o parser.lo `test -f 'google/protobuf/compiler/parser.cc' || echo '$(srcdir)/'`google/protobuf/compiler/parser.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
-code_generator.lo: google/protobuf/compiler/code_generator.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT code_generator.lo -MD -MP -MF $(DEPDIR)/code_generator.Tpo -c -o code_generator.lo `test -f 'google/protobuf/compiler/code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/code_generator.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/code_generator.Tpo $(DEPDIR)/code_generator.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/code_generator.cc' object='code_generator.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o: google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o code_generator.lo `test -f 'google/protobuf/compiler/code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/code_generator.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc
-command_line_interface.lo: google/protobuf/compiler/command_line_interface.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT command_line_interface.lo -MD -MP -MF $(DEPDIR)/command_line_interface.Tpo -c -o command_line_interface.lo `test -f 'google/protobuf/compiler/command_line_interface.cc' || echo '$(srcdir)/'`google/protobuf/compiler/command_line_interface.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/command_line_interface.Tpo $(DEPDIR)/command_line_interface.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/command_line_interface.cc' object='command_line_interface.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj: google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o command_line_interface.lo `test -f 'google/protobuf/compiler/command_line_interface.cc' || echo '$(srcdir)/'`google/protobuf/compiler/command_line_interface.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi`
-plugin.lo: google/protobuf/compiler/plugin.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT plugin.lo -MD -MP -MF $(DEPDIR)/plugin.Tpo -c -o plugin.lo `test -f 'google/protobuf/compiler/plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/plugin.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/plugin.Tpo $(DEPDIR)/plugin.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/plugin.cc' object='plugin.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-test_util.o: google/protobuf/test_util.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-test_util.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/test_util.cc' object='google/protobuf/protobuf_lazy_descriptor_test-test_util.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o plugin.lo `test -f 'google/protobuf/compiler/plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/plugin.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc
-plugin.pb.lo: google/protobuf/compiler/plugin.pb.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT plugin.pb.lo -MD -MP -MF $(DEPDIR)/plugin.pb.Tpo -c -o plugin.pb.lo `test -f 'google/protobuf/compiler/plugin.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/plugin.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/plugin.pb.Tpo $(DEPDIR)/plugin.pb.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/plugin.pb.cc' object='plugin.pb.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-test_util.obj: google/protobuf/test_util.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-test_util.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/test_util.cc' object='google/protobuf/protobuf_lazy_descriptor_test-test_util.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o plugin.pb.lo `test -f 'google/protobuf/compiler/plugin.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/plugin.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi`
-subprocess.lo: google/protobuf/compiler/subprocess.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT subprocess.lo -MD -MP -MF $(DEPDIR)/subprocess.Tpo -c -o subprocess.lo `test -f 'google/protobuf/compiler/subprocess.cc' || echo '$(srcdir)/'`google/protobuf/compiler/subprocess.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/subprocess.Tpo $(DEPDIR)/subprocess.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/subprocess.cc' object='subprocess.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.o: google/protobuf/testing/googletest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.o -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/testing/googletest.cc' object='google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o subprocess.lo `test -f 'google/protobuf/compiler/subprocess.cc' || echo '$(srcdir)/'`google/protobuf/compiler/subprocess.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc
-zip_writer.lo: google/protobuf/compiler/zip_writer.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zip_writer.lo -MD -MP -MF $(DEPDIR)/zip_writer.Tpo -c -o zip_writer.lo `test -f 'google/protobuf/compiler/zip_writer.cc' || echo '$(srcdir)/'`google/protobuf/compiler/zip_writer.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zip_writer.Tpo $(DEPDIR)/zip_writer.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/zip_writer.cc' object='zip_writer.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.obj: google/protobuf/testing/googletest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.obj -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/testing/googletest.cc' object='google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zip_writer.lo `test -f 'google/protobuf/compiler/zip_writer.cc' || echo '$(srcdir)/'`google/protobuf/compiler/zip_writer.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi`
-cpp_enum.lo: google/protobuf/compiler/cpp/cpp_enum.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_enum.lo -MD -MP -MF $(DEPDIR)/cpp_enum.Tpo -c -o cpp_enum.lo `test -f 'google/protobuf/compiler/cpp/cpp_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_enum.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_enum.Tpo $(DEPDIR)/cpp_enum.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_enum.cc' object='cpp_enum.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/testing/protobuf_lazy_descriptor_test-file.o: google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_lazy_descriptor_test-file.o -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/testing/file.cc' object='google/protobuf/testing/protobuf_lazy_descriptor_test-file.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_enum.lo `test -f 'google/protobuf/compiler/cpp/cpp_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_enum.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
-cpp_enum_field.lo: google/protobuf/compiler/cpp/cpp_enum_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_enum_field.lo -MD -MP -MF $(DEPDIR)/cpp_enum_field.Tpo -c -o cpp_enum_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_enum_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_enum_field.Tpo $(DEPDIR)/cpp_enum_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_enum_field.cc' object='cpp_enum_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/testing/protobuf_lazy_descriptor_test-file.obj: google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_lazy_descriptor_test-file.obj -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/testing/file.cc' object='google/protobuf/testing/protobuf_lazy_descriptor_test-file.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_enum_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_enum_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
-cpp_extension.lo: google/protobuf/compiler/cpp/cpp_extension.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_extension.lo -MD -MP -MF $(DEPDIR)/cpp_extension.Tpo -c -o cpp_extension.lo `test -f 'google/protobuf/compiler/cpp/cpp_extension.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_extension.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_extension.Tpo $(DEPDIR)/cpp_extension.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_extension.cc' object='cpp_extension.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.o: google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_lite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_extension.lo `test -f 'google/protobuf/compiler/cpp/cpp_extension.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_extension.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
-cpp_field.lo: google/protobuf/compiler/cpp/cpp_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_field.lo -MD -MP -MF $(DEPDIR)/cpp_field.Tpo -c -o cpp_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_field.Tpo $(DEPDIR)/cpp_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_field.cc' object='cpp_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.obj: google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_lite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
-cpp_file.lo: google/protobuf/compiler/cpp/cpp_file.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_file.lo -MD -MP -MF $(DEPDIR)/cpp_file.Tpo -c -o cpp_file.lo `test -f 'google/protobuf/compiler/cpp/cpp_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_file.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_file.Tpo $(DEPDIR)/cpp_file.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_file.cc' object='cpp_file.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.o: google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_lite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_file.lo `test -f 'google/protobuf/compiler/cpp/cpp_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_file.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
-cpp_generator.lo: google/protobuf/compiler/cpp/cpp_generator.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_generator.lo -MD -MP -MF $(DEPDIR)/cpp_generator.Tpo -c -o cpp_generator.lo `test -f 'google/protobuf/compiler/cpp/cpp_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_generator.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_generator.Tpo $(DEPDIR)/cpp_generator.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_generator.cc' object='cpp_generator.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_lite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_generator.lo `test -f 'google/protobuf/compiler/cpp/cpp_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_generator.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
-cpp_helpers.lo: google/protobuf/compiler/cpp/cpp_helpers.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_helpers.lo -MD -MP -MF $(DEPDIR)/cpp_helpers.Tpo -c -o cpp_helpers.lo `test -f 'google/protobuf/compiler/cpp/cpp_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_helpers.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_helpers.Tpo $(DEPDIR)/cpp_helpers.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_helpers.cc' object='cpp_helpers.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o: google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_public_lite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_helpers.lo `test -f 'google/protobuf/compiler/cpp/cpp_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_helpers.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
-cpp_message.lo: google/protobuf/compiler/cpp/cpp_message.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_message.lo -MD -MP -MF $(DEPDIR)/cpp_message.Tpo -c -o cpp_message.lo `test -f 'google/protobuf/compiler/cpp/cpp_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_message.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_message.Tpo $(DEPDIR)/cpp_message.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_message.cc' object='cpp_message.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj: google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_public_lite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_message.lo `test -f 'google/protobuf/compiler/cpp/cpp_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_message.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
-cpp_message_field.lo: google/protobuf/compiler/cpp/cpp_message_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_message_field.lo -MD -MP -MF $(DEPDIR)/cpp_message_field.Tpo -c -o cpp_message_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_message_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_message_field.Tpo $(DEPDIR)/cpp_message_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_message_field.cc' object='cpp_message_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.o: google/protobuf/unittest.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_message_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_message_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
-cpp_primitive_field.lo: google/protobuf/compiler/cpp/cpp_primitive_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_primitive_field.lo -MD -MP -MF $(DEPDIR)/cpp_primitive_field.Tpo -c -o cpp_primitive_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_primitive_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_primitive_field.Tpo $(DEPDIR)/cpp_primitive_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_primitive_field.cc' object='cpp_primitive_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.obj: google/protobuf/unittest.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_primitive_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_primitive_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi`
-cpp_service.lo: google/protobuf/compiler/cpp/cpp_service.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_service.lo -MD -MP -MF $(DEPDIR)/cpp_service.Tpo -c -o cpp_service.lo `test -f 'google/protobuf/compiler/cpp/cpp_service.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_service.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_service.Tpo $(DEPDIR)/cpp_service.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_service.cc' object='cpp_service.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.o: google/protobuf/unittest_empty.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_empty.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_service.lo `test -f 'google/protobuf/compiler/cpp/cpp_service.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_service.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc
-cpp_string_field.lo: google/protobuf/compiler/cpp/cpp_string_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_string_field.lo -MD -MP -MF $(DEPDIR)/cpp_string_field.Tpo -c -o cpp_string_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_string_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_string_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/cpp_string_field.Tpo $(DEPDIR)/cpp_string_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_string_field.cc' object='cpp_string_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.obj: google/protobuf/unittest_empty.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_empty.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cpp_string_field.lo `test -f 'google/protobuf/compiler/cpp/cpp_string_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_string_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi`
-java_enum.lo: google/protobuf/compiler/java/java_enum.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_enum.lo -MD -MP -MF $(DEPDIR)/java_enum.Tpo -c -o java_enum.lo `test -f 'google/protobuf/compiler/java/java_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_enum.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_enum.Tpo $(DEPDIR)/java_enum.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_enum.cc' object='java_enum.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.o: google/protobuf/unittest_import.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_enum.lo `test -f 'google/protobuf/compiler/java/java_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_enum.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc
-java_enum_field.lo: google/protobuf/compiler/java/java_enum_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_enum_field.lo -MD -MP -MF $(DEPDIR)/java_enum_field.Tpo -c -o java_enum_field.lo `test -f 'google/protobuf/compiler/java/java_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_enum_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_enum_field.Tpo $(DEPDIR)/java_enum_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_enum_field.cc' object='java_enum_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.obj: google/protobuf/unittest_import.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_enum_field.lo `test -f 'google/protobuf/compiler/java/java_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_enum_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
-java_extension.lo: google/protobuf/compiler/java/java_extension.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_extension.lo -MD -MP -MF $(DEPDIR)/java_extension.Tpo -c -o java_extension.lo `test -f 'google/protobuf/compiler/java/java_extension.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_extension.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_extension.Tpo $(DEPDIR)/java_extension.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_extension.cc' object='java_extension.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.o: google/protobuf/unittest_import_public.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_public.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_extension.lo `test -f 'google/protobuf/compiler/java/java_extension.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_extension.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc
-java_field.lo: google/protobuf/compiler/java/java_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_field.lo -MD -MP -MF $(DEPDIR)/java_field.Tpo -c -o java_field.lo `test -f 'google/protobuf/compiler/java/java_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_field.Tpo $(DEPDIR)/java_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_field.cc' object='java_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.obj: google/protobuf/unittest_import_public.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_public.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_field.lo `test -f 'google/protobuf/compiler/java/java_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi`
-java_file.lo: google/protobuf/compiler/java/java_file.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_file.lo -MD -MP -MF $(DEPDIR)/java_file.Tpo -c -o java_file.lo `test -f 'google/protobuf/compiler/java/java_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_file.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_file.Tpo $(DEPDIR)/java_file.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_file.cc' object='java_file.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.o: google/protobuf/unittest_mset.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_mset.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_file.lo `test -f 'google/protobuf/compiler/java/java_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_file.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
-java_generator.lo: google/protobuf/compiler/java/java_generator.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_generator.lo -MD -MP -MF $(DEPDIR)/java_generator.Tpo -c -o java_generator.lo `test -f 'google/protobuf/compiler/java/java_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_generator.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_generator.Tpo $(DEPDIR)/java_generator.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_generator.cc' object='java_generator.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.obj: google/protobuf/unittest_mset.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_mset.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_generator.lo `test -f 'google/protobuf/compiler/java/java_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_generator.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi`
-java_helpers.lo: google/protobuf/compiler/java/java_helpers.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_helpers.lo -MD -MP -MF $(DEPDIR)/java_helpers.Tpo -c -o java_helpers.lo `test -f 'google/protobuf/compiler/java/java_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_helpers.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_helpers.Tpo $(DEPDIR)/java_helpers.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_helpers.cc' object='java_helpers.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o: google/protobuf/unittest_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_optimize_for.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_helpers.lo `test -f 'google/protobuf/compiler/java/java_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_helpers.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc
-java_message.lo: google/protobuf/compiler/java/java_message.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_message.lo -MD -MP -MF $(DEPDIR)/java_message.Tpo -c -o java_message.lo `test -f 'google/protobuf/compiler/java/java_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_message.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_message.Tpo $(DEPDIR)/java_message.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_message.cc' object='java_message.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj: google/protobuf/unittest_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_optimize_for.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_message.lo `test -f 'google/protobuf/compiler/java/java_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_message.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi`
-java_message_field.lo: google/protobuf/compiler/java/java_message_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_message_field.lo -MD -MP -MF $(DEPDIR)/java_message_field.Tpo -c -o java_message_field.lo `test -f 'google/protobuf/compiler/java/java_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_message_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_message_field.Tpo $(DEPDIR)/java_message_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_message_field.cc' object='java_message_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o: google/protobuf/unittest_embed_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_message_field.lo `test -f 'google/protobuf/compiler/java/java_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_message_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc
-java_primitive_field.lo: google/protobuf/compiler/java/java_primitive_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_primitive_field.lo -MD -MP -MF $(DEPDIR)/java_primitive_field.Tpo -c -o java_primitive_field.lo `test -f 'google/protobuf/compiler/java/java_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_primitive_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_primitive_field.Tpo $(DEPDIR)/java_primitive_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_primitive_field.cc' object='java_primitive_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj: google/protobuf/unittest_embed_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_primitive_field.lo `test -f 'google/protobuf/compiler/java/java_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_primitive_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi`
-java_service.lo: google/protobuf/compiler/java/java_service.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_service.lo -MD -MP -MF $(DEPDIR)/java_service.Tpo -c -o java_service.lo `test -f 'google/protobuf/compiler/java/java_service.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_service.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_service.Tpo $(DEPDIR)/java_service.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_service.cc' object='java_service.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.o: google/protobuf/unittest_custom_options.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_custom_options.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_service.lo `test -f 'google/protobuf/compiler/java/java_service.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_service.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc
-javamicro_enum.lo: google/protobuf/compiler/javamicro/javamicro_enum.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_enum.lo -MD -MP -MF $(DEPDIR)/javamicro_enum.Tpo -c -o javamicro_enum.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_enum.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javamicro_enum.Tpo $(DEPDIR)/javamicro_enum.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_enum.cc' object='javamicro_enum.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj: google/protobuf/unittest_custom_options.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_custom_options.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_enum.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_enum.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi`
-javamicro_enum_field.lo: google/protobuf/compiler/javamicro/javamicro_enum_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_enum_field.lo -MD -MP -MF $(DEPDIR)/javamicro_enum_field.Tpo -c -o javamicro_enum_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_enum_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javamicro_enum_field.Tpo $(DEPDIR)/javamicro_enum_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_enum_field.cc' object='javamicro_enum_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o: google/protobuf/unittest_lite_imports_nonlite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_enum_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_enum_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc
-javamicro_field.lo: google/protobuf/compiler/javamicro/javamicro_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_field.lo -MD -MP -MF $(DEPDIR)/javamicro_field.Tpo -c -o javamicro_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javamicro_field.Tpo $(DEPDIR)/javamicro_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_field.cc' object='javamicro_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj: google/protobuf/unittest_lite_imports_nonlite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi`
-javamicro_file.lo: google/protobuf/compiler/javamicro/javamicro_file.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_file.lo -MD -MP -MF $(DEPDIR)/javamicro_file.Tpo -c -o javamicro_file.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_file.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javamicro_file.Tpo $(DEPDIR)/javamicro_file.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_file.cc' object='javamicro_file.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o: google/protobuf/unittest_no_generic_services.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_no_generic_services.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_file.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_file.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc
-javamicro_generator.lo: google/protobuf/compiler/javamicro/javamicro_generator.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_generator.lo -MD -MP -MF $(DEPDIR)/javamicro_generator.Tpo -c -o javamicro_generator.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_generator.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javamicro_generator.Tpo $(DEPDIR)/javamicro_generator.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_generator.cc' object='javamicro_generator.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj: google/protobuf/unittest_no_generic_services.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_no_generic_services.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_generator.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_generator.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi`
-javamicro_helpers.lo: google/protobuf/compiler/javamicro/javamicro_helpers.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_helpers.lo -MD -MP -MF $(DEPDIR)/javamicro_helpers.Tpo -c -o javamicro_helpers.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_helpers.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javamicro_helpers.Tpo $(DEPDIR)/javamicro_helpers.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_helpers.cc' object='javamicro_helpers.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_helpers.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_helpers.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
-javamicro_message.lo: google/protobuf/compiler/javamicro/javamicro_message.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_message.lo -MD -MP -MF $(DEPDIR)/javamicro_message.Tpo -c -o javamicro_message.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_message.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javamicro_message.Tpo $(DEPDIR)/javamicro_message.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_message.cc' object='javamicro_message.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_message.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_message.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi`
-javamicro_message_field.lo: google/protobuf/compiler/javamicro/javamicro_message_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_message_field.lo -MD -MP -MF $(DEPDIR)/javamicro_message_field.Tpo -c -o javamicro_message_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_message_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javamicro_message_field.Tpo $(DEPDIR)/javamicro_message_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_message_field.cc' object='javamicro_message_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lite_test-lite_unittest.o: google/protobuf/lite_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-lite_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo -c -o google/protobuf/protobuf_lite_test-lite_unittest.o `test -f 'google/protobuf/lite_unittest.cc' || echo '$(srcdir)/'`google/protobuf/lite_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/lite_unittest.cc' object='google/protobuf/protobuf_lite_test-lite_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_message_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_message_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-lite_unittest.o `test -f 'google/protobuf/lite_unittest.cc' || echo '$(srcdir)/'`google/protobuf/lite_unittest.cc
-javamicro_primitive_field.lo: google/protobuf/compiler/javamicro/javamicro_primitive_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_primitive_field.lo -MD -MP -MF $(DEPDIR)/javamicro_primitive_field.Tpo -c -o javamicro_primitive_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_primitive_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javamicro_primitive_field.Tpo $(DEPDIR)/javamicro_primitive_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_primitive_field.cc' object='javamicro_primitive_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lite_test-lite_unittest.obj: google/protobuf/lite_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-lite_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo -c -o google/protobuf/protobuf_lite_test-lite_unittest.obj `if test -f 'google/protobuf/lite_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/lite_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/lite_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/lite_unittest.cc' object='google/protobuf/protobuf_lite_test-lite_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_primitive_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_primitive_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-lite_unittest.obj `if test -f 'google/protobuf/lite_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/lite_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/lite_unittest.cc'; fi`
-javanano_enum.lo: google/protobuf/compiler/javanano/javanano_enum.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javanano_enum.lo -MD -MP -MF $(DEPDIR)/javanano_enum.Tpo -c -o javanano_enum.lo `test -f 'google/protobuf/compiler/javanano/javanano_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_enum.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javanano_enum.Tpo $(DEPDIR)/javanano_enum.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javanano/javanano_enum.cc' object='javanano_enum.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lite_test-test_util_lite.o: google/protobuf/test_util_lite.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-test_util_lite.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo -c -o google/protobuf/protobuf_lite_test-test_util_lite.o `test -f 'google/protobuf/test_util_lite.cc' || echo '$(srcdir)/'`google/protobuf/test_util_lite.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/test_util_lite.cc' object='google/protobuf/protobuf_lite_test-test_util_lite.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javanano_enum.lo `test -f 'google/protobuf/compiler/javanano/javanano_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_enum.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-test_util_lite.o `test -f 'google/protobuf/test_util_lite.cc' || echo '$(srcdir)/'`google/protobuf/test_util_lite.cc
-javanano_enum_field.lo: google/protobuf/compiler/javanano/javanano_enum_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javanano_enum_field.lo -MD -MP -MF $(DEPDIR)/javanano_enum_field.Tpo -c -o javanano_enum_field.lo `test -f 'google/protobuf/compiler/javanano/javanano_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_enum_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javanano_enum_field.Tpo $(DEPDIR)/javanano_enum_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javanano/javanano_enum_field.cc' object='javanano_enum_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lite_test-test_util_lite.obj: google/protobuf/test_util_lite.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-test_util_lite.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo -c -o google/protobuf/protobuf_lite_test-test_util_lite.obj `if test -f 'google/protobuf/test_util_lite.cc'; then $(CYGPATH_W) 'google/protobuf/test_util_lite.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util_lite.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/test_util_lite.cc' object='google/protobuf/protobuf_lite_test-test_util_lite.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javanano_enum_field.lo `test -f 'google/protobuf/compiler/javanano/javanano_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_enum_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-test_util_lite.obj `if test -f 'google/protobuf/test_util_lite.cc'; then $(CYGPATH_W) 'google/protobuf/test_util_lite.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util_lite.cc'; fi`
-javanano_extension.lo: google/protobuf/compiler/javanano/javanano_extension.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javanano_extension.lo -MD -MP -MF $(DEPDIR)/javanano_extension.Tpo -c -o javanano_extension.lo `test -f 'google/protobuf/compiler/javanano/javanano_extension.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_extension.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javanano_extension.Tpo $(DEPDIR)/javanano_extension.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javanano/javanano_extension.cc' object='javanano_extension.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lite_test-unittest_lite.pb.o: google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-unittest_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo -c -o google/protobuf/protobuf_lite_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_lite.pb.cc' object='google/protobuf/protobuf_lite_test-unittest_lite.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javanano_extension.lo `test -f 'google/protobuf/compiler/javanano/javanano_extension.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_extension.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
-javanano_field.lo: google/protobuf/compiler/javanano/javanano_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javanano_field.lo -MD -MP -MF $(DEPDIR)/javanano_field.Tpo -c -o javanano_field.lo `test -f 'google/protobuf/compiler/javanano/javanano_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javanano_field.Tpo $(DEPDIR)/javanano_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javanano/javanano_field.cc' object='javanano_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lite_test-unittest_lite.pb.obj: google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-unittest_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo -c -o google/protobuf/protobuf_lite_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_lite.pb.cc' object='google/protobuf/protobuf_lite_test-unittest_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javanano_field.lo `test -f 'google/protobuf/compiler/javanano/javanano_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
-javanano_file.lo: google/protobuf/compiler/javanano/javanano_file.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javanano_file.lo -MD -MP -MF $(DEPDIR)/javanano_file.Tpo -c -o javanano_file.lo `test -f 'google/protobuf/compiler/javanano/javanano_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_file.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javanano_file.Tpo $(DEPDIR)/javanano_file.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javanano/javanano_file.cc' object='javanano_file.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lite_test-unittest_import_lite.pb.o: google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-unittest_import_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo -c -o google/protobuf/protobuf_lite_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_lite.pb.cc' object='google/protobuf/protobuf_lite_test-unittest_import_lite.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javanano_file.lo `test -f 'google/protobuf/compiler/javanano/javanano_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_file.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
-javanano_generator.lo: google/protobuf/compiler/javanano/javanano_generator.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javanano_generator.lo -MD -MP -MF $(DEPDIR)/javanano_generator.Tpo -c -o javanano_generator.lo `test -f 'google/protobuf/compiler/javanano/javanano_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_generator.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javanano_generator.Tpo $(DEPDIR)/javanano_generator.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javanano/javanano_generator.cc' object='javanano_generator.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lite_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-unittest_import_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo -c -o google/protobuf/protobuf_lite_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_lite.pb.cc' object='google/protobuf/protobuf_lite_test-unittest_import_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javanano_generator.lo `test -f 'google/protobuf/compiler/javanano/javanano_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_generator.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
-javanano_helpers.lo: google/protobuf/compiler/javanano/javanano_helpers.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javanano_helpers.lo -MD -MP -MF $(DEPDIR)/javanano_helpers.Tpo -c -o javanano_helpers.lo `test -f 'google/protobuf/compiler/javanano/javanano_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_helpers.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javanano_helpers.Tpo $(DEPDIR)/javanano_helpers.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javanano/javanano_helpers.cc' object='javanano_helpers.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.o: google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo -c -o google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_public_lite.pb.cc' object='google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javanano_helpers.lo `test -f 'google/protobuf/compiler/javanano/javanano_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_helpers.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
-javanano_message.lo: google/protobuf/compiler/javanano/javanano_message.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javanano_message.lo -MD -MP -MF $(DEPDIR)/javanano_message.Tpo -c -o javanano_message.lo `test -f 'google/protobuf/compiler/javanano/javanano_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_message.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javanano_message.Tpo $(DEPDIR)/javanano_message.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javanano/javanano_message.cc' object='javanano_message.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.obj: google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo -c -o google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_public_lite.pb.cc' object='google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javanano_message.lo `test -f 'google/protobuf/compiler/javanano/javanano_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_message.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
-javanano_message_field.lo: google/protobuf/compiler/javanano/javanano_message_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javanano_message_field.lo -MD -MP -MF $(DEPDIR)/javanano_message_field.Tpo -c -o javanano_message_field.lo `test -f 'google/protobuf/compiler/javanano/javanano_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_message_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javanano_message_field.Tpo $(DEPDIR)/javanano_message_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javanano/javanano_message_field.cc' object='javanano_message_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-common_unittest.o: google/protobuf/stubs/common_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-common_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-common_unittest.o `test -f 'google/protobuf/stubs/common_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/common_unittest.cc' object='google/protobuf/stubs/protobuf_test-common_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javanano_message_field.lo `test -f 'google/protobuf/compiler/javanano/javanano_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_message_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-common_unittest.o `test -f 'google/protobuf/stubs/common_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common_unittest.cc
-javanano_primitive_field.lo: google/protobuf/compiler/javanano/javanano_primitive_field.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javanano_primitive_field.lo -MD -MP -MF $(DEPDIR)/javanano_primitive_field.Tpo -c -o javanano_primitive_field.lo `test -f 'google/protobuf/compiler/javanano/javanano_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_primitive_field.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/javanano_primitive_field.Tpo $(DEPDIR)/javanano_primitive_field.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javanano/javanano_primitive_field.cc' object='javanano_primitive_field.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-common_unittest.obj: google/protobuf/stubs/common_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-common_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-common_unittest.obj `if test -f 'google/protobuf/stubs/common_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/common_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/common_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/common_unittest.cc' object='google/protobuf/stubs/protobuf_test-common_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javanano_primitive_field.lo `test -f 'google/protobuf/compiler/javanano/javanano_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javanano/javanano_primitive_field.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-common_unittest.obj `if test -f 'google/protobuf/stubs/common_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/common_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/common_unittest.cc'; fi`
-python_generator.lo: google/protobuf/compiler/python/python_generator.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT python_generator.lo -MD -MP -MF $(DEPDIR)/python_generator.Tpo -c -o python_generator.lo `test -f 'google/protobuf/compiler/python/python_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_generator.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/python_generator.Tpo $(DEPDIR)/python_generator.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/python/python_generator.cc' object='python_generator.lo' libtool=yes @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-once_unittest.o: google/protobuf/stubs/once_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-once_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-once_unittest.o `test -f 'google/protobuf/stubs/once_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/once_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/once_unittest.cc' object='google/protobuf/stubs/protobuf_test-once_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o python_generator.lo `test -f 'google/protobuf/compiler/python/python_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_generator.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-once_unittest.o `test -f 'google/protobuf/stubs/once_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/once_unittest.cc
-protobuf_lazy_descriptor_test-cpp_unittest.o: google/protobuf/compiler/cpp/cpp_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-cpp_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo -c -o protobuf_lazy_descriptor_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='protobuf_lazy_descriptor_test-cpp_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-once_unittest.obj: google/protobuf/stubs/once_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-once_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-once_unittest.obj `if test -f 'google/protobuf/stubs/once_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/once_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/once_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/once_unittest.cc' object='google/protobuf/stubs/protobuf_test-once_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-once_unittest.obj `if test -f 'google/protobuf/stubs/once_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/once_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/once_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-cpp_unittest.obj: google/protobuf/compiler/cpp/cpp_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-cpp_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo -c -o protobuf_lazy_descriptor_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='protobuf_lazy_descriptor_test-cpp_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-strutil_unittest.o: google/protobuf/stubs/strutil_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-strutil_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-strutil_unittest.o `test -f 'google/protobuf/stubs/strutil_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/strutil_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/strutil_unittest.cc' object='google/protobuf/stubs/protobuf_test-strutil_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-strutil_unittest.o `test -f 'google/protobuf/stubs/strutil_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/strutil_unittest.cc
-protobuf_lazy_descriptor_test-test_util.o: google/protobuf/test_util.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-test_util.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo -c -o protobuf_lazy_descriptor_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/test_util.cc' object='protobuf_lazy_descriptor_test-test_util.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-strutil_unittest.obj: google/protobuf/stubs/strutil_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-strutil_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-strutil_unittest.obj `if test -f 'google/protobuf/stubs/strutil_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/strutil_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/strutil_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/strutil_unittest.cc' object='google/protobuf/stubs/protobuf_test-strutil_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-strutil_unittest.obj `if test -f 'google/protobuf/stubs/strutil_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/strutil_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/strutil_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-test_util.obj: google/protobuf/test_util.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-test_util.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo -c -o protobuf_lazy_descriptor_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/test_util.cc' object='protobuf_lazy_descriptor_test-test_util.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-structurally_valid_unittest.o: google/protobuf/stubs/structurally_valid_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-structurally_valid_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-structurally_valid_unittest.o `test -f 'google/protobuf/stubs/structurally_valid_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/structurally_valid_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/structurally_valid_unittest.cc' object='google/protobuf/stubs/protobuf_test-structurally_valid_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-structurally_valid_unittest.o `test -f 'google/protobuf/stubs/structurally_valid_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/structurally_valid_unittest.cc
-protobuf_lazy_descriptor_test-googletest.o: google/protobuf/testing/googletest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-googletest.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo -c -o protobuf_lazy_descriptor_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/googletest.cc' object='protobuf_lazy_descriptor_test-googletest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-structurally_valid_unittest.obj: google/protobuf/stubs/structurally_valid_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-structurally_valid_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-structurally_valid_unittest.obj `if test -f 'google/protobuf/stubs/structurally_valid_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/structurally_valid_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/structurally_valid_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/structurally_valid_unittest.cc' object='google/protobuf/stubs/protobuf_test-structurally_valid_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-structurally_valid_unittest.obj `if test -f 'google/protobuf/stubs/structurally_valid_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/structurally_valid_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/structurally_valid_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-googletest.obj: google/protobuf/testing/googletest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-googletest.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo -c -o protobuf_lazy_descriptor_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/googletest.cc' object='protobuf_lazy_descriptor_test-googletest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-stringprintf_unittest.o: google/protobuf/stubs/stringprintf_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-stringprintf_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-stringprintf_unittest.o `test -f 'google/protobuf/stubs/stringprintf_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/stringprintf_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/stringprintf_unittest.cc' object='google/protobuf/stubs/protobuf_test-stringprintf_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-stringprintf_unittest.o `test -f 'google/protobuf/stubs/stringprintf_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/stringprintf_unittest.cc
-protobuf_lazy_descriptor_test-file.o: google/protobuf/testing/file.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-file.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo -c -o protobuf_lazy_descriptor_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-file.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='protobuf_lazy_descriptor_test-file.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-stringprintf_unittest.obj: google/protobuf/stubs/stringprintf_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-stringprintf_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-stringprintf_unittest.obj `if test -f 'google/protobuf/stubs/stringprintf_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/stringprintf_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/stringprintf_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/stringprintf_unittest.cc' object='google/protobuf/stubs/protobuf_test-stringprintf_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-stringprintf_unittest.obj `if test -f 'google/protobuf/stubs/stringprintf_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/stringprintf_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/stringprintf_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-file.obj: google/protobuf/testing/file.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-file.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo -c -o protobuf_lazy_descriptor_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-file.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='protobuf_lazy_descriptor_test-file.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-template_util_unittest.o: google/protobuf/stubs/template_util_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-template_util_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-template_util_unittest.o `test -f 'google/protobuf/stubs/template_util_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/template_util_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/template_util_unittest.cc' object='google/protobuf/stubs/protobuf_test-template_util_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-template_util_unittest.o `test -f 'google/protobuf/stubs/template_util_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/template_util_unittest.cc
-protobuf_lazy_descriptor_test-unittest_lite.pb.o: google/protobuf/unittest_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-template_util_unittest.obj: google/protobuf/stubs/template_util_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-template_util_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-template_util_unittest.obj `if test -f 'google/protobuf/stubs/template_util_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/template_util_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/template_util_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/template_util_unittest.cc' object='google/protobuf/stubs/protobuf_test-template_util_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-template_util_unittest.obj `if test -f 'google/protobuf/stubs/template_util_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/template_util_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/template_util_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-unittest_lite.pb.obj: google/protobuf/unittest_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-type_traits_unittest.o: google/protobuf/stubs/type_traits_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-type_traits_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-type_traits_unittest.o `test -f 'google/protobuf/stubs/type_traits_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/type_traits_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/type_traits_unittest.cc' object='google/protobuf/stubs/protobuf_test-type_traits_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-type_traits_unittest.o `test -f 'google/protobuf/stubs/type_traits_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/type_traits_unittest.cc
-protobuf_lazy_descriptor_test-unittest_import_lite.pb.o: google/protobuf/unittest_import_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_import_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_lite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/stubs/protobuf_test-type_traits_unittest.obj: google/protobuf/stubs/type_traits_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-type_traits_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-type_traits_unittest.obj `if test -f 'google/protobuf/stubs/type_traits_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/type_traits_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/type_traits_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/stubs/type_traits_unittest.cc' object='google/protobuf/stubs/protobuf_test-type_traits_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-type_traits_unittest.obj `if test -f 'google/protobuf/stubs/type_traits_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/type_traits_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/type_traits_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_lite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-descriptor_database_unittest.o: google/protobuf/descriptor_database_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-descriptor_database_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo -c -o google/protobuf/protobuf_test-descriptor_database_unittest.o `test -f 'google/protobuf/descriptor_database_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_database_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/descriptor_database_unittest.cc' object='google/protobuf/protobuf_test-descriptor_database_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-descriptor_database_unittest.o `test -f 'google/protobuf/descriptor_database_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_database_unittest.cc
-protobuf_lazy_descriptor_test-unittest.pb.o: google/protobuf/unittest.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest.pb.cc' object='protobuf_lazy_descriptor_test-unittest.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-descriptor_database_unittest.obj: google/protobuf/descriptor_database_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-descriptor_database_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo -c -o google/protobuf/protobuf_test-descriptor_database_unittest.obj `if test -f 'google/protobuf/descriptor_database_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_database_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_database_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/descriptor_database_unittest.cc' object='google/protobuf/protobuf_test-descriptor_database_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-descriptor_database_unittest.obj `if test -f 'google/protobuf/descriptor_database_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_database_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_database_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-unittest.pb.obj: google/protobuf/unittest.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest.pb.cc' object='protobuf_lazy_descriptor_test-unittest.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-descriptor_unittest.o: google/protobuf/descriptor_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-descriptor_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Tpo -c -o google/protobuf/protobuf_test-descriptor_unittest.o `test -f 'google/protobuf/descriptor_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/descriptor_unittest.cc' object='google/protobuf/protobuf_test-descriptor_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-descriptor_unittest.o `test -f 'google/protobuf/descriptor_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_unittest.cc
-protobuf_lazy_descriptor_test-unittest_empty.pb.o: google/protobuf/unittest_empty.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_empty.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_empty.pb.cc' object='protobuf_lazy_descriptor_test-unittest_empty.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-descriptor_unittest.obj: google/protobuf/descriptor_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-descriptor_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Tpo -c -o google/protobuf/protobuf_test-descriptor_unittest.obj `if test -f 'google/protobuf/descriptor_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/descriptor_unittest.cc' object='google/protobuf/protobuf_test-descriptor_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-descriptor_unittest.obj `if test -f 'google/protobuf/descriptor_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-unittest_empty.pb.obj: google/protobuf/unittest_empty.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_empty.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_empty.pb.cc' object='protobuf_lazy_descriptor_test-unittest_empty.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-dynamic_message_unittest.o: google/protobuf/dynamic_message_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-dynamic_message_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo -c -o google/protobuf/protobuf_test-dynamic_message_unittest.o `test -f 'google/protobuf/dynamic_message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/dynamic_message_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/dynamic_message_unittest.cc' object='google/protobuf/protobuf_test-dynamic_message_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-dynamic_message_unittest.o `test -f 'google/protobuf/dynamic_message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/dynamic_message_unittest.cc
-protobuf_lazy_descriptor_test-unittest_import.pb.o: google/protobuf/unittest_import.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_import.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-dynamic_message_unittest.obj: google/protobuf/dynamic_message_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-dynamic_message_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo -c -o google/protobuf/protobuf_test-dynamic_message_unittest.obj `if test -f 'google/protobuf/dynamic_message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/dynamic_message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/dynamic_message_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/dynamic_message_unittest.cc' object='google/protobuf/protobuf_test-dynamic_message_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-dynamic_message_unittest.obj `if test -f 'google/protobuf/dynamic_message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/dynamic_message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/dynamic_message_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-unittest_import.pb.obj: google/protobuf/unittest_import.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_import.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-extension_set_unittest.o: google/protobuf/extension_set_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-extension_set_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Tpo -c -o google/protobuf/protobuf_test-extension_set_unittest.o `test -f 'google/protobuf/extension_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/extension_set_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/extension_set_unittest.cc' object='google/protobuf/protobuf_test-extension_set_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-extension_set_unittest.o `test -f 'google/protobuf/extension_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/extension_set_unittest.cc
-protobuf_lazy_descriptor_test-unittest_mset.pb.o: google/protobuf/unittest_mset.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_mset.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_mset.pb.cc' object='protobuf_lazy_descriptor_test-unittest_mset.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-extension_set_unittest.obj: google/protobuf/extension_set_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-extension_set_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Tpo -c -o google/protobuf/protobuf_test-extension_set_unittest.obj `if test -f 'google/protobuf/extension_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/extension_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/extension_set_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/extension_set_unittest.cc' object='google/protobuf/protobuf_test-extension_set_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-extension_set_unittest.obj `if test -f 'google/protobuf/extension_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/extension_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/extension_set_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-unittest_mset.pb.obj: google/protobuf/unittest_mset.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_mset.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_mset.pb.cc' object='protobuf_lazy_descriptor_test-unittest_mset.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-generated_message_reflection_unittest.o: google/protobuf/generated_message_reflection_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-generated_message_reflection_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo -c -o google/protobuf/protobuf_test-generated_message_reflection_unittest.o `test -f 'google/protobuf/generated_message_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_reflection_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/generated_message_reflection_unittest.cc' object='google/protobuf/protobuf_test-generated_message_reflection_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-generated_message_reflection_unittest.o `test -f 'google/protobuf/generated_message_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_reflection_unittest.cc
-protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o: google/protobuf/unittest_optimize_for.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_optimize_for.pb.cc' object='protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-generated_message_reflection_unittest.obj: google/protobuf/generated_message_reflection_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-generated_message_reflection_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo -c -o google/protobuf/protobuf_test-generated_message_reflection_unittest.obj `if test -f 'google/protobuf/generated_message_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/generated_message_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/generated_message_reflection_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/generated_message_reflection_unittest.cc' object='google/protobuf/protobuf_test-generated_message_reflection_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-generated_message_reflection_unittest.obj `if test -f 'google/protobuf/generated_message_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/generated_message_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/generated_message_reflection_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj: google/protobuf/unittest_optimize_for.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_optimize_for.pb.cc' object='protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-message_unittest.o: google/protobuf/message_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-message_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Tpo -c -o google/protobuf/protobuf_test-message_unittest.o `test -f 'google/protobuf/message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/message_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/message_unittest.cc' object='google/protobuf/protobuf_test-message_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-message_unittest.o `test -f 'google/protobuf/message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/message_unittest.cc
-protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o: google/protobuf/unittest_embed_optimize_for.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-message_unittest.obj: google/protobuf/message_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-message_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Tpo -c -o google/protobuf/protobuf_test-message_unittest.obj `if test -f 'google/protobuf/message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/message_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/message_unittest.cc' object='google/protobuf/protobuf_test-message_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-message_unittest.obj `if test -f 'google/protobuf/message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/message_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj: google/protobuf/unittest_embed_optimize_for.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-reflection_ops_unittest.o: google/protobuf/reflection_ops_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-reflection_ops_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo -c -o google/protobuf/protobuf_test-reflection_ops_unittest.o `test -f 'google/protobuf/reflection_ops_unittest.cc' || echo '$(srcdir)/'`google/protobuf/reflection_ops_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/reflection_ops_unittest.cc' object='google/protobuf/protobuf_test-reflection_ops_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-reflection_ops_unittest.o `test -f 'google/protobuf/reflection_ops_unittest.cc' || echo '$(srcdir)/'`google/protobuf/reflection_ops_unittest.cc
-protobuf_lazy_descriptor_test-unittest_custom_options.pb.o: google/protobuf/unittest_custom_options.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_custom_options.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_custom_options.pb.cc' object='protobuf_lazy_descriptor_test-unittest_custom_options.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-reflection_ops_unittest.obj: google/protobuf/reflection_ops_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-reflection_ops_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo -c -o google/protobuf/protobuf_test-reflection_ops_unittest.obj `if test -f 'google/protobuf/reflection_ops_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/reflection_ops_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/reflection_ops_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/reflection_ops_unittest.cc' object='google/protobuf/protobuf_test-reflection_ops_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-reflection_ops_unittest.obj `if test -f 'google/protobuf/reflection_ops_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/reflection_ops_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/reflection_ops_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj: google/protobuf/unittest_custom_options.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_custom_options.pb.cc' object='protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-repeated_field_unittest.o: google/protobuf/repeated_field_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-repeated_field_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo -c -o google/protobuf/protobuf_test-repeated_field_unittest.o `test -f 'google/protobuf/repeated_field_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/repeated_field_unittest.cc' object='google/protobuf/protobuf_test-repeated_field_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-repeated_field_unittest.o `test -f 'google/protobuf/repeated_field_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_unittest.cc
-protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o: google/protobuf/unittest_lite_imports_nonlite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-repeated_field_unittest.obj: google/protobuf/repeated_field_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-repeated_field_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo -c -o google/protobuf/protobuf_test-repeated_field_unittest.obj `if test -f 'google/protobuf/repeated_field_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/repeated_field_unittest.cc' object='google/protobuf/protobuf_test-repeated_field_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-repeated_field_unittest.obj `if test -f 'google/protobuf/repeated_field_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj: google/protobuf/unittest_lite_imports_nonlite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-repeated_field_reflection_unittest.o: google/protobuf/repeated_field_reflection_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-repeated_field_reflection_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo -c -o google/protobuf/protobuf_test-repeated_field_reflection_unittest.o `test -f 'google/protobuf/repeated_field_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_reflection_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/repeated_field_reflection_unittest.cc' object='google/protobuf/protobuf_test-repeated_field_reflection_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-repeated_field_reflection_unittest.o `test -f 'google/protobuf/repeated_field_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_reflection_unittest.cc
-protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o: google/protobuf/unittest_no_generic_services.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_no_generic_services.pb.cc' object='protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-repeated_field_reflection_unittest.obj: google/protobuf/repeated_field_reflection_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-repeated_field_reflection_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo -c -o google/protobuf/protobuf_test-repeated_field_reflection_unittest.obj `if test -f 'google/protobuf/repeated_field_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_reflection_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/repeated_field_reflection_unittest.cc' object='google/protobuf/protobuf_test-repeated_field_reflection_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-repeated_field_reflection_unittest.obj `if test -f 'google/protobuf/repeated_field_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_reflection_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj: google/protobuf/unittest_no_generic_services.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_no_generic_services.pb.cc' object='protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-text_format_unittest.o: google/protobuf/text_format_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-text_format_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Tpo -c -o google/protobuf/protobuf_test-text_format_unittest.o `test -f 'google/protobuf/text_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/text_format_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/text_format_unittest.cc' object='google/protobuf/protobuf_test-text_format_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-text_format_unittest.o `test -f 'google/protobuf/text_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/text_format_unittest.cc
-protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo -c -o protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-text_format_unittest.obj: google/protobuf/text_format_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-text_format_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Tpo -c -o google/protobuf/protobuf_test-text_format_unittest.obj `if test -f 'google/protobuf/text_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/text_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/text_format_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/text_format_unittest.cc' object='google/protobuf/protobuf_test-text_format_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-text_format_unittest.obj `if test -f 'google/protobuf/text_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/text_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/text_format_unittest.cc'; fi`
-protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo -c -o protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unknown_field_set_unittest.o: google/protobuf/unknown_field_set_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unknown_field_set_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo -c -o google/protobuf/protobuf_test-unknown_field_set_unittest.o `test -f 'google/protobuf/unknown_field_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/unknown_field_set_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unknown_field_set_unittest.cc' object='google/protobuf/protobuf_test-unknown_field_set_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unknown_field_set_unittest.o `test -f 'google/protobuf/unknown_field_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/unknown_field_set_unittest.cc
-protobuf_lite_test-lite_unittest.o: google/protobuf/lite_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-lite_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo -c -o protobuf_lite_test-lite_unittest.o `test -f 'google/protobuf/lite_unittest.cc' || echo '$(srcdir)/'`google/protobuf/lite_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo $(DEPDIR)/protobuf_lite_test-lite_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/lite_unittest.cc' object='protobuf_lite_test-lite_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unknown_field_set_unittest.obj: google/protobuf/unknown_field_set_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unknown_field_set_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo -c -o google/protobuf/protobuf_test-unknown_field_set_unittest.obj `if test -f 'google/protobuf/unknown_field_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/unknown_field_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unknown_field_set_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unknown_field_set_unittest.cc' object='google/protobuf/protobuf_test-unknown_field_set_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-lite_unittest.o `test -f 'google/protobuf/lite_unittest.cc' || echo '$(srcdir)/'`google/protobuf/lite_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unknown_field_set_unittest.obj `if test -f 'google/protobuf/unknown_field_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/unknown_field_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unknown_field_set_unittest.cc'; fi`
-protobuf_lite_test-lite_unittest.obj: google/protobuf/lite_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-lite_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo -c -o protobuf_lite_test-lite_unittest.obj `if test -f 'google/protobuf/lite_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/lite_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/lite_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo $(DEPDIR)/protobuf_lite_test-lite_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/lite_unittest.cc' object='protobuf_lite_test-lite_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-wire_format_unittest.o: google/protobuf/wire_format_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-wire_format_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Tpo -c -o google/protobuf/protobuf_test-wire_format_unittest.o `test -f 'google/protobuf/wire_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/wire_format_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/wire_format_unittest.cc' object='google/protobuf/protobuf_test-wire_format_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-lite_unittest.obj `if test -f 'google/protobuf/lite_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/lite_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/lite_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-wire_format_unittest.o `test -f 'google/protobuf/wire_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/wire_format_unittest.cc
-protobuf_lite_test-test_util_lite.o: google/protobuf/test_util_lite.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-test_util_lite.o -MD -MP -MF $(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo -c -o protobuf_lite_test-test_util_lite.o `test -f 'google/protobuf/test_util_lite.cc' || echo '$(srcdir)/'`google/protobuf/test_util_lite.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo $(DEPDIR)/protobuf_lite_test-test_util_lite.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/test_util_lite.cc' object='protobuf_lite_test-test_util_lite.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-wire_format_unittest.obj: google/protobuf/wire_format_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-wire_format_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Tpo -c -o google/protobuf/protobuf_test-wire_format_unittest.obj `if test -f 'google/protobuf/wire_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/wire_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/wire_format_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/wire_format_unittest.cc' object='google/protobuf/protobuf_test-wire_format_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-test_util_lite.o `test -f 'google/protobuf/test_util_lite.cc' || echo '$(srcdir)/'`google/protobuf/test_util_lite.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-wire_format_unittest.obj `if test -f 'google/protobuf/wire_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/wire_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/wire_format_unittest.cc'; fi`
-protobuf_lite_test-test_util_lite.obj: google/protobuf/test_util_lite.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-test_util_lite.obj -MD -MP -MF $(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo -c -o protobuf_lite_test-test_util_lite.obj `if test -f 'google/protobuf/test_util_lite.cc'; then $(CYGPATH_W) 'google/protobuf/test_util_lite.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util_lite.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo $(DEPDIR)/protobuf_lite_test-test_util_lite.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/test_util_lite.cc' object='protobuf_lite_test-test_util_lite.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/io/protobuf_test-coded_stream_unittest.o: google/protobuf/io/coded_stream_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-coded_stream_unittest.o -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo -c -o google/protobuf/io/protobuf_test-coded_stream_unittest.o `test -f 'google/protobuf/io/coded_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/coded_stream_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/io/coded_stream_unittest.cc' object='google/protobuf/io/protobuf_test-coded_stream_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-test_util_lite.obj `if test -f 'google/protobuf/test_util_lite.cc'; then $(CYGPATH_W) 'google/protobuf/test_util_lite.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util_lite.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-coded_stream_unittest.o `test -f 'google/protobuf/io/coded_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/coded_stream_unittest.cc
-protobuf_lite_test-unittest_lite.pb.o: google/protobuf/unittest_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-unittest_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo -c -o protobuf_lite_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo $(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite.pb.cc' object='protobuf_lite_test-unittest_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/io/protobuf_test-coded_stream_unittest.obj: google/protobuf/io/coded_stream_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-coded_stream_unittest.obj -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo -c -o google/protobuf/io/protobuf_test-coded_stream_unittest.obj `if test -f 'google/protobuf/io/coded_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/coded_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/coded_stream_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/io/coded_stream_unittest.cc' object='google/protobuf/io/protobuf_test-coded_stream_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-coded_stream_unittest.obj `if test -f 'google/protobuf/io/coded_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/coded_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/coded_stream_unittest.cc'; fi`
-protobuf_lite_test-unittest_lite.pb.obj: google/protobuf/unittest_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-unittest_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo -c -o protobuf_lite_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo $(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite.pb.cc' object='protobuf_lite_test-unittest_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/io/protobuf_test-printer_unittest.o: google/protobuf/io/printer_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-printer_unittest.o -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Tpo -c -o google/protobuf/io/protobuf_test-printer_unittest.o `test -f 'google/protobuf/io/printer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/printer_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/io/printer_unittest.cc' object='google/protobuf/io/protobuf_test-printer_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-printer_unittest.o `test -f 'google/protobuf/io/printer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/printer_unittest.cc
-protobuf_lite_test-unittest_import_lite.pb.o: google/protobuf/unittest_import_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-unittest_import_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo -c -o protobuf_lite_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo $(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_lite.pb.cc' object='protobuf_lite_test-unittest_import_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/io/protobuf_test-printer_unittest.obj: google/protobuf/io/printer_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-printer_unittest.obj -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Tpo -c -o google/protobuf/io/protobuf_test-printer_unittest.obj `if test -f 'google/protobuf/io/printer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/printer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/printer_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/io/printer_unittest.cc' object='google/protobuf/io/protobuf_test-printer_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-printer_unittest.obj `if test -f 'google/protobuf/io/printer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/printer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/printer_unittest.cc'; fi`
-protobuf_lite_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-unittest_import_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo -c -o protobuf_lite_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo $(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_lite.pb.cc' object='protobuf_lite_test-unittest_import_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/io/protobuf_test-tokenizer_unittest.o: google/protobuf/io/tokenizer_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-tokenizer_unittest.o -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo -c -o google/protobuf/io/protobuf_test-tokenizer_unittest.o `test -f 'google/protobuf/io/tokenizer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/tokenizer_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/io/tokenizer_unittest.cc' object='google/protobuf/io/protobuf_test-tokenizer_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-tokenizer_unittest.o `test -f 'google/protobuf/io/tokenizer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/tokenizer_unittest.cc
-protobuf_test-common_unittest.o: google/protobuf/stubs/common_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-common_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-common_unittest.Tpo -c -o protobuf_test-common_unittest.o `test -f 'google/protobuf/stubs/common_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-common_unittest.Tpo $(DEPDIR)/protobuf_test-common_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/common_unittest.cc' object='protobuf_test-common_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/io/protobuf_test-tokenizer_unittest.obj: google/protobuf/io/tokenizer_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-tokenizer_unittest.obj -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo -c -o google/protobuf/io/protobuf_test-tokenizer_unittest.obj `if test -f 'google/protobuf/io/tokenizer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/tokenizer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/tokenizer_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/io/tokenizer_unittest.cc' object='google/protobuf/io/protobuf_test-tokenizer_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-common_unittest.o `test -f 'google/protobuf/stubs/common_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-tokenizer_unittest.obj `if test -f 'google/protobuf/io/tokenizer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/tokenizer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/tokenizer_unittest.cc'; fi`
-protobuf_test-common_unittest.obj: google/protobuf/stubs/common_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-common_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-common_unittest.Tpo -c -o protobuf_test-common_unittest.obj `if test -f 'google/protobuf/stubs/common_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/common_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/common_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-common_unittest.Tpo $(DEPDIR)/protobuf_test-common_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/common_unittest.cc' object='protobuf_test-common_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/io/protobuf_test-zero_copy_stream_unittest.o: google/protobuf/io/zero_copy_stream_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-zero_copy_stream_unittest.o -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo -c -o google/protobuf/io/protobuf_test-zero_copy_stream_unittest.o `test -f 'google/protobuf/io/zero_copy_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/io/zero_copy_stream_unittest.cc' object='google/protobuf/io/protobuf_test-zero_copy_stream_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-common_unittest.obj `if test -f 'google/protobuf/stubs/common_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/common_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/common_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-zero_copy_stream_unittest.o `test -f 'google/protobuf/io/zero_copy_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_unittest.cc
-protobuf_test-once_unittest.o: google/protobuf/stubs/once_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-once_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-once_unittest.Tpo -c -o protobuf_test-once_unittest.o `test -f 'google/protobuf/stubs/once_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/once_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-once_unittest.Tpo $(DEPDIR)/protobuf_test-once_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/once_unittest.cc' object='protobuf_test-once_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/io/protobuf_test-zero_copy_stream_unittest.obj: google/protobuf/io/zero_copy_stream_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-zero_copy_stream_unittest.obj -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo -c -o google/protobuf/io/protobuf_test-zero_copy_stream_unittest.obj `if test -f 'google/protobuf/io/zero_copy_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/zero_copy_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/zero_copy_stream_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/io/zero_copy_stream_unittest.cc' object='google/protobuf/io/protobuf_test-zero_copy_stream_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-once_unittest.o `test -f 'google/protobuf/stubs/once_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/once_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-zero_copy_stream_unittest.obj `if test -f 'google/protobuf/io/zero_copy_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/zero_copy_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/zero_copy_stream_unittest.cc'; fi`
-protobuf_test-once_unittest.obj: google/protobuf/stubs/once_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-once_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-once_unittest.Tpo -c -o protobuf_test-once_unittest.obj `if test -f 'google/protobuf/stubs/once_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/once_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/once_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-once_unittest.Tpo $(DEPDIR)/protobuf_test-once_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/once_unittest.cc' object='protobuf_test-once_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/protobuf_test-command_line_interface_unittest.o: google/protobuf/compiler/command_line_interface_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-command_line_interface_unittest.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo -c -o google/protobuf/compiler/protobuf_test-command_line_interface_unittest.o `test -f 'google/protobuf/compiler/command_line_interface_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/command_line_interface_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/command_line_interface_unittest.cc' object='google/protobuf/compiler/protobuf_test-command_line_interface_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-once_unittest.obj `if test -f 'google/protobuf/stubs/once_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/once_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/once_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-command_line_interface_unittest.o `test -f 'google/protobuf/compiler/command_line_interface_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/command_line_interface_unittest.cc
-protobuf_test-strutil_unittest.o: google/protobuf/stubs/strutil_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-strutil_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-strutil_unittest.Tpo -c -o protobuf_test-strutil_unittest.o `test -f 'google/protobuf/stubs/strutil_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/strutil_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-strutil_unittest.Tpo $(DEPDIR)/protobuf_test-strutil_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/strutil_unittest.cc' object='protobuf_test-strutil_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/protobuf_test-command_line_interface_unittest.obj: google/protobuf/compiler/command_line_interface_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-command_line_interface_unittest.obj -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo -c -o google/protobuf/compiler/protobuf_test-command_line_interface_unittest.obj `if test -f 'google/protobuf/compiler/command_line_interface_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/command_line_interface_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/command_line_interface_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/command_line_interface_unittest.cc' object='google/protobuf/compiler/protobuf_test-command_line_interface_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-strutil_unittest.o `test -f 'google/protobuf/stubs/strutil_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/strutil_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-command_line_interface_unittest.obj `if test -f 'google/protobuf/compiler/command_line_interface_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/command_line_interface_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/command_line_interface_unittest.cc'; fi`
-protobuf_test-strutil_unittest.obj: google/protobuf/stubs/strutil_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-strutil_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-strutil_unittest.Tpo -c -o protobuf_test-strutil_unittest.obj `if test -f 'google/protobuf/stubs/strutil_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/strutil_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/strutil_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-strutil_unittest.Tpo $(DEPDIR)/protobuf_test-strutil_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/strutil_unittest.cc' object='protobuf_test-strutil_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/protobuf_test-importer_unittest.o: google/protobuf/compiler/importer_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-importer_unittest.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Tpo -c -o google/protobuf/compiler/protobuf_test-importer_unittest.o `test -f 'google/protobuf/compiler/importer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/importer_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/importer_unittest.cc' object='google/protobuf/compiler/protobuf_test-importer_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-strutil_unittest.obj `if test -f 'google/protobuf/stubs/strutil_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/strutil_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/strutil_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-importer_unittest.o `test -f 'google/protobuf/compiler/importer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/importer_unittest.cc
-protobuf_test-structurally_valid_unittest.o: google/protobuf/stubs/structurally_valid_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-structurally_valid_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo -c -o protobuf_test-structurally_valid_unittest.o `test -f 'google/protobuf/stubs/structurally_valid_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/structurally_valid_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo $(DEPDIR)/protobuf_test-structurally_valid_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/structurally_valid_unittest.cc' object='protobuf_test-structurally_valid_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/protobuf_test-importer_unittest.obj: google/protobuf/compiler/importer_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-importer_unittest.obj -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Tpo -c -o google/protobuf/compiler/protobuf_test-importer_unittest.obj `if test -f 'google/protobuf/compiler/importer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/importer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/importer_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/importer_unittest.cc' object='google/protobuf/compiler/protobuf_test-importer_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-structurally_valid_unittest.o `test -f 'google/protobuf/stubs/structurally_valid_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/structurally_valid_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-importer_unittest.obj `if test -f 'google/protobuf/compiler/importer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/importer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/importer_unittest.cc'; fi`
-protobuf_test-structurally_valid_unittest.obj: google/protobuf/stubs/structurally_valid_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-structurally_valid_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo -c -o protobuf_test-structurally_valid_unittest.obj `if test -f 'google/protobuf/stubs/structurally_valid_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/structurally_valid_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/structurally_valid_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo $(DEPDIR)/protobuf_test-structurally_valid_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/structurally_valid_unittest.cc' object='protobuf_test-structurally_valid_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/protobuf_test-mock_code_generator.o: google/protobuf/compiler/mock_code_generator.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-mock_code_generator.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Tpo -c -o google/protobuf/compiler/protobuf_test-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/mock_code_generator.cc' object='google/protobuf/compiler/protobuf_test-mock_code_generator.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-structurally_valid_unittest.obj `if test -f 'google/protobuf/stubs/structurally_valid_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/structurally_valid_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/structurally_valid_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc
-protobuf_test-descriptor_database_unittest.o: google/protobuf/descriptor_database_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-descriptor_database_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo -c -o protobuf_test-descriptor_database_unittest.o `test -f 'google/protobuf/descriptor_database_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_database_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo $(DEPDIR)/protobuf_test-descriptor_database_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor_database_unittest.cc' object='protobuf_test-descriptor_database_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/protobuf_test-mock_code_generator.obj: google/protobuf/compiler/mock_code_generator.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-mock_code_generator.obj -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Tpo -c -o google/protobuf/compiler/protobuf_test-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/mock_code_generator.cc' object='google/protobuf/compiler/protobuf_test-mock_code_generator.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-descriptor_database_unittest.o `test -f 'google/protobuf/descriptor_database_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_database_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi`
-protobuf_test-descriptor_database_unittest.obj: google/protobuf/descriptor_database_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-descriptor_database_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo -c -o protobuf_test-descriptor_database_unittest.obj `if test -f 'google/protobuf/descriptor_database_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_database_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_database_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo $(DEPDIR)/protobuf_test-descriptor_database_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor_database_unittest.cc' object='protobuf_test-descriptor_database_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/protobuf_test-parser_unittest.o: google/protobuf/compiler/parser_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-parser_unittest.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Tpo -c -o google/protobuf/compiler/protobuf_test-parser_unittest.o `test -f 'google/protobuf/compiler/parser_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/parser_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/parser_unittest.cc' object='google/protobuf/compiler/protobuf_test-parser_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-descriptor_database_unittest.obj `if test -f 'google/protobuf/descriptor_database_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_database_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_database_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-parser_unittest.o `test -f 'google/protobuf/compiler/parser_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/parser_unittest.cc
-protobuf_test-descriptor_unittest.o: google/protobuf/descriptor_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-descriptor_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-descriptor_unittest.Tpo -c -o protobuf_test-descriptor_unittest.o `test -f 'google/protobuf/descriptor_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-descriptor_unittest.Tpo $(DEPDIR)/protobuf_test-descriptor_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor_unittest.cc' object='protobuf_test-descriptor_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/protobuf_test-parser_unittest.obj: google/protobuf/compiler/parser_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-parser_unittest.obj -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Tpo -c -o google/protobuf/compiler/protobuf_test-parser_unittest.obj `if test -f 'google/protobuf/compiler/parser_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/parser_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/parser_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/parser_unittest.cc' object='google/protobuf/compiler/protobuf_test-parser_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-descriptor_unittest.o `test -f 'google/protobuf/descriptor_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-parser_unittest.obj `if test -f 'google/protobuf/compiler/parser_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/parser_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/parser_unittest.cc'; fi`
-protobuf_test-descriptor_unittest.obj: google/protobuf/descriptor_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-descriptor_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-descriptor_unittest.Tpo -c -o protobuf_test-descriptor_unittest.obj `if test -f 'google/protobuf/descriptor_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-descriptor_unittest.Tpo $(DEPDIR)/protobuf_test-descriptor_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/descriptor_unittest.cc' object='protobuf_test-descriptor_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o: google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-descriptor_unittest.obj `if test -f 'google/protobuf/descriptor_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
-protobuf_test-dynamic_message_unittest.o: google/protobuf/dynamic_message_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-dynamic_message_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo -c -o protobuf_test-dynamic_message_unittest.o `test -f 'google/protobuf/dynamic_message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/dynamic_message_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo $(DEPDIR)/protobuf_test-dynamic_message_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/dynamic_message_unittest.cc' object='protobuf_test-dynamic_message_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj: google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-dynamic_message_unittest.o `test -f 'google/protobuf/dynamic_message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/dynamic_message_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; fi`
-protobuf_test-dynamic_message_unittest.obj: google/protobuf/dynamic_message_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-dynamic_message_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo -c -o protobuf_test-dynamic_message_unittest.obj `if test -f 'google/protobuf/dynamic_message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/dynamic_message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/dynamic_message_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo $(DEPDIR)/protobuf_test-dynamic_message_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/dynamic_message_unittest.cc' object='protobuf_test-dynamic_message_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o: google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-dynamic_message_unittest.obj `if test -f 'google/protobuf/dynamic_message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/dynamic_message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/dynamic_message_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc
-protobuf_test-extension_set_unittest.o: google/protobuf/extension_set_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-extension_set_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-extension_set_unittest.Tpo -c -o protobuf_test-extension_set_unittest.o `test -f 'google/protobuf/extension_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/extension_set_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-extension_set_unittest.Tpo $(DEPDIR)/protobuf_test-extension_set_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/extension_set_unittest.cc' object='protobuf_test-extension_set_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj: google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-extension_set_unittest.o `test -f 'google/protobuf/extension_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/extension_set_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi`
-protobuf_test-extension_set_unittest.obj: google/protobuf/extension_set_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-extension_set_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-extension_set_unittest.Tpo -c -o protobuf_test-extension_set_unittest.obj `if test -f 'google/protobuf/extension_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/extension_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/extension_set_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-extension_set_unittest.Tpo $(DEPDIR)/protobuf_test-extension_set_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/extension_set_unittest.cc' object='protobuf_test-extension_set_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o: google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-extension_set_unittest.obj `if test -f 'google/protobuf/extension_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/extension_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/extension_set_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
-protobuf_test-generated_message_reflection_unittest.o: google/protobuf/generated_message_reflection_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-generated_message_reflection_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo -c -o protobuf_test-generated_message_reflection_unittest.o `test -f 'google/protobuf/generated_message_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_reflection_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo $(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/generated_message_reflection_unittest.cc' object='protobuf_test-generated_message_reflection_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj: google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-generated_message_reflection_unittest.o `test -f 'google/protobuf/generated_message_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_reflection_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; fi`
-protobuf_test-generated_message_reflection_unittest.obj: google/protobuf/generated_message_reflection_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-generated_message_reflection_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo -c -o protobuf_test-generated_message_reflection_unittest.obj `if test -f 'google/protobuf/generated_message_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/generated_message_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/generated_message_reflection_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo $(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/generated_message_reflection_unittest.cc' object='protobuf_test-generated_message_reflection_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o: google/protobuf/compiler/java/java_plugin_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o `test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_plugin_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/java/java_plugin_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-generated_message_reflection_unittest.obj `if test -f 'google/protobuf/generated_message_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/generated_message_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/generated_message_reflection_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o `test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_plugin_unittest.cc
-protobuf_test-message_unittest.o: google/protobuf/message_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-message_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-message_unittest.Tpo -c -o protobuf_test-message_unittest.o `test -f 'google/protobuf/message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/message_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-message_unittest.Tpo $(DEPDIR)/protobuf_test-message_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/message_unittest.cc' object='protobuf_test-message_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj: google/protobuf/compiler/java/java_plugin_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_plugin_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/java/java_plugin_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-message_unittest.o `test -f 'google/protobuf/message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/message_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_plugin_unittest.cc'; fi`
-protobuf_test-message_unittest.obj: google/protobuf/message_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-message_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-message_unittest.Tpo -c -o protobuf_test-message_unittest.obj `if test -f 'google/protobuf/message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/message_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-message_unittest.Tpo $(DEPDIR)/protobuf_test-message_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/message_unittest.cc' object='protobuf_test-message_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o: google/protobuf/compiler/java/java_doc_comment_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o `test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/java/java_doc_comment_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-message_unittest.obj `if test -f 'google/protobuf/message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/message_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o `test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment_unittest.cc
-protobuf_test-reflection_ops_unittest.o: google/protobuf/reflection_ops_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-reflection_ops_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo -c -o protobuf_test-reflection_ops_unittest.o `test -f 'google/protobuf/reflection_ops_unittest.cc' || echo '$(srcdir)/'`google/protobuf/reflection_ops_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo $(DEPDIR)/protobuf_test-reflection_ops_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/reflection_ops_unittest.cc' object='protobuf_test-reflection_ops_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj: google/protobuf/compiler/java/java_doc_comment_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj `if test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_doc_comment_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/java/java_doc_comment_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-reflection_ops_unittest.o `test -f 'google/protobuf/reflection_ops_unittest.cc' || echo '$(srcdir)/'`google/protobuf/reflection_ops_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj `if test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_doc_comment_unittest.cc'; fi`
-protobuf_test-reflection_ops_unittest.obj: google/protobuf/reflection_ops_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-reflection_ops_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo -c -o protobuf_test-reflection_ops_unittest.obj `if test -f 'google/protobuf/reflection_ops_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/reflection_ops_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/reflection_ops_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo $(DEPDIR)/protobuf_test-reflection_ops_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/reflection_ops_unittest.cc' object='protobuf_test-reflection_ops_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o: google/protobuf/compiler/python/python_plugin_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o -MD -MP -MF google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo -c -o google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o `test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_plugin_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/python/python_plugin_unittest.cc' object='google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-reflection_ops_unittest.obj `if test -f 'google/protobuf/reflection_ops_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/reflection_ops_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/reflection_ops_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o `test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_plugin_unittest.cc
-protobuf_test-repeated_field_unittest.o: google/protobuf/repeated_field_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-repeated_field_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo -c -o protobuf_test-repeated_field_unittest.o `test -f 'google/protobuf/repeated_field_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo $(DEPDIR)/protobuf_test-repeated_field_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/repeated_field_unittest.cc' object='protobuf_test-repeated_field_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj: google/protobuf/compiler/python/python_plugin_unittest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj -MD -MP -MF google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo -c -o google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/python_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/python_plugin_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/python/python_plugin_unittest.cc' object='google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-repeated_field_unittest.o `test -f 'google/protobuf/repeated_field_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/python_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/python_plugin_unittest.cc'; fi`
-protobuf_test-repeated_field_unittest.obj: google/protobuf/repeated_field_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-repeated_field_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo -c -o protobuf_test-repeated_field_unittest.obj `if test -f 'google/protobuf/repeated_field_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo $(DEPDIR)/protobuf_test-repeated_field_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/repeated_field_unittest.cc' object='protobuf_test-repeated_field_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-test_util.o: google/protobuf/test_util.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-test_util.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-test_util.Tpo -c -o google/protobuf/protobuf_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-test_util.Tpo google/protobuf/$(DEPDIR)/protobuf_test-test_util.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/test_util.cc' object='google/protobuf/protobuf_test-test_util.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-repeated_field_unittest.obj `if test -f 'google/protobuf/repeated_field_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc
-protobuf_test-text_format_unittest.o: google/protobuf/text_format_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-text_format_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-text_format_unittest.Tpo -c -o protobuf_test-text_format_unittest.o `test -f 'google/protobuf/text_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/text_format_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-text_format_unittest.Tpo $(DEPDIR)/protobuf_test-text_format_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/text_format_unittest.cc' object='protobuf_test-text_format_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-test_util.obj: google/protobuf/test_util.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-test_util.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-test_util.Tpo -c -o google/protobuf/protobuf_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-test_util.Tpo google/protobuf/$(DEPDIR)/protobuf_test-test_util.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/test_util.cc' object='google/protobuf/protobuf_test-test_util.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-text_format_unittest.o `test -f 'google/protobuf/text_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/text_format_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi`
-protobuf_test-text_format_unittest.obj: google/protobuf/text_format_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-text_format_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-text_format_unittest.Tpo -c -o protobuf_test-text_format_unittest.obj `if test -f 'google/protobuf/text_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/text_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/text_format_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-text_format_unittest.Tpo $(DEPDIR)/protobuf_test-text_format_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/text_format_unittest.cc' object='protobuf_test-text_format_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/testing/protobuf_test-googletest.o: google/protobuf/testing/googletest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_test-googletest.o -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Tpo -c -o google/protobuf/testing/protobuf_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/testing/googletest.cc' object='google/protobuf/testing/protobuf_test-googletest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-text_format_unittest.obj `if test -f 'google/protobuf/text_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/text_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/text_format_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc
-protobuf_test-unknown_field_set_unittest.o: google/protobuf/unknown_field_set_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unknown_field_set_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo -c -o protobuf_test-unknown_field_set_unittest.o `test -f 'google/protobuf/unknown_field_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/unknown_field_set_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo $(DEPDIR)/protobuf_test-unknown_field_set_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unknown_field_set_unittest.cc' object='protobuf_test-unknown_field_set_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/testing/protobuf_test-googletest.obj: google/protobuf/testing/googletest.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_test-googletest.obj -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Tpo -c -o google/protobuf/testing/protobuf_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/testing/googletest.cc' object='google/protobuf/testing/protobuf_test-googletest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unknown_field_set_unittest.o `test -f 'google/protobuf/unknown_field_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/unknown_field_set_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi`
-protobuf_test-unknown_field_set_unittest.obj: google/protobuf/unknown_field_set_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unknown_field_set_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo -c -o protobuf_test-unknown_field_set_unittest.obj `if test -f 'google/protobuf/unknown_field_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/unknown_field_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unknown_field_set_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo $(DEPDIR)/protobuf_test-unknown_field_set_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unknown_field_set_unittest.cc' object='protobuf_test-unknown_field_set_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/testing/protobuf_test-file.o: google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_test-file.o -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Tpo -c -o google/protobuf/testing/protobuf_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/testing/file.cc' object='google/protobuf/testing/protobuf_test-file.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unknown_field_set_unittest.obj `if test -f 'google/protobuf/unknown_field_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/unknown_field_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unknown_field_set_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
-protobuf_test-wire_format_unittest.o: google/protobuf/wire_format_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-wire_format_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-wire_format_unittest.Tpo -c -o protobuf_test-wire_format_unittest.o `test -f 'google/protobuf/wire_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/wire_format_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-wire_format_unittest.Tpo $(DEPDIR)/protobuf_test-wire_format_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/wire_format_unittest.cc' object='protobuf_test-wire_format_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/testing/protobuf_test-file.obj: google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_test-file.obj -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Tpo -c -o google/protobuf/testing/protobuf_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/testing/file.cc' object='google/protobuf/testing/protobuf_test-file.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-wire_format_unittest.o `test -f 'google/protobuf/wire_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/wire_format_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
-protobuf_test-wire_format_unittest.obj: google/protobuf/wire_format_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-wire_format_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-wire_format_unittest.Tpo -c -o protobuf_test-wire_format_unittest.obj `if test -f 'google/protobuf/wire_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/wire_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/wire_format_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-wire_format_unittest.Tpo $(DEPDIR)/protobuf_test-wire_format_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/wire_format_unittest.cc' object='protobuf_test-wire_format_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_lite.pb.o: google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_lite.pb.cc' object='google/protobuf/protobuf_test-unittest_lite.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-wire_format_unittest.obj `if test -f 'google/protobuf/wire_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/wire_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/wire_format_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
-protobuf_test-coded_stream_unittest.o: google/protobuf/io/coded_stream_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-coded_stream_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo -c -o protobuf_test-coded_stream_unittest.o `test -f 'google/protobuf/io/coded_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/coded_stream_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo $(DEPDIR)/protobuf_test-coded_stream_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/coded_stream_unittest.cc' object='protobuf_test-coded_stream_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_lite.pb.obj: google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_lite.pb.cc' object='google/protobuf/protobuf_test-unittest_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-coded_stream_unittest.o `test -f 'google/protobuf/io/coded_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/coded_stream_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
-protobuf_test-coded_stream_unittest.obj: google/protobuf/io/coded_stream_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-coded_stream_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo -c -o protobuf_test-coded_stream_unittest.obj `if test -f 'google/protobuf/io/coded_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/coded_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/coded_stream_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo $(DEPDIR)/protobuf_test-coded_stream_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/coded_stream_unittest.cc' object='protobuf_test-coded_stream_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_import_lite.pb.o: google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_lite.pb.cc' object='google/protobuf/protobuf_test-unittest_import_lite.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-coded_stream_unittest.obj `if test -f 'google/protobuf/io/coded_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/coded_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/coded_stream_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
-protobuf_test-printer_unittest.o: google/protobuf/io/printer_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-printer_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-printer_unittest.Tpo -c -o protobuf_test-printer_unittest.o `test -f 'google/protobuf/io/printer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/printer_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-printer_unittest.Tpo $(DEPDIR)/protobuf_test-printer_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/printer_unittest.cc' object='protobuf_test-printer_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_lite.pb.cc' object='google/protobuf/protobuf_test-unittest_import_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-printer_unittest.o `test -f 'google/protobuf/io/printer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/printer_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
-protobuf_test-printer_unittest.obj: google/protobuf/io/printer_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-printer_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-printer_unittest.Tpo -c -o protobuf_test-printer_unittest.obj `if test -f 'google/protobuf/io/printer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/printer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/printer_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-printer_unittest.Tpo $(DEPDIR)/protobuf_test-printer_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/printer_unittest.cc' object='protobuf_test-printer_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_import_public_lite.pb.o: google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import_public_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_public_lite.pb.cc' object='google/protobuf/protobuf_test-unittest_import_public_lite.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-printer_unittest.obj `if test -f 'google/protobuf/io/printer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/printer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/printer_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
-protobuf_test-tokenizer_unittest.o: google/protobuf/io/tokenizer_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-tokenizer_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo -c -o protobuf_test-tokenizer_unittest.o `test -f 'google/protobuf/io/tokenizer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/tokenizer_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo $(DEPDIR)/protobuf_test-tokenizer_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/tokenizer_unittest.cc' object='protobuf_test-tokenizer_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_import_public_lite.pb.obj: google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import_public_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_public_lite.pb.cc' object='google/protobuf/protobuf_test-unittest_import_public_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-tokenizer_unittest.o `test -f 'google/protobuf/io/tokenizer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/tokenizer_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
-protobuf_test-tokenizer_unittest.obj: google/protobuf/io/tokenizer_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-tokenizer_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo -c -o protobuf_test-tokenizer_unittest.obj `if test -f 'google/protobuf/io/tokenizer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/tokenizer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/tokenizer_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo $(DEPDIR)/protobuf_test-tokenizer_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/tokenizer_unittest.cc' object='protobuf_test-tokenizer_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest.pb.o: google/protobuf/unittest.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Tpo -c -o google/protobuf/protobuf_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest.pb.cc' object='google/protobuf/protobuf_test-unittest.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-tokenizer_unittest.obj `if test -f 'google/protobuf/io/tokenizer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/tokenizer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/tokenizer_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
-protobuf_test-zero_copy_stream_unittest.o: google/protobuf/io/zero_copy_stream_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-zero_copy_stream_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo -c -o protobuf_test-zero_copy_stream_unittest.o `test -f 'google/protobuf/io/zero_copy_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo $(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/zero_copy_stream_unittest.cc' object='protobuf_test-zero_copy_stream_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest.pb.obj: google/protobuf/unittest.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Tpo -c -o google/protobuf/protobuf_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest.pb.cc' object='google/protobuf/protobuf_test-unittest.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-zero_copy_stream_unittest.o `test -f 'google/protobuf/io/zero_copy_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi`
-protobuf_test-zero_copy_stream_unittest.obj: google/protobuf/io/zero_copy_stream_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-zero_copy_stream_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo -c -o protobuf_test-zero_copy_stream_unittest.obj `if test -f 'google/protobuf/io/zero_copy_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/zero_copy_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/zero_copy_stream_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo $(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/io/zero_copy_stream_unittest.cc' object='protobuf_test-zero_copy_stream_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_empty.pb.o: google/protobuf/unittest_empty.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_empty.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_empty.pb.cc' object='google/protobuf/protobuf_test-unittest_empty.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-zero_copy_stream_unittest.obj `if test -f 'google/protobuf/io/zero_copy_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/zero_copy_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/zero_copy_stream_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc
-protobuf_test-command_line_interface_unittest.o: google/protobuf/compiler/command_line_interface_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-command_line_interface_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo -c -o protobuf_test-command_line_interface_unittest.o `test -f 'google/protobuf/compiler/command_line_interface_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/command_line_interface_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo $(DEPDIR)/protobuf_test-command_line_interface_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/command_line_interface_unittest.cc' object='protobuf_test-command_line_interface_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_empty.pb.obj: google/protobuf/unittest_empty.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_empty.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_empty.pb.cc' object='google/protobuf/protobuf_test-unittest_empty.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-command_line_interface_unittest.o `test -f 'google/protobuf/compiler/command_line_interface_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/command_line_interface_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi`
-protobuf_test-command_line_interface_unittest.obj: google/protobuf/compiler/command_line_interface_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-command_line_interface_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo -c -o protobuf_test-command_line_interface_unittest.obj `if test -f 'google/protobuf/compiler/command_line_interface_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/command_line_interface_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/command_line_interface_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo $(DEPDIR)/protobuf_test-command_line_interface_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/command_line_interface_unittest.cc' object='protobuf_test-command_line_interface_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_import.pb.o: google/protobuf/unittest_import.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import.pb.cc' object='google/protobuf/protobuf_test-unittest_import.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-command_line_interface_unittest.obj `if test -f 'google/protobuf/compiler/command_line_interface_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/command_line_interface_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/command_line_interface_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc
-protobuf_test-importer_unittest.o: google/protobuf/compiler/importer_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-importer_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-importer_unittest.Tpo -c -o protobuf_test-importer_unittest.o `test -f 'google/protobuf/compiler/importer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/importer_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-importer_unittest.Tpo $(DEPDIR)/protobuf_test-importer_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/importer_unittest.cc' object='protobuf_test-importer_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_import.pb.obj: google/protobuf/unittest_import.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import.pb.cc' object='google/protobuf/protobuf_test-unittest_import.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-importer_unittest.o `test -f 'google/protobuf/compiler/importer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/importer_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
-protobuf_test-importer_unittest.obj: google/protobuf/compiler/importer_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-importer_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-importer_unittest.Tpo -c -o protobuf_test-importer_unittest.obj `if test -f 'google/protobuf/compiler/importer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/importer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/importer_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-importer_unittest.Tpo $(DEPDIR)/protobuf_test-importer_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/importer_unittest.cc' object='protobuf_test-importer_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_import_public.pb.o: google/protobuf/unittest_import_public.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import_public.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_public.pb.cc' object='google/protobuf/protobuf_test-unittest_import_public.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-importer_unittest.obj `if test -f 'google/protobuf/compiler/importer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/importer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/importer_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc
-protobuf_test-mock_code_generator.o: google/protobuf/compiler/mock_code_generator.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-mock_code_generator.o -MD -MP -MF $(DEPDIR)/protobuf_test-mock_code_generator.Tpo -c -o protobuf_test-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-mock_code_generator.Tpo $(DEPDIR)/protobuf_test-mock_code_generator.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/mock_code_generator.cc' object='protobuf_test-mock_code_generator.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_import_public.pb.obj: google/protobuf/unittest_import_public.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import_public.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_import_public.pb.cc' object='google/protobuf/protobuf_test-unittest_import_public.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi`
-protobuf_test-mock_code_generator.obj: google/protobuf/compiler/mock_code_generator.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-mock_code_generator.obj -MD -MP -MF $(DEPDIR)/protobuf_test-mock_code_generator.Tpo -c -o protobuf_test-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-mock_code_generator.Tpo $(DEPDIR)/protobuf_test-mock_code_generator.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/mock_code_generator.cc' object='protobuf_test-mock_code_generator.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_mset.pb.o: google/protobuf/unittest_mset.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_mset.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_mset.pb.cc' object='google/protobuf/protobuf_test-unittest_mset.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
-protobuf_test-parser_unittest.o: google/protobuf/compiler/parser_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-parser_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-parser_unittest.Tpo -c -o protobuf_test-parser_unittest.o `test -f 'google/protobuf/compiler/parser_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/parser_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-parser_unittest.Tpo $(DEPDIR)/protobuf_test-parser_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/parser_unittest.cc' object='protobuf_test-parser_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_mset.pb.obj: google/protobuf/unittest_mset.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_mset.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_mset.pb.cc' object='google/protobuf/protobuf_test-unittest_mset.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-parser_unittest.o `test -f 'google/protobuf/compiler/parser_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/parser_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi`
-protobuf_test-parser_unittest.obj: google/protobuf/compiler/parser_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-parser_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-parser_unittest.Tpo -c -o protobuf_test-parser_unittest.obj `if test -f 'google/protobuf/compiler/parser_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/parser_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/parser_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-parser_unittest.Tpo $(DEPDIR)/protobuf_test-parser_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/parser_unittest.cc' object='protobuf_test-parser_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_optimize_for.pb.o: google/protobuf/unittest_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_optimize_for.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_optimize_for.pb.cc' object='google/protobuf/protobuf_test-unittest_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-parser_unittest.obj `if test -f 'google/protobuf/compiler/parser_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/parser_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/parser_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc
-protobuf_test-cpp_bootstrap_unittest.o: google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_bootstrap_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo -c -o protobuf_test-cpp_bootstrap_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' object='protobuf_test-cpp_bootstrap_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_optimize_for.pb.obj: google/protobuf/unittest_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_optimize_for.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_optimize_for.pb.cc' object='google/protobuf/protobuf_test-unittest_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_bootstrap_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi`
-protobuf_test-cpp_bootstrap_unittest.obj: google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_bootstrap_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo -c -o protobuf_test-cpp_bootstrap_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' object='protobuf_test-cpp_bootstrap_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.o: google/protobuf/unittest_embed_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_bootstrap_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc
-protobuf_test-cpp_unittest.o: google/protobuf/compiler/cpp/cpp_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_unittest.Tpo -c -o protobuf_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='protobuf_test-cpp_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.obj: google/protobuf/unittest_embed_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi`
-protobuf_test-cpp_unittest.obj: google/protobuf/compiler/cpp/cpp_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_unittest.Tpo -c -o protobuf_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='protobuf_test-cpp_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_custom_options.pb.o: google/protobuf/unittest_custom_options.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_custom_options.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_custom_options.pb.cc' object='google/protobuf/protobuf_test-unittest_custom_options.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc
-protobuf_test-cpp_plugin_unittest.o: google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_plugin_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo -c -o protobuf_test-cpp_plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' object='protobuf_test-cpp_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_custom_options.pb.obj: google/protobuf/unittest_custom_options.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_custom_options.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_custom_options.pb.cc' object='google/protobuf/protobuf_test-unittest_custom_options.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi`
-protobuf_test-cpp_plugin_unittest.obj: google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_plugin_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo -c -o protobuf_test-cpp_plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' object='protobuf_test-cpp_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.o: google/protobuf/unittest_lite_imports_nonlite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc
-protobuf_test-java_plugin_unittest.o: google/protobuf/compiler/java/java_plugin_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-java_plugin_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo -c -o protobuf_test-java_plugin_unittest.o `test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_plugin_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-java_plugin_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_plugin_unittest.cc' object='protobuf_test-java_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.obj: google/protobuf/unittest_lite_imports_nonlite.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-java_plugin_unittest.o `test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_plugin_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi`
-protobuf_test-java_plugin_unittest.obj: google/protobuf/compiler/java/java_plugin_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-java_plugin_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo -c -o protobuf_test-java_plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_plugin_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-java_plugin_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_plugin_unittest.cc' object='protobuf_test-java_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_no_generic_services.pb.o: google/protobuf/unittest_no_generic_services.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_no_generic_services.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_no_generic_services.pb.cc' object='google/protobuf/protobuf_test-unittest_no_generic_services.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-java_plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_plugin_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc
-protobuf_test-python_plugin_unittest.o: google/protobuf/compiler/python/python_plugin_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-python_plugin_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo -c -o protobuf_test-python_plugin_unittest.o `test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_plugin_unittest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-python_plugin_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/python/python_plugin_unittest.cc' object='protobuf_test-python_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/protobuf_test-unittest_no_generic_services.pb.obj: google/protobuf/unittest_no_generic_services.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_no_generic_services.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/unittest_no_generic_services.pb.cc' object='google/protobuf/protobuf_test-unittest_no_generic_services.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-python_plugin_unittest.o `test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_plugin_unittest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi`
-protobuf_test-python_plugin_unittest.obj: google/protobuf/compiler/python/python_plugin_unittest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-python_plugin_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo -c -o protobuf_test-python_plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/python_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/python_plugin_unittest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-python_plugin_unittest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/python/python_plugin_unittest.cc' object='protobuf_test-python_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-python_plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/python_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/python_plugin_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
-protobuf_test-test_util.o: google/protobuf/test_util.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-test_util.o -MD -MP -MF $(DEPDIR)/protobuf_test-test_util.Tpo -c -o protobuf_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-test_util.Tpo $(DEPDIR)/protobuf_test-test_util.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/test_util.cc' object='protobuf_test-test_util.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi`
-protobuf_test-test_util.obj: google/protobuf/test_util.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-test_util.obj -MD -MP -MF $(DEPDIR)/protobuf_test-test_util.Tpo -c -o protobuf_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-test_util.Tpo $(DEPDIR)/protobuf_test-test_util.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/test_util.cc' object='protobuf_test-test_util.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/test_plugin-mock_code_generator.o: google/protobuf/compiler/mock_code_generator.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/test_plugin-mock_code_generator.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Tpo -c -o google/protobuf/compiler/test_plugin-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Tpo google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/mock_code_generator.cc' object='google/protobuf/compiler/test_plugin-mock_code_generator.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/test_plugin-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc
-protobuf_test-googletest.o: google/protobuf/testing/googletest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-googletest.o -MD -MP -MF $(DEPDIR)/protobuf_test-googletest.Tpo -c -o protobuf_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-googletest.Tpo $(DEPDIR)/protobuf_test-googletest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/googletest.cc' object='protobuf_test-googletest.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/test_plugin-mock_code_generator.obj: google/protobuf/compiler/mock_code_generator.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/test_plugin-mock_code_generator.obj -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Tpo -c -o google/protobuf/compiler/test_plugin-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Tpo google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/mock_code_generator.cc' object='google/protobuf/compiler/test_plugin-mock_code_generator.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/test_plugin-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi`
-protobuf_test-googletest.obj: google/protobuf/testing/googletest.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-googletest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-googletest.Tpo -c -o protobuf_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-googletest.Tpo $(DEPDIR)/protobuf_test-googletest.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/googletest.cc' object='protobuf_test-googletest.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/testing/test_plugin-file.o: google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/test_plugin-file.o -MD -MP -MF google/protobuf/testing/$(DEPDIR)/test_plugin-file.Tpo -c -o google/protobuf/testing/test_plugin-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/test_plugin-file.Tpo google/protobuf/testing/$(DEPDIR)/test_plugin-file.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/testing/file.cc' object='google/protobuf/testing/test_plugin-file.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/test_plugin-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
-protobuf_test-file.o: google/protobuf/testing/file.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-file.o -MD -MP -MF $(DEPDIR)/protobuf_test-file.Tpo -c -o protobuf_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-file.Tpo $(DEPDIR)/protobuf_test-file.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='protobuf_test-file.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/testing/test_plugin-file.obj: google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/test_plugin-file.obj -MD -MP -MF google/protobuf/testing/$(DEPDIR)/test_plugin-file.Tpo -c -o google/protobuf/testing/test_plugin-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/test_plugin-file.Tpo google/protobuf/testing/$(DEPDIR)/test_plugin-file.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/testing/file.cc' object='google/protobuf/testing/test_plugin-file.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/test_plugin-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
-protobuf_test-file.obj: google/protobuf/testing/file.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-file.obj -MD -MP -MF $(DEPDIR)/protobuf_test-file.Tpo -c -o protobuf_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-file.Tpo $(DEPDIR)/protobuf_test-file.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='protobuf_test-file.obj' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/test_plugin-test_plugin.o: google/protobuf/compiler/test_plugin.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/test_plugin-test_plugin.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Tpo -c -o google/protobuf/compiler/test_plugin-test_plugin.o `test -f 'google/protobuf/compiler/test_plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/test_plugin.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Tpo google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/test_plugin.cc' object='google/protobuf/compiler/test_plugin-test_plugin.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/test_plugin-test_plugin.o `test -f 'google/protobuf/compiler/test_plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/test_plugin.cc
-protobuf_test-unittest_lite.pb.o: google/protobuf/unittest_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo -c -o protobuf_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_lite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite.pb.cc' object='protobuf_test-unittest_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+google/protobuf/compiler/test_plugin-test_plugin.obj: google/protobuf/compiler/test_plugin.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/test_plugin-test_plugin.obj -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Tpo -c -o google/protobuf/compiler/test_plugin-test_plugin.obj `if test -f 'google/protobuf/compiler/test_plugin.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/test_plugin.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/test_plugin.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Tpo google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/test_plugin.cc' object='google/protobuf/compiler/test_plugin-test_plugin.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
-
-protobuf_test-unittest_lite.pb.obj: google/protobuf/unittest_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo -c -o protobuf_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_lite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite.pb.cc' object='protobuf_test-unittest_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
-
-protobuf_test-unittest_import_lite.pb.o: google/protobuf/unittest_import_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo -c -o protobuf_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import_lite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_lite.pb.cc' object='protobuf_test-unittest_import_lite.pb.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
-
-protobuf_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_lite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo -c -o protobuf_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import_lite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_lite.pb.cc' object='protobuf_test-unittest_import_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
-
-protobuf_test-unittest.pb.o: google/protobuf/unittest.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest.pb.Tpo -c -o protobuf_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest.pb.Tpo $(DEPDIR)/protobuf_test-unittest.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest.pb.cc' object='protobuf_test-unittest.pb.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
-
-protobuf_test-unittest.pb.obj: google/protobuf/unittest.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest.pb.Tpo -c -o protobuf_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest.pb.Tpo $(DEPDIR)/protobuf_test-unittest.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest.pb.cc' object='protobuf_test-unittest.pb.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi`
-
-protobuf_test-unittest_empty.pb.o: google/protobuf/unittest_empty.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_empty.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo -c -o protobuf_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo $(DEPDIR)/protobuf_test-unittest_empty.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_empty.pb.cc' object='protobuf_test-unittest_empty.pb.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc
-
-protobuf_test-unittest_empty.pb.obj: google/protobuf/unittest_empty.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_empty.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo -c -o protobuf_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo $(DEPDIR)/protobuf_test-unittest_empty.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_empty.pb.cc' object='protobuf_test-unittest_empty.pb.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi`
-
-protobuf_test-unittest_import.pb.o: google/protobuf/unittest_import.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import.pb.Tpo -c -o protobuf_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import.pb.cc' object='protobuf_test-unittest_import.pb.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc
-
-protobuf_test-unittest_import.pb.obj: google/protobuf/unittest_import.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import.pb.Tpo -c -o protobuf_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import.pb.cc' object='protobuf_test-unittest_import.pb.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
-
-protobuf_test-unittest_mset.pb.o: google/protobuf/unittest_mset.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_mset.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo -c -o protobuf_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo $(DEPDIR)/protobuf_test-unittest_mset.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_mset.pb.cc' object='protobuf_test-unittest_mset.pb.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
-
-protobuf_test-unittest_mset.pb.obj: google/protobuf/unittest_mset.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_mset.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo -c -o protobuf_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo $(DEPDIR)/protobuf_test-unittest_mset.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_mset.pb.cc' object='protobuf_test-unittest_mset.pb.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi`
-
-protobuf_test-unittest_optimize_for.pb.o: google/protobuf/unittest_optimize_for.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_optimize_for.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo -c -o protobuf_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo $(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_optimize_for.pb.cc' object='protobuf_test-unittest_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc
-
-protobuf_test-unittest_optimize_for.pb.obj: google/protobuf/unittest_optimize_for.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_optimize_for.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo -c -o protobuf_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo $(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_optimize_for.pb.cc' object='protobuf_test-unittest_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi`
-
-protobuf_test-unittest_embed_optimize_for.pb.o: google/protobuf/unittest_embed_optimize_for.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_embed_optimize_for.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo -c -o protobuf_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo $(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='protobuf_test-unittest_embed_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc
-
-protobuf_test-unittest_embed_optimize_for.pb.obj: google/protobuf/unittest_embed_optimize_for.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_embed_optimize_for.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo -c -o protobuf_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo $(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='protobuf_test-unittest_embed_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi`
-
-protobuf_test-unittest_custom_options.pb.o: google/protobuf/unittest_custom_options.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_custom_options.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo -c -o protobuf_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo $(DEPDIR)/protobuf_test-unittest_custom_options.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_custom_options.pb.cc' object='protobuf_test-unittest_custom_options.pb.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc
-
-protobuf_test-unittest_custom_options.pb.obj: google/protobuf/unittest_custom_options.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_custom_options.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo -c -o protobuf_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo $(DEPDIR)/protobuf_test-unittest_custom_options.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_custom_options.pb.cc' object='protobuf_test-unittest_custom_options.pb.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi`
-
-protobuf_test-unittest_lite_imports_nonlite.pb.o: google/protobuf/unittest_lite_imports_nonlite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_lite_imports_nonlite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo -c -o protobuf_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='protobuf_test-unittest_lite_imports_nonlite.pb.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc
-
-protobuf_test-unittest_lite_imports_nonlite.pb.obj: google/protobuf/unittest_lite_imports_nonlite.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_lite_imports_nonlite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo -c -o protobuf_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='protobuf_test-unittest_lite_imports_nonlite.pb.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi`
-
-protobuf_test-unittest_no_generic_services.pb.o: google/protobuf/unittest_no_generic_services.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_no_generic_services.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo -c -o protobuf_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_no_generic_services.pb.cc' object='protobuf_test-unittest_no_generic_services.pb.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc
-
-protobuf_test-unittest_no_generic_services.pb.obj: google/protobuf/unittest_no_generic_services.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_no_generic_services.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo -c -o protobuf_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_no_generic_services.pb.cc' object='protobuf_test-unittest_no_generic_services.pb.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi`
-
-protobuf_test-cpp_test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_test_bad_identifiers.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo -c -o protobuf_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='protobuf_test-cpp_test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
-
-protobuf_test-cpp_test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_test_bad_identifiers.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo -c -o protobuf_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='protobuf_test-cpp_test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi`
-
-main.o: google/protobuf/compiler/main.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT main.o -MD -MP -MF $(DEPDIR)/main.Tpo -c -o main.o `test -f 'google/protobuf/compiler/main.cc' || echo '$(srcdir)/'`google/protobuf/compiler/main.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/main.Tpo $(DEPDIR)/main.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/main.cc' object='main.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o main.o `test -f 'google/protobuf/compiler/main.cc' || echo '$(srcdir)/'`google/protobuf/compiler/main.cc
-
-main.obj: google/protobuf/compiler/main.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT main.obj -MD -MP -MF $(DEPDIR)/main.Tpo -c -o main.obj `if test -f 'google/protobuf/compiler/main.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/main.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/main.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/main.Tpo $(DEPDIR)/main.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/main.cc' object='main.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o main.obj `if test -f 'google/protobuf/compiler/main.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/main.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/main.cc'; fi`
-
-test_plugin-mock_code_generator.o: google/protobuf/compiler/mock_code_generator.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-mock_code_generator.o -MD -MP -MF $(DEPDIR)/test_plugin-mock_code_generator.Tpo -c -o test_plugin-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/test_plugin-mock_code_generator.Tpo $(DEPDIR)/test_plugin-mock_code_generator.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/mock_code_generator.cc' object='test_plugin-mock_code_generator.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc
-
-test_plugin-mock_code_generator.obj: google/protobuf/compiler/mock_code_generator.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-mock_code_generator.obj -MD -MP -MF $(DEPDIR)/test_plugin-mock_code_generator.Tpo -c -o test_plugin-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/test_plugin-mock_code_generator.Tpo $(DEPDIR)/test_plugin-mock_code_generator.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/mock_code_generator.cc' object='test_plugin-mock_code_generator.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi`
-
-test_plugin-file.o: google/protobuf/testing/file.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-file.o -MD -MP -MF $(DEPDIR)/test_plugin-file.Tpo -c -o test_plugin-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/test_plugin-file.Tpo $(DEPDIR)/test_plugin-file.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='test_plugin-file.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
-
-test_plugin-file.obj: google/protobuf/testing/file.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-file.obj -MD -MP -MF $(DEPDIR)/test_plugin-file.Tpo -c -o test_plugin-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/test_plugin-file.Tpo $(DEPDIR)/test_plugin-file.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='test_plugin-file.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
-
-test_plugin-test_plugin.o: google/protobuf/compiler/test_plugin.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-test_plugin.o -MD -MP -MF $(DEPDIR)/test_plugin-test_plugin.Tpo -c -o test_plugin-test_plugin.o `test -f 'google/protobuf/compiler/test_plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/test_plugin.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/test_plugin-test_plugin.Tpo $(DEPDIR)/test_plugin-test_plugin.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/test_plugin.cc' object='test_plugin-test_plugin.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-test_plugin.o `test -f 'google/protobuf/compiler/test_plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/test_plugin.cc
-
-test_plugin-test_plugin.obj: google/protobuf/compiler/test_plugin.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-test_plugin.obj -MD -MP -MF $(DEPDIR)/test_plugin-test_plugin.Tpo -c -o test_plugin-test_plugin.obj `if test -f 'google/protobuf/compiler/test_plugin.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/test_plugin.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/test_plugin.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/test_plugin-test_plugin.Tpo $(DEPDIR)/test_plugin-test_plugin.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/test_plugin.cc' object='test_plugin-test_plugin.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-test_plugin.obj `if test -f 'google/protobuf/compiler/test_plugin.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/test_plugin.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/test_plugin.cc'; fi`
-
-zcgunzip.o: google/protobuf/testing/zcgunzip.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zcgunzip.o -MD -MP -MF $(DEPDIR)/zcgunzip.Tpo -c -o zcgunzip.o `test -f 'google/protobuf/testing/zcgunzip.cc' || echo '$(srcdir)/'`google/protobuf/testing/zcgunzip.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zcgunzip.Tpo $(DEPDIR)/zcgunzip.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/zcgunzip.cc' object='zcgunzip.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zcgunzip.o `test -f 'google/protobuf/testing/zcgunzip.cc' || echo '$(srcdir)/'`google/protobuf/testing/zcgunzip.cc
-
-zcgunzip.obj: google/protobuf/testing/zcgunzip.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zcgunzip.obj -MD -MP -MF $(DEPDIR)/zcgunzip.Tpo -c -o zcgunzip.obj `if test -f 'google/protobuf/testing/zcgunzip.cc'; then $(CYGPATH_W) 'google/protobuf/testing/zcgunzip.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/zcgunzip.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zcgunzip.Tpo $(DEPDIR)/zcgunzip.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/zcgunzip.cc' object='zcgunzip.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zcgunzip.obj `if test -f 'google/protobuf/testing/zcgunzip.cc'; then $(CYGPATH_W) 'google/protobuf/testing/zcgunzip.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/zcgunzip.cc'; fi`
-
-zcgzip.o: google/protobuf/testing/zcgzip.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zcgzip.o -MD -MP -MF $(DEPDIR)/zcgzip.Tpo -c -o zcgzip.o `test -f 'google/protobuf/testing/zcgzip.cc' || echo '$(srcdir)/'`google/protobuf/testing/zcgzip.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zcgzip.Tpo $(DEPDIR)/zcgzip.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/zcgzip.cc' object='zcgzip.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zcgzip.o `test -f 'google/protobuf/testing/zcgzip.cc' || echo '$(srcdir)/'`google/protobuf/testing/zcgzip.cc
-
-zcgzip.obj: google/protobuf/testing/zcgzip.cc
-@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zcgzip.obj -MD -MP -MF $(DEPDIR)/zcgzip.Tpo -c -o zcgzip.obj `if test -f 'google/protobuf/testing/zcgzip.cc'; then $(CYGPATH_W) 'google/protobuf/testing/zcgzip.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/zcgzip.cc'; fi`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/zcgzip.Tpo $(DEPDIR)/zcgzip.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/zcgzip.cc' object='zcgzip.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zcgzip.obj `if test -f 'google/protobuf/testing/zcgzip.cc'; then $(CYGPATH_W) 'google/protobuf/testing/zcgzip.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/zcgzip.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/test_plugin-test_plugin.obj `if test -f 'google/protobuf/compiler/test_plugin.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/test_plugin.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/test_plugin.cc'; fi`
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
+ -rm -rf google/protobuf/.libs google/protobuf/_libs
+ -rm -rf google/protobuf/compiler/.libs google/protobuf/compiler/_libs
+ -rm -rf google/protobuf/compiler/cpp/.libs google/protobuf/compiler/cpp/_libs
+ -rm -rf google/protobuf/compiler/java/.libs google/protobuf/compiler/java/_libs
+ -rm -rf google/protobuf/compiler/javamicro/.libs google/protobuf/compiler/javamicro/_libs
+ -rm -rf google/protobuf/compiler/javanano/.libs google/protobuf/compiler/javanano/_libs
+ -rm -rf google/protobuf/compiler/python/.libs google/protobuf/compiler/python/_libs
+ -rm -rf google/protobuf/io/.libs google/protobuf/io/_libs
+ -rm -rf google/protobuf/stubs/.libs google/protobuf/stubs/_libs
install-nobase_dist_protoDATA: $(nobase_dist_proto_DATA)
@$(NORMAL_INSTALL)
- test -z "$(protodir)" || $(MKDIR_P) "$(DESTDIR)$(protodir)"
@list='$(nobase_dist_proto_DATA)'; test -n "$(protodir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(protodir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(protodir)" || exit 1; \
+ fi; \
$(am__nobase_list) | while read dir files; do \
xfiles=; for file in $$files; do \
if test -f "$$file"; then xfiles="$$xfiles $$file"; \
else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
test -z "$$xfiles" || { \
test "x$$dir" = x. || { \
- echo "$(MKDIR_P) '$(DESTDIR)$(protodir)/$$dir'"; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(protodir)/$$dir'"; \
$(MKDIR_P) "$(DESTDIR)$(protodir)/$$dir"; }; \
echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(protodir)/$$dir'"; \
$(INSTALL_DATA) $$xfiles "$(DESTDIR)$(protodir)/$$dir" || exit $$?; }; \
@@ -2715,15 +3312,18 @@ uninstall-nobase_dist_protoDATA:
dir='$(DESTDIR)$(protodir)'; $(am__uninstall_files_from_dir)
install-nobase_includeHEADERS: $(nobase_include_HEADERS)
@$(NORMAL_INSTALL)
- test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
@list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+ fi; \
$(am__nobase_list) | while read dir files; do \
xfiles=; for file in $$files; do \
if test -f "$$file"; then xfiles="$$xfiles $$file"; \
else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
test -z "$$xfiles" || { \
test "x$$dir" = x. || { \
- echo "$(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \
$(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \
echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \
$(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \
@@ -2735,26 +3335,15 @@ uninstall-nobase_includeHEADERS:
$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ $(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
@@ -2766,15 +3355,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$$unique; \
fi; \
fi
-ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
@@ -2783,102 +3368,215 @@ GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-check-TESTS: $(TESTS)
- @failed=0; all=0; xfail=0; xpass=0; skip=0; \
- srcdir=$(srcdir); export srcdir; \
- list=' $(TESTS) '; \
- $(am__tty_colors); \
- if test -n "$$list"; then \
- for tst in $$list; do \
- if test -f ./$$tst; then dir=./; \
- elif test -f $$tst; then dir=; \
- else dir="$(srcdir)/"; fi; \
- if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
- all=`expr $$all + 1`; \
- case " $(XFAIL_TESTS) " in \
- *[\ \ ]$$tst[\ \ ]*) \
- xpass=`expr $$xpass + 1`; \
- failed=`expr $$failed + 1`; \
- col=$$red; res=XPASS; \
- ;; \
- *) \
- col=$$grn; res=PASS; \
- ;; \
- esac; \
- elif test $$? -ne 77; then \
- all=`expr $$all + 1`; \
- case " $(XFAIL_TESTS) " in \
- *[\ \ ]$$tst[\ \ ]*) \
- xfail=`expr $$xfail + 1`; \
- col=$$lgn; res=XFAIL; \
- ;; \
- *) \
- failed=`expr $$failed + 1`; \
- col=$$red; res=FAIL; \
- ;; \
- esac; \
- else \
- skip=`expr $$skip + 1`; \
- col=$$blu; res=SKIP; \
- fi; \
- echo "$${col}$$res$${std}: $$tst"; \
- done; \
- if test "$$all" -eq 1; then \
- tests="test"; \
- All=""; \
- else \
- tests="tests"; \
- All="All "; \
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
fi; \
- if test "$$failed" -eq 0; then \
- if test "$$xfail" -eq 0; then \
- banner="$$All$$all $$tests passed"; \
- else \
- if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
- banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
- fi; \
- else \
- if test "$$xpass" -eq 0; then \
- banner="$$failed of $$all $$tests failed"; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ else \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
else \
- if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
- banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
fi; \
- fi; \
- dashes="$$banner"; \
- skipped=""; \
- if test "$$skip" -ne 0; then \
- if test "$$skip" -eq 1; then \
- skipped="($$skip test was not run)"; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
else \
- skipped="($$skip tests were not run)"; \
+ color_start= color_end=; \
fi; \
- test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
- dashes="$$skipped"; \
- fi; \
- report=""; \
- if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
- report="Please report to $(PACKAGE_BUGREPORT)"; \
- test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
- dashes="$$report"; \
- fi; \
- dashes=`echo "$$dashes" | sed s/./=/g`; \
- if test "$$failed" -eq 0; then \
- col="$$grn"; \
- else \
- col="$$red"; \
- fi; \
- echo "$${col}$$dashes$${std}"; \
- echo "$${col}$$banner$${std}"; \
- test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
- test -z "$$report" || echo "$${col}$$report$${std}"; \
- echo "$${col}$$dashes$${std}"; \
- test "$$failed" -eq 0; \
- else :; fi
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+protobuf-test.log: protobuf-test$(EXEEXT)
+ @p='protobuf-test$(EXEEXT)'; \
+ b='protobuf-test'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+protobuf-lazy-descriptor-test.log: protobuf-lazy-descriptor-test$(EXEEXT)
+ @p='protobuf-lazy-descriptor-test$(EXEEXT)'; \
+ b='protobuf-lazy-descriptor-test'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+protobuf-lite-test.log: protobuf-lite-test$(EXEEXT)
+ @p='protobuf-lite-test$(EXEEXT)'; \
+ b='protobuf-lite-test'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+google/protobuf/compiler/zip_output_unittest.sh.log: google/protobuf/compiler/zip_output_unittest.sh
+ @p='google/protobuf/compiler/zip_output_unittest.sh'; \
+ b='google/protobuf/compiler/zip_output_unittest.sh'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+google/protobuf/io/gzip_stream_unittest.sh.log: google/protobuf/io/gzip_stream_unittest.sh
+ @p='google/protobuf/io/gzip_stream_unittest.sh'; \
+ b='google/protobuf/io/gzip_stream_unittest.sh'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -2943,6 +3641,9 @@ install-strip:
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
@@ -2950,6 +3651,26 @@ clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -rm -f google/protobuf/$(DEPDIR)/$(am__dirstamp)
+ -rm -f google/protobuf/$(am__dirstamp)
+ -rm -f google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+ -rm -f google/protobuf/compiler/$(am__dirstamp)
+ -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+ -rm -f google/protobuf/compiler/cpp/$(am__dirstamp)
+ -rm -f google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+ -rm -f google/protobuf/compiler/java/$(am__dirstamp)
+ -rm -f google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+ -rm -f google/protobuf/compiler/javamicro/$(am__dirstamp)
+ -rm -f google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+ -rm -f google/protobuf/compiler/javanano/$(am__dirstamp)
+ -rm -f google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp)
+ -rm -f google/protobuf/compiler/python/$(am__dirstamp)
+ -rm -f google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+ -rm -f google/protobuf/io/$(am__dirstamp)
+ -rm -f google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+ -rm -f google/protobuf/stubs/$(am__dirstamp)
+ -rm -f google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+ -rm -f google/protobuf/testing/$(am__dirstamp)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -2962,7 +3683,7 @@ clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
clean-libLTLIBRARIES clean-libtool clean-local mostlyclean-am
distclean: distclean-am
- -rm -rf ./$(DEPDIR)
+ -rm -rf google/protobuf/$(DEPDIR) google/protobuf/compiler/$(DEPDIR) google/protobuf/compiler/cpp/$(DEPDIR) google/protobuf/compiler/java/$(DEPDIR) google/protobuf/compiler/javamicro/$(DEPDIR) google/protobuf/compiler/javanano/$(DEPDIR) google/protobuf/compiler/python/$(DEPDIR) google/protobuf/io/$(DEPDIR) google/protobuf/stubs/$(DEPDIR) google/protobuf/testing/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@@ -3009,7 +3730,7 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR)
+ -rm -rf google/protobuf/$(DEPDIR) google/protobuf/compiler/$(DEPDIR) google/protobuf/compiler/cpp/$(DEPDIR) google/protobuf/compiler/java/$(DEPDIR) google/protobuf/compiler/javamicro/$(DEPDIR) google/protobuf/compiler/javanano/$(DEPDIR) google/protobuf/compiler/python/$(DEPDIR) google/protobuf/io/$(DEPDIR) google/protobuf/stubs/$(DEPDIR) google/protobuf/testing/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
@@ -3032,21 +3753,22 @@ uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
.MAKE: all check check-am install install-am install-strip
-.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
- clean-libLTLIBRARIES clean-libtool clean-local ctags distclean \
- distclean-compile distclean-generic distclean-libtool \
- distclean-tags distdir dvi dvi-am html html-am info info-am \
- install install-am install-binPROGRAMS install-data \
- install-data-am install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-libLTLIBRARIES install-man \
- install-nobase_dist_protoDATA install-nobase_includeHEADERS \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ clean-libLTLIBRARIES clean-libtool clean-local cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-libLTLIBRARIES \
+ install-man install-nobase_dist_protoDATA \
+ install-nobase_includeHEADERS install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am \
uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
uninstall-nobase_dist_protoDATA \
uninstall-nobase_includeHEADERS
diff --git a/src/google/protobuf/SEBS b/src/google/protobuf/SEBS
new file mode 100644
index 0000000..ba33c73
--- /dev/null
+++ b/src/google/protobuf/SEBS
@@ -0,0 +1,240 @@
+# **EXPERIMENTAL**
+#
+# See http://sebs.googlecode.com
+#
+# This is an experimental build definition file using the SEBS build system.
+# I (Kenton Varda, maintainer of Protocol Buffers) happen to be the author of
+# SEBS, though SEBS is not a Google project. I'm sticking this file in
+# protobuf's SVN because that's the easiest place for me to put it, and it
+# shouldn't harm anyone. This file is not included in the distribution.
+#
+# Currently, to use this file, you must generate config.h and put it at the
+# top level of the source tree.
+
+_cpp = sebs.import_("//sebs/cpp.sebs")
+
+# ====================================================================
+# Public targets
+
+protobuf_lite = _cpp.Library(
+ name = "protobuf-lite",
+ srcs = [ "stubs/common.cc",
+ "stubs/once.cc",
+ "stubs/hash.cc",
+ "stubs/hash.h",
+ "stubs/map-util.h",
+ "stubs/stl_util-inl.h",
+ "extension_set.cc",
+ "generated_message_util.cc",
+ "message_lite.cc",
+ "repeated_field.cc",
+ "wire_format_lite.cc",
+ "io/coded_stream.cc",
+ "io/zero_copy_stream.cc",
+ "io/zero_copy_stream_impl_lite.cc" ],
+ deps = [ _cpp.SystemLibrary(name = "pthread") ])
+
+protobuf = _cpp.Library(
+ name = "protobuf",
+ srcs = [ "stubs/strutil.cc",
+ "stubs/strutil.h",
+ "stubs/substitute.cc",
+ "stubs/substitute.h",
+ "stubs/structurally_valid.cc",
+ "descriptor.cc",
+ "descriptor.pb.cc",
+ "descriptor_database.cc",
+ "dynamic_message.cc",
+ "extension_set_heavy.cc",
+ "generated_message_reflection.cc",
+ "message.cc",
+ "reflection_ops.cc",
+ "service.cc",
+ "text_format.cc",
+ "unknown_field_set.cc",
+ "wire_format.cc",
+ "io/gzip_stream.cc",
+ "io/printer.cc",
+ "io/tokenizer.cc",
+ "io/zero_copy_stream_impl.cc",
+ "compiler/importer.cc",
+ "compiler/parser.cc" ],
+ deps = [ protobuf_lite,
+ _cpp.SystemLibrary(name = "z") ])
+
+libprotoc = _cpp.Library(
+ name = "protoc",
+ srcs = [ "compiler/code_generator.cc",
+ "compiler/command_line_interface.cc",
+ "compiler/cpp/cpp_enum.cc",
+ "compiler/cpp/cpp_enum.h",
+ "compiler/cpp/cpp_enum_field.cc",
+ "compiler/cpp/cpp_enum_field.h",
+ "compiler/cpp/cpp_extension.cc",
+ "compiler/cpp/cpp_extension.h",
+ "compiler/cpp/cpp_field.cc",
+ "compiler/cpp/cpp_field.h",
+ "compiler/cpp/cpp_file.cc",
+ "compiler/cpp/cpp_file.h",
+ "compiler/cpp/cpp_generator.cc",
+ "compiler/cpp/cpp_helpers.cc",
+ "compiler/cpp/cpp_helpers.h",
+ "compiler/cpp/cpp_message.cc",
+ "compiler/cpp/cpp_message.h",
+ "compiler/cpp/cpp_message_field.cc",
+ "compiler/cpp/cpp_message_field.h",
+ "compiler/cpp/cpp_primitive_field.cc",
+ "compiler/cpp/cpp_primitive_field.h",
+ "compiler/cpp/cpp_service.cc",
+ "compiler/cpp/cpp_service.h",
+ "compiler/cpp/cpp_string_field.cc",
+ "compiler/cpp/cpp_string_field.h",
+ "compiler/java/java_enum.cc",
+ "compiler/java/java_enum.h",
+ "compiler/java/java_enum_field.cc",
+ "compiler/java/java_enum_field.h",
+ "compiler/java/java_extension.cc",
+ "compiler/java/java_extension.h",
+ "compiler/java/java_field.cc",
+ "compiler/java/java_field.h",
+ "compiler/java/java_file.cc",
+ "compiler/java/java_file.h",
+ "compiler/java/java_generator.cc",
+ "compiler/java/java_helpers.cc",
+ "compiler/java/java_helpers.h",
+ "compiler/java/java_message.cc",
+ "compiler/java/java_message.h",
+ "compiler/java/java_message_field.cc",
+ "compiler/java/java_message_field.h",
+ "compiler/java/java_primitive_field.cc",
+ "compiler/java/java_primitive_field.h",
+ "compiler/java/java_service.cc",
+ "compiler/java/java_service.h",
+ "compiler/python/python_generator.cc" ],
+ deps = [ protobuf ])
+
+protoc = _cpp.Binary(
+ name = "protoc",
+ srcs = [ "compiler/main.cc" ],
+ deps = [ libprotoc ])
+
+# ====================================================================
+# ProtobufLibrary rule class
+
+class ProtobufLibrary(sebs.Rule):
+ argument_spec = sebs.ArgumentSpec(srcs = [sebs.Artifact],
+ deps = ([sebs.Rule], []),
+ lite = (bool, False))
+
+ def _expand(self, args):
+ for dep in args.deps:
+ if not isinstance(dep, ProtobufLibrary):
+ raise sebs.DefinitionError(
+ "Dependency of ProtobufLibrary is not a ProtobufLibrary: %s" % dep)
+
+ protoc.expand_once()
+
+ # We must build protoc for the host configuration to allow cross-compiling.
+ host_protoc = self.context.configured_artifact(protoc.binary, "host")
+
+ protoc_action = self.context.action(self, "protobuf")
+ protoc_args = [host_protoc, "-Isrc", "-Itmp", "-Iinclude","--cpp_out=tmp"]
+
+ cpp_srcs = []
+ for src in args.srcs:
+ protoc_args.append(src)
+
+ # We cannot build .proto files from other packages because the .pb.cc
+ # and .pb.h files would be written to that package, and we aren't allowed
+ # to write to other packages.
+ if self.context.local_filename(src) is None:
+ raise sebs.DefinitionError(
+ "Source file is not in this package: %s" % src)
+
+ cc_artifact = self.context.derived_artifact(src, ".pb.cc", protoc_action)
+ header_artifact = self.context.derived_artifact(
+ src, ".pb.h", protoc_action)
+
+ cpp_srcs.append(cc_artifact)
+ cpp_srcs.append(header_artifact)
+
+ protoc_action.set_command(
+ sebs.SubprocessCommand(protoc_action, protoc_args, implicit = cpp_srcs))
+
+ deps = list(args.deps)
+ if args.lite:
+ deps.append(protobuf_lite)
+ else:
+ deps.append(protobuf)
+
+ self.__cpp_library = _cpp.Library(srcs = cpp_srcs, deps = deps,
+ context = self.context)
+ self.__cpp_library.label = self.label
+ self.outputs = []
+
+ def as_cpp_library(self):
+ self.expand_once()
+ return self.__cpp_library
+
+# ====================================================================
+# Tests
+
+_lite_test_protos = ProtobufLibrary(
+ srcs = [ "unittest_lite.proto",
+ "unittest_import_lite.proto" ],
+ lite = True)
+_test_protos = ProtobufLibrary(
+ srcs = [ "unittest.proto",
+ "unittest_empty.proto",
+ "unittest_import.proto",
+ "unittest_mset.proto",
+ "unittest_optimize_for.proto",
+ "unittest_embed_optimize_for.proto",
+ "unittest_custom_options.proto",
+ "unittest_lite_imports_nonlite.proto",
+ "compiler/cpp/cpp_test_bad_identifiers.proto" ],
+ deps = [ _lite_test_protos ])
+
+_test_util = _cpp.Library(
+ name = "test_util",
+ srcs = [ "test_util.cc",
+ "test_util.h",
+ "testing/googletest.cc",
+ "testing/googletest.h",
+ "testing/file.cc",
+ "testing/file.h" ],
+ deps = [ protobuf, _test_protos, _cpp.SystemLibrary(name = "gtest")] )
+
+protobuf_lite_test = _cpp.Test(
+ srcs = [ "lite_unittest.cc",
+ "test_util_lite.cc",
+ "test_util_lite.h" ],
+ deps = [ _lite_test_protos ])
+
+protobuf_test = _cpp.Test(
+ srcs = [ "stubs/common_unittest.cc",
+ "stubs/once_unittest.cc",
+ "stubs/strutil_unittest.cc",
+ "stubs/structurally_valid_unittest.cc",
+ "descriptor_database_unittest.cc",
+ "descriptor_unittest.cc",
+ "dynamic_message_unittest.cc",
+ "extension_set_unittest.cc",
+ "generated_message_reflection_unittest.cc",
+ "message_unittest.cc",
+ "reflection_ops_unittest.cc",
+ "repeated_field_unittest.cc",
+ "text_format_unittest.cc",
+ "unknown_field_set_unittest.cc",
+ "wire_format_unittest.cc",
+ "io/coded_stream_unittest.cc",
+ "io/printer_unittest.cc",
+ "io/tokenizer_unittest.cc",
+ "io/zero_copy_stream_unittest.cc",
+ "compiler/command_line_interface_unittest.cc",
+ "compiler/importer_unittest.cc",
+ "compiler/parser_unittest.cc",
+ "compiler/cpp/cpp_bootstrap_unittest.cc",
+ "compiler/cpp/cpp_unittest.cc" ],
+ deps = [ protobuf, libprotoc, _test_util,
+ _cpp.SystemLibrary(name = "gtest_main") ])
diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc
index 3413a36..0039b00 100644
--- a/src/google/protobuf/compiler/code_generator.cc
+++ b/src/google/protobuf/compiler/code_generator.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -42,19 +42,28 @@ namespace protobuf {
namespace compiler {
CodeGenerator::~CodeGenerator() {}
-OutputDirectory::~OutputDirectory() {}
+GeneratorContext::~GeneratorContext() {}
-io::ZeroCopyOutputStream* OutputDirectory::OpenForInsert(
+io::ZeroCopyOutputStream*
+GeneratorContext::OpenForAppend(const string& filename) {
+ return NULL;
+}
+
+io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert(
const string& filename, const string& insertion_point) {
- GOOGLE_LOG(FATAL) << "This OutputDirectory does not support insertion.";
+ GOOGLE_LOG(FATAL) << "This GeneratorContext does not support insertion.";
return NULL; // make compiler happy
}
+void GeneratorContext::ListParsedFiles(
+ vector<const FileDescriptor*>* output) {
+ GOOGLE_LOG(FATAL) << "This GeneratorContext does not support ListParsedFiles";
+}
+
// Parses a set of comma-delimited name/value pairs.
void ParseGeneratorParameter(const string& text,
vector<pair<string, string> >* output) {
- vector<string> parts;
- SplitStringUsing(text, ",", &parts);
+ vector<string> parts = Split(text, ",", true);
for (int i = 0; i < parts.size(); i++) {
string::size_type equals_pos = parts[i].find_first_of('=');
diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h
index ea094cd..321a8cc 100644
--- a/src/google/protobuf/compiler/code_generator.h
+++ b/src/google/protobuf/compiler/code_generator.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -53,7 +53,7 @@ namespace compiler {
// Defined in this file.
class CodeGenerator;
-class OutputDirectory;
+class GeneratorContext;
// The abstract interface to a class which generates code implementing a
// particular proto file in a particular language. A number of these may
@@ -76,7 +76,7 @@ class LIBPROTOC_EXPORT CodeGenerator {
// the problem (e.g. "invalid parameter") and returns false.
virtual bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
string* error) const = 0;
private:
@@ -85,11 +85,12 @@ class LIBPROTOC_EXPORT CodeGenerator {
// CodeGenerators generate one or more files in a given directory. This
// abstract interface represents the directory to which the CodeGenerator is
-// to write.
-class LIBPROTOC_EXPORT OutputDirectory {
+// to write and other information about the context in which the Generator
+// runs.
+class LIBPROTOC_EXPORT GeneratorContext {
public:
- inline OutputDirectory() {}
- virtual ~OutputDirectory();
+ inline GeneratorContext() {}
+ virtual ~GeneratorContext();
// Opens the given file, truncating it if it exists, and returns a
// ZeroCopyOutputStream that writes to the file. The caller takes ownership
@@ -103,6 +104,9 @@ class LIBPROTOC_EXPORT OutputDirectory {
// contain "." or ".." components.
virtual io::ZeroCopyOutputStream* Open(const string& filename) = 0;
+ // Similar to Open() but the output will be appended to the file if exists
+ virtual io::ZeroCopyOutputStream* OpenForAppend(const string& filename);
+
// Creates a ZeroCopyOutputStream which will insert code into the given file
// at the given insertion point. See plugin.proto (plugin.pb.h) for more
// information on insertion points. The default implementation
@@ -112,10 +116,19 @@ class LIBPROTOC_EXPORT OutputDirectory {
virtual io::ZeroCopyOutputStream* OpenForInsert(
const string& filename, const string& insertion_point);
+ // Returns a vector of FileDescriptors for all the files being compiled
+ // in this run. Useful for languages, such as Go, that treat files
+ // differently when compiled as a set rather than individually.
+ virtual void ListParsedFiles(vector<const FileDescriptor*>* output);
+
private:
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OutputDirectory);
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext);
};
+// The type GeneratorContext was once called OutputDirectory. This typedef
+// provides backward compatibility.
+typedef GeneratorContext OutputDirectory;
+
// Several code generators treat the parameter argument as holding a
// list of options separated by commas. This helper function parses
// a set of comma-delimited name/value pairs: e.g.,
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index d3495ca..f9f27bd 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -48,6 +48,11 @@
#include <iostream>
#include <ctype.h>
+#include <google/protobuf/stubs/hash.h>
+#include <memory>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.pb.h>
@@ -56,14 +61,13 @@
#include <google/protobuf/descriptor.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/printer.h>
-#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
-#include <google/protobuf/stubs/map-util.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
-#include <google/protobuf/stubs/hash.h>
+#include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
@@ -144,7 +148,7 @@ void AddTrailingSlash(string* path) {
bool VerifyDirectoryExists(const string& path) {
if (path.empty()) return true;
- if (access(path.c_str(), W_OK) == -1) {
+ if (access(path.c_str(), F_OK) == -1) {
cerr << path << ": " << strerror(errno) << endl;
return false;
} else {
@@ -158,8 +162,7 @@ bool VerifyDirectoryExists(const string& path) {
// directories listed in |filename|.
bool TryCreateParentDirectory(const string& prefix, const string& filename) {
// Recursively create parent directories to the output file.
- vector<string> parts;
- SplitStringUsing(filename, "/", &parts);
+ vector<string> parts = Split(filename, "/", true);
string path_so_far = prefix;
for (int i = 0; i < parts.size() - 1; i++) {
path_so_far += parts[i];
@@ -182,14 +185,23 @@ bool TryCreateParentDirectory(const string& prefix, const string& filename) {
class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
public io::ErrorCollector {
public:
- ErrorPrinter(ErrorFormat format) : format_(format) {}
+ ErrorPrinter(ErrorFormat format, DiskSourceTree *tree = NULL)
+ : format_(format), tree_(tree) {}
~ErrorPrinter() {}
// implements MultiFileErrorCollector ------------------------------
void AddError(const string& filename, int line, int column,
const string& message) {
- cerr << filename;
+ // Print full path when running under MSVS
+ string dfile;
+ if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS &&
+ tree_ != NULL &&
+ tree_->VirtualFileToDiskFile(filename, &dfile)) {
+ cerr << dfile;
+ } else {
+ cerr << filename;
+ }
// Users typically expect 1-based line/column numbers, so we add 1
// to each here.
@@ -215,16 +227,17 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
private:
const ErrorFormat format_;
+ DiskSourceTree *tree_;
};
// -------------------------------------------------------------------
-// An OutputDirectory implementation that buffers files in memory, then dumps
+// A GeneratorContext implementation that buffers files in memory, then dumps
// them all to disk on demand.
-class CommandLineInterface::MemoryOutputDirectory : public OutputDirectory {
+class CommandLineInterface::GeneratorContextImpl : public GeneratorContext {
public:
- MemoryOutputDirectory();
- ~MemoryOutputDirectory();
+ GeneratorContextImpl(const vector<const FileDescriptor*>& parsed_files);
+ ~GeneratorContextImpl();
// Write all files in the directory to disk at the given output location,
// which must end in a '/'.
@@ -238,10 +251,14 @@ class CommandLineInterface::MemoryOutputDirectory : public OutputDirectory {
// format, unless one has already been written.
void AddJarManifest();
- // implements OutputDirectory --------------------------------------
+ // implements GeneratorContext --------------------------------------
io::ZeroCopyOutputStream* Open(const string& filename);
+ io::ZeroCopyOutputStream* OpenForAppend(const string& filename);
io::ZeroCopyOutputStream* OpenForInsert(
const string& filename, const string& insertion_point);
+ void ListParsedFiles(vector<const FileDescriptor*>* output) {
+ *output = parsed_files_;
+ }
private:
friend class MemoryOutputStream;
@@ -249,14 +266,16 @@ class CommandLineInterface::MemoryOutputDirectory : public OutputDirectory {
// map instead of hash_map so that files are written in order (good when
// writing zips).
map<string, string*> files_;
+ const vector<const FileDescriptor*>& parsed_files_;
bool had_error_;
};
class CommandLineInterface::MemoryOutputStream
: public io::ZeroCopyOutputStream {
public:
- MemoryOutputStream(MemoryOutputDirectory* directory, const string& filename);
- MemoryOutputStream(MemoryOutputDirectory* directory, const string& filename,
+ MemoryOutputStream(GeneratorContextImpl* directory, const string& filename,
+ bool append_mode);
+ MemoryOutputStream(GeneratorContextImpl* directory, const string& filename,
const string& insertion_point);
virtual ~MemoryOutputStream();
@@ -267,27 +286,33 @@ class CommandLineInterface::MemoryOutputStream
private:
// Where to insert the string when it's done.
- MemoryOutputDirectory* directory_;
+ GeneratorContextImpl* directory_;
string filename_;
string insertion_point_;
// The string we're building.
string data_;
+ // Whether we should append the output stream to the existing file.
+ bool append_mode_;
+
// StringOutputStream writing to data_.
scoped_ptr<io::StringOutputStream> inner_;
};
// -------------------------------------------------------------------
-CommandLineInterface::MemoryOutputDirectory::MemoryOutputDirectory()
- : had_error_(false) {}
+CommandLineInterface::GeneratorContextImpl::GeneratorContextImpl(
+ const vector<const FileDescriptor*>& parsed_files)
+ : parsed_files_(parsed_files),
+ had_error_(false) {
+}
-CommandLineInterface::MemoryOutputDirectory::~MemoryOutputDirectory() {
+CommandLineInterface::GeneratorContextImpl::~GeneratorContextImpl() {
STLDeleteValues(&files_);
}
-bool CommandLineInterface::MemoryOutputDirectory::WriteAllToDisk(
+bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk(
const string& prefix) {
if (had_error_) {
return false;
@@ -362,7 +387,7 @@ bool CommandLineInterface::MemoryOutputDirectory::WriteAllToDisk(
return true;
}
-bool CommandLineInterface::MemoryOutputDirectory::WriteAllToZip(
+bool CommandLineInterface::GeneratorContextImpl::WriteAllToZip(
const string& filename) {
if (had_error_) {
return false;
@@ -403,7 +428,7 @@ bool CommandLineInterface::MemoryOutputDirectory::WriteAllToZip(
return true;
}
-void CommandLineInterface::MemoryOutputDirectory::AddJarManifest() {
+void CommandLineInterface::GeneratorContextImpl::AddJarManifest() {
string** map_slot = &files_["META-INF/MANIFEST.MF"];
if (*map_slot == NULL) {
*map_slot = new string(
@@ -413,13 +438,19 @@ void CommandLineInterface::MemoryOutputDirectory::AddJarManifest() {
}
}
-io::ZeroCopyOutputStream* CommandLineInterface::MemoryOutputDirectory::Open(
+io::ZeroCopyOutputStream* CommandLineInterface::GeneratorContextImpl::Open(
const string& filename) {
- return new MemoryOutputStream(this, filename);
+ return new MemoryOutputStream(this, filename, false);
}
io::ZeroCopyOutputStream*
-CommandLineInterface::MemoryOutputDirectory::OpenForInsert(
+CommandLineInterface::GeneratorContextImpl::OpenForAppend(
+ const string& filename) {
+ return new MemoryOutputStream(this, filename, true);
+}
+
+io::ZeroCopyOutputStream*
+CommandLineInterface::GeneratorContextImpl::OpenForInsert(
const string& filename, const string& insertion_point) {
return new MemoryOutputStream(this, filename, insertion_point);
}
@@ -427,14 +458,15 @@ CommandLineInterface::MemoryOutputDirectory::OpenForInsert(
// -------------------------------------------------------------------
CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
- MemoryOutputDirectory* directory, const string& filename)
+ GeneratorContextImpl* directory, const string& filename, bool append_mode)
: directory_(directory),
filename_(filename),
+ append_mode_(append_mode),
inner_(new io::StringOutputStream(&data_)) {
}
CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
- MemoryOutputDirectory* directory, const string& filename,
+ GeneratorContextImpl* directory, const string& filename,
const string& insertion_point)
: directory_(directory),
filename_(filename),
@@ -452,8 +484,12 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() {
if (insertion_point_.empty()) {
// This was just a regular Open().
if (*map_slot != NULL) {
- cerr << filename_ << ": Tried to write the same file twice." << endl;
- directory_->had_error_ = true;
+ if (append_mode_) {
+ (*map_slot)->append(data_);
+ } else {
+ cerr << filename_ << ": Tried to write the same file twice." << endl;
+ directory_->had_error_ = true;
+ }
return;
}
@@ -546,8 +582,10 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() {
CommandLineInterface::CommandLineInterface()
: mode_(MODE_COMPILE),
+ print_mode_(PRINT_NONE),
error_format_(ERROR_FORMAT_GCC),
imports_in_descriptor_set_(false),
+ source_info_in_descriptor_set_(false),
disallow_services_(false),
inputs_are_proto_path_relative_(false) {}
CommandLineInterface::~CommandLineInterface() {}
@@ -556,9 +594,23 @@ void CommandLineInterface::RegisterGenerator(const string& flag_name,
CodeGenerator* generator,
const string& help_text) {
GeneratorInfo info;
+ info.flag_name = flag_name;
+ info.generator = generator;
+ info.help_text = help_text;
+ generators_by_flag_name_[flag_name] = info;
+}
+
+void CommandLineInterface::RegisterGenerator(const string& flag_name,
+ const string& option_flag_name,
+ CodeGenerator* generator,
+ const string& help_text) {
+ GeneratorInfo info;
+ info.flag_name = flag_name;
+ info.option_flag_name = option_flag_name;
info.generator = generator;
info.help_text = help_text;
- generators_[flag_name] = info;
+ generators_by_flag_name_[flag_name] = info;
+ generators_by_option_name_[option_flag_name] = info;
}
void CommandLineInterface::AllowPlugins(const string& exe_name_prefix) {
@@ -567,7 +619,14 @@ void CommandLineInterface::AllowPlugins(const string& exe_name_prefix) {
int CommandLineInterface::Run(int argc, const char* const argv[]) {
Clear();
- if (!ParseArguments(argc, argv)) return 1;
+ switch (ParseArguments(argc, argv)) {
+ case PARSE_ARGUMENT_DONE_AND_EXIT:
+ return 0;
+ case PARSE_ARGUMENT_FAIL:
+ return 1;
+ case PARSE_ARGUMENT_DONE_AND_CONTINUE:
+ break;
+ }
// Set up the source tree.
DiskSourceTree source_tree;
@@ -583,7 +642,7 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
}
// Allocate the Importer.
- ErrorPrinter error_collector(error_format_);
+ ErrorPrinter error_collector(error_format_, &source_tree);
Importer importer(&source_tree, &error_collector);
vector<const FileDescriptor*> parsed_files;
@@ -591,7 +650,9 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
// Parse each file.
for (int i = 0; i < input_files_.size(); i++) {
// Import the file.
+ importer.AddUnusedImportTrackFile(input_files_[i]);
const FileDescriptor* parsed_file = importer.Import(input_files_[i]);
+ importer.ClearUnusedImportTrackFiles();
if (parsed_file == NULL) return 1;
parsed_files.push_back(parsed_file);
@@ -603,11 +664,11 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
}
}
- // We construct a separate OutputDirectory for each output location. Note
+ // We construct a separate GeneratorContext for each output location. Note
// that two code generators may output to the same location, in which case
- // they should share a single OutputDirectory (so that OpenForInsert() works).
- typedef hash_map<string, MemoryOutputDirectory*> OutputDirectoryMap;
- OutputDirectoryMap output_directories;
+ // they should share a single GeneratorContext so that OpenForInsert() works.
+ typedef hash_map<string, GeneratorContextImpl*> GeneratorContextMap;
+ GeneratorContextMap output_directories;
// Generate output.
if (mode_ == MODE_COMPILE) {
@@ -617,11 +678,11 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
!HasSuffixString(output_location, ".jar")) {
AddTrailingSlash(&output_location);
}
- MemoryOutputDirectory** map_slot = &output_directories[output_location];
+ GeneratorContextImpl** map_slot = &output_directories[output_location];
if (*map_slot == NULL) {
// First time we've seen this output location.
- *map_slot = new MemoryOutputDirectory;
+ *map_slot = new GeneratorContextImpl(parsed_files);
}
if (!GenerateOutput(parsed_files, output_directives_[i], *map_slot)) {
@@ -632,10 +693,10 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
}
// Write all output to disk.
- for (OutputDirectoryMap::iterator iter = output_directories.begin();
+ for (GeneratorContextMap::iterator iter = output_directories.begin();
iter != output_directories.end(); ++iter) {
const string& location = iter->first;
- MemoryOutputDirectory* directory = iter->second;
+ GeneratorContextImpl* directory = iter->second;
if (HasSuffixString(location, "/")) {
if (!directory->WriteAllToDisk(location)) {
STLDeleteValues(&output_directories);
@@ -680,6 +741,25 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
}
}
+ if (mode_ == MODE_PRINT) {
+ switch (print_mode_) {
+ case PRINT_FREE_FIELDS:
+ for (int i = 0; i < parsed_files.size(); ++i) {
+ const FileDescriptor* fd = parsed_files[i];
+ for (int j = 0; j < fd->message_type_count(); ++j) {
+ PrintFreeFieldNumbers(fd->message_type(j));
+ }
+ }
+ break;
+ case PRINT_NONE:
+ GOOGLE_LOG(ERROR) << "If the code reaches here, it usually means a bug of "
+ "flag parsing in the CommonadLineInterface.";
+ return 1;
+
+ // Do not add a default case.
+ }
+ }
+
return 0;
}
@@ -694,7 +774,9 @@ void CommandLineInterface::Clear() {
descriptor_set_name_.clear();
mode_ = MODE_COMPILE;
+ print_mode_ = PRINT_NONE;
imports_in_descriptor_set_ = false;
+ source_info_in_descriptor_set_ = false;
disallow_services_ = false;
}
@@ -737,7 +819,8 @@ bool CommandLineInterface::MakeInputsBeProtoPathRelative(
return true;
}
-bool CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
+CommandLineInterface::ParseArgumentStatus
+CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
executable_name_ = argv[0];
// Iterate through all arguments and parse them.
@@ -751,41 +834,50 @@ bool CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
if (name == "--decode") {
cerr << "To decode an unknown message, use --decode_raw." << endl;
}
- return false;
+ return PARSE_ARGUMENT_FAIL;
} else {
++i;
value = argv[i];
}
}
- if (!InterpretArgument(name, value)) return false;
+ ParseArgumentStatus status = InterpretArgument(name, value);
+ if (status != PARSE_ARGUMENT_DONE_AND_CONTINUE)
+ return status;
}
// If no --proto_path was given, use the current working directory.
if (proto_path_.empty()) {
- proto_path_.push_back(make_pair("", "."));
+ // Don't use make_pair as the old/default standard library on Solaris
+ // doesn't support it without explicit template parameters, which are
+ // incompatible with C++0x's make_pair.
+ proto_path_.push_back(pair<string, string>("", "."));
}
// Check some errror cases.
bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty();
if (decoding_raw && !input_files_.empty()) {
cerr << "When using --decode_raw, no input files should be given." << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
} else if (!decoding_raw && input_files_.empty()) {
cerr << "Missing input file." << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
}
if (mode_ == MODE_COMPILE && output_directives_.empty() &&
descriptor_set_name_.empty()) {
cerr << "Missing output directives." << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
}
if (imports_in_descriptor_set_ && descriptor_set_name_.empty()) {
cerr << "--include_imports only makes sense when combined with "
"--descriptor_set_out." << endl;
}
+ if (source_info_in_descriptor_set_ && descriptor_set_name_.empty()) {
+ cerr << "--include_source_info only makes sense when combined with "
+ "--descriptor_set_out." << endl;
+ }
- return true;
+ return PARSE_ARGUMENT_DONE_AND_CONTINUE;
}
bool CommandLineInterface::ParseArgument(const char* arg,
@@ -835,8 +927,10 @@ bool CommandLineInterface::ParseArgument(const char* arg,
if (*name == "-h" || *name == "--help" ||
*name == "--disallow_services" ||
*name == "--include_imports" ||
+ *name == "--include_source_info" ||
*name == "--version" ||
- *name == "--decode_raw") {
+ *name == "--decode_raw" ||
+ *name == "--print_free_field_numbers") {
// HACK: These are the only flags that don't take a value.
// They probably should not be hard-coded like this but for now it's
// not worth doing better.
@@ -847,8 +941,9 @@ bool CommandLineInterface::ParseArgument(const char* arg,
return true;
}
-bool CommandLineInterface::InterpretArgument(const string& name,
- const string& value) {
+CommandLineInterface::ParseArgumentStatus
+CommandLineInterface::InterpretArgument(const string& name,
+ const string& value) {
if (name.empty()) {
// Not a flag. Just a filename.
if (value.empty()) {
@@ -856,7 +951,7 @@ bool CommandLineInterface::InterpretArgument(const string& name,
"arguments to " << executable_name_ << ". This is actually "
"sort of hard to do. Congrats. Unfortunately it is not valid "
"input so the program is going to die now." << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
}
input_files_.push_back(value);
@@ -865,14 +960,14 @@ bool CommandLineInterface::InterpretArgument(const string& name,
// Java's -classpath (and some other languages) delimits path components
// with colons. Let's accept that syntax too just to make things more
// intuitive.
- vector<string> parts;
- SplitStringUsing(value, kPathSeparator, &parts);
+ vector<string> parts = Split(
+ value, kPathSeparator, true);
for (int i = 0; i < parts.size(); i++) {
string virtual_path;
string disk_path;
- int equals_pos = parts[i].find_first_of('=');
+ string::size_type equals_pos = parts[i].find_first_of('=');
if (equals_pos == string::npos) {
virtual_path = "";
disk_path = parts[i];
@@ -884,7 +979,7 @@ bool CommandLineInterface::InterpretArgument(const string& name,
if (disk_path.empty()) {
cerr << "--proto_path passed empty directory name. (Use \".\" for "
"current directory.)" << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
}
// Make sure disk path exists, warn otherwise.
@@ -892,35 +987,45 @@ bool CommandLineInterface::InterpretArgument(const string& name,
cerr << disk_path << ": warning: directory does not exist." << endl;
}
- proto_path_.push_back(make_pair(virtual_path, disk_path));
+ // Don't use make_pair as the old/default standard library on Solaris
+ // doesn't support it without explicit template parameters, which are
+ // incompatible with C++0x's make_pair.
+ proto_path_.push_back(pair<string, string>(virtual_path, disk_path));
}
} else if (name == "-o" || name == "--descriptor_set_out") {
if (!descriptor_set_name_.empty()) {
cerr << name << " may only be passed once." << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
}
if (value.empty()) {
cerr << name << " requires a non-empty value." << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
}
if (mode_ != MODE_COMPILE) {
cerr << "Cannot use --encode or --decode and generate descriptors at the "
"same time." << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
}
descriptor_set_name_ = value;
} else if (name == "--include_imports") {
if (imports_in_descriptor_set_) {
cerr << name << " may only be passed once." << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
}
imports_in_descriptor_set_ = true;
+ } else if (name == "--include_source_info") {
+ if (source_info_in_descriptor_set_) {
+ cerr << name << " may only be passed once." << endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ source_info_in_descriptor_set_ = true;
+
} else if (name == "-h" || name == "--help") {
PrintHelpText();
- return false; // Exit without running compiler.
+ return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler.
} else if (name == "--version") {
if (!version_info_.empty()) {
@@ -929,7 +1034,7 @@ bool CommandLineInterface::InterpretArgument(const string& name,
cout << "libprotoc "
<< protobuf::internal::VersionString(GOOGLE_PROTOBUF_VERSION)
<< endl;
- return false; // Exit without running compiler.
+ return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler.
} else if (name == "--disallow_services") {
disallow_services_ = true;
@@ -938,12 +1043,12 @@ bool CommandLineInterface::InterpretArgument(const string& name,
name == "--decode_raw") {
if (mode_ != MODE_COMPILE) {
cerr << "Only one of --encode and --decode can be specified." << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
}
if (!output_directives_.empty() || !descriptor_set_name_.empty()) {
cerr << "Cannot use " << name
<< " and generate code or descriptors at the same time." << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
}
mode_ = (name == "--encode") ? MODE_ENCODE : MODE_DECODE;
@@ -953,10 +1058,10 @@ bool CommandLineInterface::InterpretArgument(const string& name,
if (name == "--decode") {
cerr << "To decode an unknown message, use --decode_raw." << endl;
}
- return false;
+ return PARSE_ARGUMENT_FAIL;
} else if (!value.empty() && name == "--decode_raw") {
cerr << "--decode_raw does not take a parameter." << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
}
codec_type_ = value;
@@ -968,16 +1073,16 @@ bool CommandLineInterface::InterpretArgument(const string& name,
error_format_ = ERROR_FORMAT_MSVS;
} else {
cerr << "Unknown error format: " << value << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
}
} else if (name == "--plugin") {
if (plugin_prefix_.empty()) {
cerr << "This compiler does not support plugins." << endl;
- return false;
+ return PARSE_ARGUMENT_FAIL;
}
- string name;
+ string plugin_name;
string path;
string::size_type equals_pos = value.find_first_of('=');
@@ -985,57 +1090,81 @@ bool CommandLineInterface::InterpretArgument(const string& name,
// Use the basename of the file.
string::size_type slash_pos = value.find_last_of('/');
if (slash_pos == string::npos) {
- name = value;
+ plugin_name = value;
} else {
- name = value.substr(slash_pos + 1);
+ plugin_name = value.substr(slash_pos + 1);
}
path = value;
} else {
- name = value.substr(0, equals_pos);
+ plugin_name = value.substr(0, equals_pos);
path = value.substr(equals_pos + 1);
}
- plugins_[name] = path;
+ plugins_[plugin_name] = path;
+ } else if (name == "--print_free_field_numbers") {
+ if (mode_ != MODE_COMPILE) {
+ cerr << "Cannot use " << name << " and use --encode, --decode or print "
+ << "other info at the same time." << endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (!output_directives_.empty() || !descriptor_set_name_.empty()) {
+ cerr << "Cannot use " << name
+ << " and generate code or descriptors at the same time." << endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ mode_ = MODE_PRINT;
+ print_mode_ = PRINT_FREE_FIELDS;
} else {
// Some other flag. Look it up in the generators list.
- const GeneratorInfo* generator_info = FindOrNull(generators_, name);
+ const GeneratorInfo* generator_info =
+ FindOrNull(generators_by_flag_name_, name);
if (generator_info == NULL &&
(plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) {
- cerr << "Unknown flag: " << name << endl;
- return false;
- }
+ // Check if it's a generator option flag.
+ generator_info = FindOrNull(generators_by_option_name_, name);
+ if (generator_info == NULL) {
+ cerr << "Unknown flag: " << name << endl;
+ return PARSE_ARGUMENT_FAIL;
+ } else {
+ string* parameters = &generator_parameters_[generator_info->flag_name];
+ if (!parameters->empty()) {
+ parameters->append(",");
+ }
+ parameters->append(value);
+ }
+ } else {
+ // It's an output flag. Add it to the output directives.
+ if (mode_ != MODE_COMPILE) {
+ cerr << "Cannot use --encode, --decode or print .proto info and "
+ "generate code at the same time." << endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
- // It's an output flag. Add it to the output directives.
- if (mode_ != MODE_COMPILE) {
- cerr << "Cannot use --encode or --decode and generate code at the "
- "same time." << endl;
- return false;
- }
+ OutputDirective directive;
+ directive.name = name;
+ if (generator_info == NULL) {
+ directive.generator = NULL;
+ } else {
+ directive.generator = generator_info->generator;
+ }
- OutputDirective directive;
- directive.name = name;
- if (generator_info == NULL) {
- directive.generator = NULL;
- } else {
- directive.generator = generator_info->generator;
- }
+ // Split value at ':' to separate the generator parameter from the
+ // filename. However, avoid doing this if the colon is part of a valid
+ // Windows-style absolute path.
+ string::size_type colon_pos = value.find_first_of(':');
+ if (colon_pos == string::npos || IsWindowsAbsolutePath(value)) {
+ directive.output_location = value;
+ } else {
+ directive.parameter = value.substr(0, colon_pos);
+ directive.output_location = value.substr(colon_pos + 1);
+ }
- // Split value at ':' to separate the generator parameter from the
- // filename. However, avoid doing this if the colon is part of a valid
- // Windows-style absolute path.
- string::size_type colon_pos = value.find_first_of(':');
- if (colon_pos == string::npos || IsWindowsAbsolutePath(value)) {
- directive.output_location = value;
- } else {
- directive.parameter = value.substr(0, colon_pos);
- directive.output_location = value.substr(colon_pos + 1);
+ output_directives_.push_back(directive);
}
-
- output_directives_.push_back(directive);
}
- return true;
+ return PARSE_ARGUMENT_DONE_AND_CONTINUE;
}
void CommandLineInterface::PrintHelpText() {
@@ -1068,9 +1197,20 @@ void CommandLineInterface::PrintHelpText() {
" --include_imports When using --descriptor_set_out, also include\n"
" all dependencies of the input files in the\n"
" set, so that the set is self-contained.\n"
+" --include_source_info When using --descriptor_set_out, do not strip\n"
+" SourceCodeInfo from the FileDescriptorProto.\n"
+" This results in vastly larger descriptors that\n"
+" include information about the original\n"
+" location of each decl in the source file as\n"
+" well as surrounding comments.\n"
" --error_format=FORMAT Set the format in which to print errors.\n"
" FORMAT may be 'gcc' (the default) or 'msvs'\n"
-" (Microsoft Visual Studio format)." << endl;
+" (Microsoft Visual Studio format).\n"
+" --print_free_field_numbers Print the free field numbers of the messages\n"
+" 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." << endl;
if (!plugin_prefix_.empty()) {
cerr <<
" --plugin=EXECUTABLE Specifies a plugin executable to use.\n"
@@ -1083,8 +1223,8 @@ void CommandLineInterface::PrintHelpText() {
" the executable's own name differs." << endl;
}
- for (GeneratorMap::iterator iter = generators_.begin();
- iter != generators_.end(); ++iter) {
+ for (GeneratorMap::iterator iter = generators_by_flag_name_.begin();
+ iter != generators_by_flag_name_.end(); ++iter) {
// FIXME(kenton): If the text is long enough it will wrap, which is ugly,
// but fixing this nicely (e.g. splitting on spaces) is probably more
// trouble than it's worth.
@@ -1097,7 +1237,7 @@ void CommandLineInterface::PrintHelpText() {
bool CommandLineInterface::GenerateOutput(
const vector<const FileDescriptor*>& parsed_files,
const OutputDirective& output_directive,
- OutputDirectory* output_directory) {
+ GeneratorContext* generator_context) {
// Call the generator.
string error;
if (output_directive.generator == NULL) {
@@ -1112,16 +1252,22 @@ bool CommandLineInterface::GenerateOutput(
if (!GeneratePluginOutput(parsed_files, plugin_name,
output_directive.parameter,
- output_directory, &error)) {
+ generator_context, &error)) {
cerr << output_directive.name << ": " << error << endl;
return false;
}
} else {
// Regular generator.
+ string parameters = output_directive.parameter;
+ if (!generator_parameters_[output_directive.name].empty()) {
+ if (!parameters.empty()) {
+ parameters.append(",");
+ }
+ parameters.append(generator_parameters_[output_directive.name]);
+ }
for (int i = 0; i < parsed_files.size(); i++) {
- if (!output_directive.generator->Generate(
- parsed_files[i], output_directive.parameter,
- output_directory, &error)) {
+ if (!output_directive.generator->Generate(parsed_files[i], parameters,
+ generator_context, &error)) {
// Generator returned an error.
cerr << output_directive.name << ": " << parsed_files[i]->name() << ": "
<< error << endl;
@@ -1137,7 +1283,7 @@ bool CommandLineInterface::GeneratePluginOutput(
const vector<const FileDescriptor*>& parsed_files,
const string& plugin_name,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
string* error) {
CodeGeneratorRequest request;
CodeGeneratorResponse response;
@@ -1150,8 +1296,9 @@ bool CommandLineInterface::GeneratePluginOutput(
set<const FileDescriptor*> already_seen;
for (int i = 0; i < parsed_files.size(); i++) {
request.add_file_to_generate(parsed_files[i]->name());
- GetTransitiveDependencies(parsed_files[i], &already_seen,
- request.mutable_proto_file());
+ GetTransitiveDependencies(parsed_files[i],
+ true, // Include source code info.
+ &already_seen, request.mutable_proto_file());
}
// Invoke the plugin.
@@ -1180,14 +1327,14 @@ bool CommandLineInterface::GeneratePluginOutput(
// We reset current_output to NULL first so that the old file is closed
// before the new one is opened.
current_output.reset();
- current_output.reset(output_directory->OpenForInsert(
+ current_output.reset(generator_context->OpenForInsert(
output_file.name(), output_file.insertion_point()));
} else if (!output_file.name().empty()) {
// Starting a new file. Open it.
// We reset current_output to NULL first so that the old file is closed
// before the new one is opened.
current_output.reset();
- current_output.reset(output_directory->Open(output_file.name()));
+ current_output.reset(generator_context->Open(output_file.name()));
} else if (current_output == NULL) {
*error = strings::Substitute(
"$0: First file chunk returned by plugin did not specify a file name.",
@@ -1281,12 +1428,17 @@ bool CommandLineInterface::WriteDescriptorSet(
if (imports_in_descriptor_set_) {
set<const FileDescriptor*> already_seen;
for (int i = 0; i < parsed_files.size(); i++) {
- GetTransitiveDependencies(
- parsed_files[i], &already_seen, file_set.mutable_file());
+ GetTransitiveDependencies(parsed_files[i],
+ source_info_in_descriptor_set_,
+ &already_seen, file_set.mutable_file());
}
} else {
for (int i = 0; i < parsed_files.size(); i++) {
- parsed_files[i]->CopyTo(file_set.add_file());
+ FileDescriptorProto* file_proto = file_set.add_file();
+ parsed_files[i]->CopyTo(file_proto);
+ if (source_info_in_descriptor_set_) {
+ parsed_files[i]->CopySourceCodeInfoTo(file_proto);
+ }
}
}
@@ -1316,7 +1468,7 @@ bool CommandLineInterface::WriteDescriptorSet(
}
void CommandLineInterface::GetTransitiveDependencies(
- const FileDescriptor* file,
+ const FileDescriptor* file, bool include_source_code_info,
set<const FileDescriptor*>* already_seen,
RepeatedPtrField<FileDescriptorProto>* output) {
if (!already_seen->insert(file).second) {
@@ -1326,13 +1478,125 @@ void CommandLineInterface::GetTransitiveDependencies(
// Add all dependencies.
for (int i = 0; i < file->dependency_count(); i++) {
- GetTransitiveDependencies(file->dependency(i), already_seen, output);
+ GetTransitiveDependencies(file->dependency(i), include_source_code_info,
+ already_seen, output);
}
// Add this file.
- file->CopyTo(output->Add());
+ FileDescriptorProto* new_descriptor = output->Add();
+ file->CopyTo(new_descriptor);
+ if (include_source_code_info) {
+ file->CopySourceCodeInfoTo(new_descriptor);
+ }
+}
+
+namespace {
+
+// Utility function for PrintFreeFieldNumbers.
+// Stores occupied ranges into the ranges parameter, and next level of sub
+// message types into the nested_messages parameter. The FieldRange is left
+// inclusive, right exclusive. i.e. [a, b).
+//
+// Nested Messages:
+// Note that it only stores the nested message type, iff the nested type is
+// either a direct child of the given descriptor, or the nested type is a
+// decendent of the given descriptor and all the nodes between the
+// nested type and the given descriptor are group types. e.g.
+//
+// message Foo {
+// message Bar {
+// message NestedBar {}
+// }
+// group Baz = 1 {
+// group NestedBazGroup = 2 {
+// message Quz {
+// message NestedQuz {}
+// }
+// }
+// message NestedBaz {}
+// }
+// }
+//
+// In this case, Bar, Quz and NestedBaz will be added into the nested types.
+// Since free field numbers of group types will not be printed, this makes sure
+// the nested message types in groups will not be dropped. The nested_messages
+// parameter will contain the direct children (when groups are ignored in the
+// tree) of the given descriptor for the caller to traverse. The declaration
+// order of the nested messages is also preserved.
+typedef pair<int, int> FieldRange;
+void GatherOccupiedFieldRanges(const Descriptor* descriptor,
+ set<FieldRange>* ranges,
+ vector<const Descriptor*>* nested_messages) {
+ set<const Descriptor*> groups;
+ for (int i = 0; i < descriptor->field_count(); ++i) {
+ const FieldDescriptor* fd = descriptor->field(i);
+ ranges->insert(FieldRange(fd->number(), fd->number() + 1));
+ if (fd->type() == FieldDescriptor::TYPE_GROUP) {
+ groups.insert(fd->message_type());
+ }
+ }
+ for (int i = 0; i < descriptor->extension_range_count(); ++i) {
+ ranges->insert(FieldRange(descriptor->extension_range(i)->start,
+ descriptor->extension_range(i)->end));
+ }
+ // Handle the nested messages/groups in declaration order to make it
+ // post-order strict.
+ for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+ const Descriptor* nested_desc = descriptor->nested_type(i);
+ if (groups.find(nested_desc) != groups.end()) {
+ GatherOccupiedFieldRanges(nested_desc, ranges, nested_messages);
+ } else {
+ nested_messages->push_back(nested_desc);
+ }
+ }
}
+// Utility function for PrintFreeFieldNumbers.
+// Actually prints the formatted free field numbers for given message name and
+// occupied ranges.
+void FormatFreeFieldNumbers(const string& name,
+ const set<FieldRange>& ranges) {
+ string output;
+ StringAppendF(&output, "%-35s free:", name.c_str());
+ int next_free_number = 1;
+ for (set<FieldRange>::const_iterator i = ranges.begin();
+ i != ranges.end(); ++i) {
+ // This happens when groups re-use parent field numbers, in which
+ // case we skip the FieldRange entirely.
+ if (next_free_number >= i->second) continue;
+
+ if (next_free_number < i->first) {
+ if (next_free_number + 1 == i->first) {
+ // Singleton
+ StringAppendF(&output, " %d", next_free_number);
+ } else {
+ // Range
+ StringAppendF(&output, " %d-%d", next_free_number, i->first - 1);
+ }
+ }
+ next_free_number = i->second;
+ }
+ if (next_free_number <= FieldDescriptor::kMaxNumber) {
+ StringAppendF(&output, " %d-INF", next_free_number);
+ }
+ cout << output << endl;
+}
+
+} // namespace
+
+void CommandLineInterface::PrintFreeFieldNumbers(
+ const Descriptor* descriptor) {
+ set<FieldRange> ranges;
+ vector<const Descriptor*> nested_messages;
+ GatherOccupiedFieldRanges(descriptor, &ranges, &nested_messages);
+
+ for (int i = 0; i < nested_messages.size(); ++i) {
+ PrintFreeFieldNumbers(nested_messages[i]);
+ }
+ FormatFreeFieldNumbers(descriptor->full_name(), ranges);
+}
+
+
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h
index d25a50e..47f2891 100644
--- a/src/google/protobuf/compiler/command_line_interface.h
+++ b/src/google/protobuf/compiler/command_line_interface.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -48,15 +48,16 @@
namespace google {
namespace protobuf {
-class FileDescriptor; // descriptor.h
+class Descriptor; // descriptor.h
class DescriptorPool; // descriptor.h
+class FileDescriptor; // descriptor.h
class FileDescriptorProto; // descriptor.pb.h
template<typename T> class RepeatedPtrField; // repeated_field.h
namespace compiler {
class CodeGenerator; // code_generator.h
-class OutputDirectory; // code_generator.h
+class GeneratorContext; // code_generator.h
class DiskSourceTree; // importer.h
// This class implements the command-line interface to the protocol compiler.
@@ -112,6 +113,19 @@ class LIBPROTOC_EXPORT CommandLineInterface {
CodeGenerator* generator,
const string& help_text);
+ // Register a code generator for a language.
+ // Besides flag_name you can specify another option_flag_name that could be
+ // used to pass extra parameters to the registered code generator.
+ // Suppose you have registered a generator by calling:
+ // command_line_interface.RegisterGenerator("--foo_out", "--foo_opt", ...)
+ // Then you could invoke the compiler with a command like:
+ // protoc --foo_out=enable_bar:outdir --foo_opt=enable_baz
+ // This will pass "enable_bar,enable_baz" as the parameter to the generator.
+ void RegisterGenerator(const string& flag_name,
+ const string& option_flag_name,
+ CodeGenerator* generator,
+ const string& help_text);
+
// Enables "plugins". In this mode, if a command-line flag ends with "_out"
// but does not match any registered generator, the compiler will attempt to
// find a "plugin" to implement the generator. Plugins are just executables.
@@ -174,7 +188,7 @@ class LIBPROTOC_EXPORT CommandLineInterface {
// -----------------------------------------------------------------
class ErrorPrinter;
- class MemoryOutputDirectory;
+ class GeneratorContextImpl;
class MemoryOutputStream;
// Clear state from previous Run().
@@ -186,8 +200,15 @@ class LIBPROTOC_EXPORT CommandLineInterface {
bool MakeInputsBeProtoPathRelative(
DiskSourceTree* source_tree);
+ // Return status for ParseArguments() and InterpretArgument().
+ enum ParseArgumentStatus {
+ PARSE_ARGUMENT_DONE_AND_CONTINUE,
+ PARSE_ARGUMENT_DONE_AND_EXIT,
+ PARSE_ARGUMENT_FAIL
+ };
+
// Parse all command-line arguments.
- bool ParseArguments(int argc, const char* const argv[]);
+ 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,
@@ -203,7 +224,8 @@ class LIBPROTOC_EXPORT CommandLineInterface {
bool ParseArgument(const char* arg, string* name, string* value);
// Interprets arguments parsed with ParseArgument.
- bool InterpretArgument(const string& name, const string& value);
+ ParseArgumentStatus InterpretArgument(const string& name,
+ const string& value);
// Print the --help text to stderr.
void PrintHelpText();
@@ -212,11 +234,11 @@ class LIBPROTOC_EXPORT CommandLineInterface {
struct OutputDirective; // see below
bool GenerateOutput(const vector<const FileDescriptor*>& parsed_files,
const OutputDirective& output_directive,
- OutputDirectory* output_directory);
+ GeneratorContext* generator_context);
bool GeneratePluginOutput(const vector<const FileDescriptor*>& parsed_files,
const string& plugin_name,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
string* error);
// Implements --encode and --decode.
@@ -230,12 +252,30 @@ class LIBPROTOC_EXPORT CommandLineInterface {
// protos will be ordered such that every file is listed before any file that
// depends on it, so that you can call DescriptorPool::BuildFile() on them
// in order. Any files in *already_seen will not be added, and each file
- // added will be inserted into *already_seen.
+ // added will be inserted into *already_seen. If include_source_code_info is
+ // true then include the source code information in the FileDescriptorProtos.
static void GetTransitiveDependencies(
const FileDescriptor* file,
+ bool include_source_code_info,
set<const FileDescriptor*>* already_seen,
RepeatedPtrField<FileDescriptorProto>* output);
+ // Implements the --print_free_field_numbers. This function prints free field
+ // numbers into stdout for the message and it's nested message types in
+ // post-order, i.e. nested types first. Printed range are left-right
+ // inclusive, i.e. [a, b].
+ //
+ // Groups:
+ // For historical reasons, groups are considered to share the same
+ // field number space with the parent message, thus it will not print free
+ // field numbers for groups. The field numbers used in the groups are
+ // excluded in the free field numbers of the parent message.
+ //
+ // Extension Ranges:
+ // Extension ranges are considered ocuppied field numbers and they will not be
+ // listed as free numbers in the output.
+ void PrintFreeFieldNumbers(const Descriptor* descriptor);
+
// -----------------------------------------------------------------
// The name of the executable as invoked (i.e. argv[0]).
@@ -244,13 +284,21 @@ class LIBPROTOC_EXPORT CommandLineInterface {
// Version info set with SetVersionInfo().
string version_info_;
- // Map from flag names to registered generators.
+ // Registered generators.
struct GeneratorInfo {
+ string flag_name;
+ string option_flag_name;
CodeGenerator* generator;
string help_text;
};
typedef map<string, GeneratorInfo> GeneratorMap;
- GeneratorMap generators_;
+ GeneratorMap generators_by_flag_name_;
+ GeneratorMap generators_by_option_name_;
+ // A map from generator names to the parameters specified using the option
+ // flag. For example, if the user invokes the compiler with:
+ // protoc --foo_out=outputdir --foo_opt=enable_bar ...
+ // Then there will be an entry ("--foo_out", "enable_bar") in this map.
+ map<string, string> generator_parameters_;
// See AllowPlugins(). If this is empty, plugins aren't allowed.
string plugin_prefix_;
@@ -264,11 +312,19 @@ class LIBPROTOC_EXPORT CommandLineInterface {
enum Mode {
MODE_COMPILE, // Normal mode: parse .proto files and compile them.
MODE_ENCODE, // --encode: read text from stdin, write binary to stdout.
- MODE_DECODE // --decode: read binary from stdin, write text to stdout.
+ MODE_DECODE, // --decode: read binary from stdin, write text to stdout.
+ MODE_PRINT, // Print mode: print info of the given .proto files and exit.
};
Mode mode_;
+ enum PrintMode {
+ PRINT_NONE, // Not in MODE_PRINT
+ PRINT_FREE_FIELDS, // --print_free_fields
+ };
+
+ PrintMode print_mode_;
+
enum ErrorFormat {
ERROR_FORMAT_GCC, // GCC error output format (default).
ERROR_FORMAT_MSVS // Visual Studio output (--error_format=msvs).
@@ -302,6 +358,10 @@ class LIBPROTOC_EXPORT CommandLineInterface {
// the .proto files listed on the command-line are added.
bool imports_in_descriptor_set_;
+ // True if --include_source_info was given, meaning that we should not strip
+ // SourceCodeInfo from the DescriptorSet.
+ bool source_info_in_descriptor_set_;
+
// Was the --disallow_services flag used?
bool disallow_services_;
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index 9129ebf..6bf7357 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -40,6 +40,7 @@
#else
#include <unistd.h>
#endif
+#include <memory>
#include <vector>
#include <google/protobuf/descriptor.pb.h>
@@ -48,6 +49,7 @@
#include <google/protobuf/compiler/command_line_interface.h>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/mock_code_generator.h>
+#include <google/protobuf/compiler/subprocess.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/testing/file.h>
@@ -121,6 +123,13 @@ class CommandLineInterfaceTest : public testing::Test {
// substring.
void ExpectErrorSubstring(const string& expected_substring);
+ // Like ExpectErrorSubstring, but checks that Run() returned zero.
+ void ExpectErrorSubstringWithZeroReturnCode(
+ const string& expected_substring);
+
+ // Checks that the captured stdout is the same as the expected_text.
+ void ExpectCapturedStdout(const string& expected_text);
+
// Returns true if ExpectErrorSubstring(expected_substring) would pass, but
// does not fail otherwise.
bool HasAlternateErrorSubstring(const string& expected_substring);
@@ -143,6 +152,10 @@ class CommandLineInterfaceTest : public testing::Test {
const string& proto_name,
const string& message_name,
const string& output_directory);
+ void ExpectGeneratedWithMultipleInputs(const string& generator_name,
+ const string& all_proto_names,
+ const string& proto_name,
+ const string& message_name);
void ExpectGeneratedWithInsertions(const string& generator_name,
const string& parameter,
const string& insertions,
@@ -173,6 +186,9 @@ class CommandLineInterfaceTest : public testing::Test {
// The captured stderr output.
string error_text_;
+ // The captured stdout.
+ string captured_stdout_;
+
// Pointers which need to be deleted later.
vector<CodeGenerator*> mock_generators_to_delete_;
@@ -190,7 +206,7 @@ class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator {
// implements CodeGenerator ----------------------------------------
bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
called_ = true;
parameter_ = parameter;
@@ -215,12 +231,12 @@ void CommandLineInterfaceTest::SetUp() {
}
// Create the temp directory.
- GOOGLE_CHECK(File::CreateDir(temp_directory_.c_str(), DEFAULT_FILE_MODE));
+ GOOGLE_CHECK_OK(File::CreateDir(temp_directory_, 0777));
// Register generators.
CodeGenerator* generator = new MockCodeGenerator("test_generator");
mock_generators_to_delete_.push_back(generator);
- cli_.RegisterGenerator("--test_out", generator, "Test output.");
+ cli_.RegisterGenerator("--test_out", "--test_opt", generator, "Test output.");
cli_.RegisterGenerator("-t", generator, "Test output.");
generator = new MockCodeGenerator("alt_generator");
@@ -246,12 +262,10 @@ void CommandLineInterfaceTest::TearDown() {
}
void CommandLineInterfaceTest::Run(const string& command) {
- vector<string> args;
- SplitStringUsing(command, " ", &args);
+ vector<string> args = Split(command, " ", true);
if (!disallow_plugins_) {
cli_.AllowPlugins("prefix-");
-
const char* possible_paths[] = {
// When building with shared libraries, libtool hides the real executable
// in .libs and puts a fake wrapper in the current directory.
@@ -287,18 +301,27 @@ void CommandLineInterfaceTest::Run(const string& command) {
}
}
- scoped_array<const char*> argv(new const char*[args.size()]);
+ scoped_array<const char*> argv(new const char* [args.size()]);
for (int i = 0; i < args.size(); i++) {
args[i] = StringReplace(args[i], "$tmpdir", temp_directory_, true);
argv[i] = args[i].c_str();
}
+ // TODO(jieluo): Cygwin doesn't work well if we try to capture stderr and
+ // stdout at the same time. Need to figure out why and add this capture back
+ // for Cygwin.
+#if !defined(__CYGWIN__)
+ CaptureTestStdout();
+#endif
CaptureTestStderr();
return_code_ = cli_.Run(args.size(), argv.get());
error_text_ = GetCapturedTestStderr();
+#if !defined(__CYGWIN__)
+ captured_stdout_ = GetCapturedTestStdout();
+#endif
}
// -------------------------------------------------------------------
@@ -310,16 +333,20 @@ void CommandLineInterfaceTest::CreateTempFile(
string::size_type slash_pos = name.find_last_of('/');
if (slash_pos != string::npos) {
string dir = name.substr(0, slash_pos);
- File::RecursivelyCreateDir(temp_directory_ + "/" + dir, 0777);
+ if (!File::Exists(temp_directory_ + "/" + dir)) {
+ GOOGLE_CHECK_OK(File::RecursivelyCreateDir(temp_directory_ + "/" + dir,
+ 0777));
+ }
}
// Write file.
string full_name = temp_directory_ + "/" + name;
- File::WriteStringToFileOrDie(contents, full_name);
+ GOOGLE_CHECK_OK(File::SetContents(full_name, contents, true));
}
void CommandLineInterfaceTest::CreateTempDir(const string& name) {
- File::RecursivelyCreateDir(temp_directory_ + "/" + name, 0777);
+ GOOGLE_CHECK_OK(File::RecursivelyCreateDir(temp_directory_ + "/" + name,
+ 0777));
}
// -------------------------------------------------------------------
@@ -341,6 +368,12 @@ void CommandLineInterfaceTest::ExpectErrorSubstring(
EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_);
}
+void CommandLineInterfaceTest::ExpectErrorSubstringWithZeroReturnCode(
+ const string& expected_substring) {
+ EXPECT_EQ(0, return_code_);
+ EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_);
+}
+
bool CommandLineInterfaceTest::HasAlternateErrorSubstring(
const string& expected_substring) {
EXPECT_NE(0, return_code_);
@@ -353,7 +386,8 @@ void CommandLineInterfaceTest::ExpectGenerated(
const string& proto_name,
const string& message_name) {
MockCodeGenerator::ExpectGenerated(
- generator_name, parameter, "", proto_name, message_name, temp_directory_);
+ generator_name, parameter, "", proto_name, message_name, proto_name,
+ temp_directory_);
}
void CommandLineInterfaceTest::ExpectGenerated(
@@ -363,10 +397,21 @@ void CommandLineInterfaceTest::ExpectGenerated(
const string& message_name,
const string& output_directory) {
MockCodeGenerator::ExpectGenerated(
- generator_name, parameter, "", proto_name, message_name,
+ generator_name, parameter, "", proto_name, message_name, proto_name,
temp_directory_ + "/" + output_directory);
}
+void CommandLineInterfaceTest::ExpectGeneratedWithMultipleInputs(
+ const string& generator_name,
+ const string& all_proto_names,
+ const string& proto_name,
+ const string& message_name) {
+ MockCodeGenerator::ExpectGenerated(
+ generator_name, "", "", proto_name, message_name,
+ all_proto_names,
+ temp_directory_);
+}
+
void CommandLineInterfaceTest::ExpectGeneratedWithInsertions(
const string& generator_name,
const string& parameter,
@@ -375,7 +420,7 @@ void CommandLineInterfaceTest::ExpectGeneratedWithInsertions(
const string& message_name) {
MockCodeGenerator::ExpectGenerated(
generator_name, parameter, insertions, proto_name, message_name,
- temp_directory_);
+ proto_name, temp_directory_);
}
void CommandLineInterfaceTest::ExpectNullCodeGeneratorCalled(
@@ -388,14 +433,18 @@ void CommandLineInterfaceTest::ReadDescriptorSet(
const string& filename, FileDescriptorSet* descriptor_set) {
string path = temp_directory_ + "/" + filename;
string file_contents;
- if (!File::ReadFileToString(path, &file_contents)) {
- FAIL() << "File not found: " << path;
- }
+ GOOGLE_CHECK_OK(File::GetContents(path, &file_contents, true));
+
if (!descriptor_set->ParseFromString(file_contents)) {
FAIL() << "Could not parse file contents: " << path;
}
}
+void CommandLineInterfaceTest::ExpectCapturedStdout(
+ const string& expected_text) {
+ EXPECT_EQ(expected_text, captured_stdout_);
+}
+
// ===================================================================
TEST_F(CommandLineInterfaceTest, BasicOutput) {
@@ -455,8 +504,44 @@ TEST_F(CommandLineInterfaceTest, MultipleInputs) {
"--proto_path=$tmpdir foo.proto bar.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "foo.proto", "Foo");
- ExpectGenerated("test_generator", "", "bar.proto", "Bar");
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport) {
+ // Test parsing multiple input files with an import of a separate file.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"baz.proto\";\n"
+ "message Bar {\n"
+ " optional Baz a = 1;\n"
+ "}\n");
+ CreateTempFile("baz.proto",
+ "syntax = \"proto2\";\n"
+ "message Baz {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto bar.proto");
+
+ ExpectNoErrors();
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
}
TEST_F(CommandLineInterfaceTest, CreateDirectory) {
@@ -492,6 +577,32 @@ TEST_F(CommandLineInterfaceTest, GeneratorParameters) {
ExpectGenerated("test_plugin", "TestPluginParameter", "foo.proto", "Foo");
}
+TEST_F(CommandLineInterfaceTest, ExtraGeneratorParameters) {
+ // Test that generator parameters specified with the option flag are
+ // correctly passed to the code generator.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ // Create the "a" and "b" sub-directories.
+ CreateTempDir("a");
+ CreateTempDir("b");
+
+ Run("protocol_compiler "
+ "--test_opt=foo1 "
+ "--test_out=bar:$tmpdir/a "
+ "--test_opt=foo2 "
+ "--test_out=baz:$tmpdir/b "
+ "--test_opt=foo3 "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated(
+ "test_generator", "bar,foo1,foo2,foo3", "foo.proto", "Foo", "a");
+ ExpectGenerated(
+ "test_generator", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b");
+}
+
TEST_F(CommandLineInterfaceTest, Insert) {
// Test running a generator that inserts code into another's output.
@@ -515,7 +626,7 @@ TEST_F(CommandLineInterfaceTest, Insert) {
"foo.proto", "Foo");
}
-#if defined(_WIN32) || defined(__CYGWIN__)
+#if defined(_WIN32)
TEST_F(CommandLineInterfaceTest, WindowsOutputPath) {
// Test that the output path can be a Windows-style path.
@@ -725,8 +836,35 @@ TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) {
FileDescriptorSet descriptor_set;
ReadDescriptorSet("descriptor_set", &descriptor_set);
if (HasFatalFailure()) return;
- ASSERT_EQ(1, descriptor_set.file_size());
+ EXPECT_EQ(1, descriptor_set.file_size());
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());
+}
+
+TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithSourceInfo) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+ "--include_source_info --proto_path=$tmpdir bar.proto");
+
+ ExpectNoErrors();
+
+ FileDescriptorSet descriptor_set;
+ ReadDescriptorSet("descriptor_set", &descriptor_set);
+ if (HasFatalFailure()) return;
+ EXPECT_EQ(1, descriptor_set.file_size());
+ EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
+ // Source code info included.
+ EXPECT_TRUE(descriptor_set.file(0).has_source_code_info());
}
TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) {
@@ -748,13 +886,47 @@ TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) {
FileDescriptorSet descriptor_set;
ReadDescriptorSet("descriptor_set", &descriptor_set);
if (HasFatalFailure()) return;
- ASSERT_EQ(2, descriptor_set.file_size());
+ EXPECT_EQ(2, descriptor_set.file_size());
if (descriptor_set.file(0).name() == "bar.proto") {
std::swap(descriptor_set.mutable_file()->mutable_data()[0],
descriptor_set.mutable_file()->mutable_data()[1]);
}
EXPECT_EQ("foo.proto", descriptor_set.file(0).name());
EXPECT_EQ("bar.proto", descriptor_set.file(1).name());
+ // Descriptor set should not have source code info.
+ EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
+ EXPECT_FALSE(descriptor_set.file(1).has_source_code_info());
+}
+
+TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSetWithSourceInfo) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+ "--include_imports --include_source_info --proto_path=$tmpdir bar.proto");
+
+ ExpectNoErrors();
+
+ FileDescriptorSet descriptor_set;
+ ReadDescriptorSet("descriptor_set", &descriptor_set);
+ if (HasFatalFailure()) return;
+ EXPECT_EQ(2, descriptor_set.file_size());
+ if (descriptor_set.file(0).name() == "bar.proto") {
+ std::swap(descriptor_set.mutable_file()->mutable_data()[0],
+ descriptor_set.mutable_file()->mutable_data()[1]);
+ }
+ EXPECT_EQ("foo.proto", descriptor_set.file(0).name());
+ EXPECT_EQ("bar.proto", descriptor_set.file(1).name());
+ // Source code info included.
+ EXPECT_TRUE(descriptor_set.file(0).has_source_code_info());
+ EXPECT_TRUE(descriptor_set.file(1).has_source_code_info());
}
// -------------------------------------------------------------------
@@ -1077,6 +1249,17 @@ TEST_F(CommandLineInterfaceTest, GeneratorPluginCrash) {
#endif
}
+TEST_F(CommandLineInterfaceTest, PluginReceivesSourceCodeInfo) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_HasSourceCodeInfo {}\n");
+
+ Run("protocol_compiler --plug_out=$tmpdir --proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring(
+ "Saw message type MockCodeGenerator_HasSourceCodeInfo: 1.");
+}
+
TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) {
// Test what happens if the plugin isn't found.
@@ -1089,9 +1272,8 @@ TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) {
"--proto_path=$tmpdir error.proto");
#ifdef _WIN32
- ExpectErrorSubstring(
- "--badplug_out: prefix-gen-badplug: The system cannot find the file "
- "specified.");
+ ExpectErrorSubstring("--badplug_out: prefix-gen-badplug: " +
+ Subprocess::Win32ErrorMessage(ERROR_FILE_NOT_FOUND));
#else
// Error written to stdout by child process after exec() fails.
ExpectErrorSubstring(
@@ -1120,11 +1302,11 @@ TEST_F(CommandLineInterfaceTest, GeneratorPluginNotAllowed) {
TEST_F(CommandLineInterfaceTest, HelpText) {
Run("test_exec_name --help");
- ExpectErrorSubstring("Usage: test_exec_name ");
- ExpectErrorSubstring("--test_out=OUT_DIR");
- ExpectErrorSubstring("Test output.");
- ExpectErrorSubstring("--alt_out=OUT_DIR");
- ExpectErrorSubstring("Alt output.");
+ ExpectErrorSubstringWithZeroReturnCode("Usage: test_exec_name ");
+ ExpectErrorSubstringWithZeroReturnCode("--test_out=OUT_DIR");
+ ExpectErrorSubstringWithZeroReturnCode("Test output.");
+ ExpectErrorSubstringWithZeroReturnCode("--alt_out=OUT_DIR");
+ ExpectErrorSubstringWithZeroReturnCode("Alt output.");
}
TEST_F(CommandLineInterfaceTest, GccFormatErrors) {
@@ -1153,7 +1335,7 @@ TEST_F(CommandLineInterfaceTest, MsvsFormatErrors) {
"--proto_path=$tmpdir --error_format=msvs foo.proto");
ExpectErrorText(
- "foo.proto(2) : error in column=1: Expected top-level statement "
+ "$tmpdir/foo.proto(2) : error in column=1: Expected top-level statement "
"(e.g. \"message\").\n");
}
@@ -1234,6 +1416,76 @@ TEST_F(CommandLineInterfaceTest, MissingValueAtEndError) {
ExpectErrorText("Missing value for flag: --test_out\n");
}
+TEST_F(CommandLineInterfaceTest, PrintFreeFieldNumbers) {
+ CreateTempFile(
+ "foo.proto",
+ "syntax = \"proto2\";\n"
+ "package foo;\n"
+ "message Foo {\n"
+ " optional int32 a = 2;\n"
+ " optional string b = 4;\n"
+ " optional string c = 5;\n"
+ " optional int64 d = 8;\n"
+ " optional double e = 10;\n"
+ "}\n");
+ CreateTempFile(
+ "bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {\n"
+ " optional int32 a = 2;\n"
+ " extensions 4 to 5;\n"
+ " optional int64 d = 8;\n"
+ " extensions 10;\n"
+ "}\n");
+ CreateTempFile(
+ "baz.proto",
+ "syntax = \"proto2\";\n"
+ "message Baz {\n"
+ " optional int32 a = 2;\n"
+ " optional int64 d = 8;\n"
+ " extensions 15 to max;\n" // unordered.
+ " extensions 13;\n"
+ " extensions 10 to 12;\n"
+ " extensions 5;\n"
+ " extensions 4;\n"
+ "}\n");
+ CreateTempFile(
+ "quz.proto",
+ "syntax = \"proto2\";\n"
+ "message Quz {\n"
+ " message Foo {}\n" // nested message
+ " optional int32 a = 2;\n"
+ " optional group C = 4 {\n"
+ " optional int32 d = 5;\n"
+ " }\n"
+ " extensions 8 to 10;\n"
+ " optional group E = 11 {\n"
+ " optional int32 f = 9;\n" // explicitly reuse extension range 8-10
+ " optional group G = 15 {\n" // nested group
+ " message Foo {}\n" // nested message inside nested group
+ " }\n"
+ " }\n"
+ "}\n");
+
+ Run("protocol_compiler --print_free_field_numbers --proto_path=$tmpdir "
+ "foo.proto bar.proto baz.proto quz.proto");
+
+ ExpectNoErrors();
+
+ // TODO(jieluo): Cygwin doesn't work well if we try to capture stderr and
+ // stdout at the same time. Need to figure out why and add this test back
+ // for Cygwin.
+#if !defined(__CYGWIN__)
+ ExpectCapturedStdout(
+ "foo.Foo free: 1 3 6-7 9 11-INF\n"
+ "Bar free: 1 3 6-7 9 11-INF\n"
+ "Baz free: 1 3 6-7 9 14\n"
+ "Quz.Foo free: 1-INF\n"
+ "Quz.E.G.Foo free: 1-INF\n"
+ "Quz free: 1 3 6-7 12-14 16-INF\n");
+#endif
+}
+
// ===================================================================
// Test for --encode and --decode. Note that it would be easier to do this
@@ -1253,7 +1505,7 @@ class EncodeDecodeTest : public testing::Test {
void RedirectStdinFromText(const string& input) {
string filename = TestTempDir() + "/test_stdin";
- File::WriteStringToFileOrDie(input, filename);
+ GOOGLE_CHECK_OK(File::SetContents(filename, input, true));
GOOGLE_CHECK(RedirectStdinFromFile(filename));
}
@@ -1287,7 +1539,7 @@ class EncodeDecodeTest : public testing::Test {
SplitStringUsing(command, " ", &args);
args.push_back("--proto_path=" + TestSourceDir());
- scoped_array<const char*> argv(new const char*[args.size()]);
+ scoped_array<const char*> argv(new const char* [args.size()]);
for (int i = 0; i < args.size(); i++) {
argv[i] = args[i].c_str();
}
@@ -1308,7 +1560,7 @@ class EncodeDecodeTest : public testing::Test {
void ExpectStdoutMatchesBinaryFile(const string& filename) {
string expected_output;
- ASSERT_TRUE(File::ReadFileToString(filename, &expected_output));
+ GOOGLE_CHECK_OK(File::GetContents(filename, &expected_output, true));
// Don't use EXPECT_EQ because we don't want to print raw binary data to
// stdout on failure.
@@ -1317,7 +1569,7 @@ class EncodeDecodeTest : public testing::Test {
void ExpectStdoutMatchesTextFile(const string& filename) {
string expected_output;
- ASSERT_TRUE(File::ReadFileToString(filename, &expected_output));
+ GOOGLE_CHECK_OK(File::GetContents(filename, &expected_output, true));
ExpectStdoutMatchesText(expected_output);
}
@@ -1337,22 +1589,23 @@ class EncodeDecodeTest : public testing::Test {
};
TEST_F(EncodeDecodeTest, Encode) {
- RedirectStdinFromFile(TestSourceDir() +
- "/google/protobuf/testdata/text_format_unittest_data.txt");
+ RedirectStdinFromFile(TestSourceDir() + "/google/protobuf/"
+ "testdata/text_format_unittest_data_oneof_implemented.txt");
EXPECT_TRUE(Run("google/protobuf/unittest.proto "
"--encode=protobuf_unittest.TestAllTypes"));
ExpectStdoutMatchesBinaryFile(TestSourceDir() +
- "/google/protobuf/testdata/golden_message");
+ "/google/protobuf/testdata/golden_message_oneof_implemented");
ExpectStderrMatchesText("");
}
TEST_F(EncodeDecodeTest, Decode) {
RedirectStdinFromFile(TestSourceDir() +
- "/google/protobuf/testdata/golden_message");
+ "/google/protobuf/testdata/golden_message_oneof_implemented");
EXPECT_TRUE(Run("google/protobuf/unittest.proto "
"--decode=protobuf_unittest.TestAllTypes"));
ExpectStdoutMatchesTextFile(TestSourceDir() +
- "/google/protobuf/testdata/text_format_unittest_data.txt");
+ "/google/protobuf/"
+ "testdata/text_format_unittest_data_oneof_implemented.txt");
ExpectStderrMatchesText("");
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
index 30b1d2b..4878819 100644
--- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -48,8 +48,8 @@
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
-#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/stl_util.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
@@ -79,10 +79,10 @@ class MockErrorCollector : public MultiFileErrorCollector {
}
};
-class MockOutputDirectory : public OutputDirectory {
+class MockGeneratorContext : public GeneratorContext {
public:
- MockOutputDirectory() {}
- ~MockOutputDirectory() {
+ MockGeneratorContext() {}
+ ~MockGeneratorContext() {
STLDeleteValues(&files_);
}
@@ -93,16 +93,16 @@ class MockOutputDirectory : public OutputDirectory {
<< "Generator failed to generate file: " << virtual_filename;
string actual_contents;
- File::ReadFileToStringOrDie(
- TestSourceDir() + "/" + physical_filename,
- &actual_contents);
+ GOOGLE_CHECK_OK(
+ File::GetContents(TestSourceDir() + "/" + physical_filename,
+ &actual_contents, true));
EXPECT_TRUE(actual_contents == *expected_contents)
<< physical_filename << " needs to be regenerated. Please run "
"generate_descriptor_proto.sh and add this file "
"to your CL.";
}
- // implements OutputDirectory --------------------------------------
+ // implements GeneratorContext --------------------------------------
virtual io::ZeroCopyOutputStream* Open(const string& filename) {
string** map_slot = &files_[filename];
@@ -130,24 +130,24 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) {
ASSERT_TRUE(plugin_proto_file != NULL);
CppGenerator generator;
- MockOutputDirectory output_directory;
+ MockGeneratorContext context;
string error;
string parameter;
parameter = "dllexport_decl=LIBPROTOBUF_EXPORT";
ASSERT_TRUE(generator.Generate(proto_file, parameter,
- &output_directory, &error));
+ &context, &error));
parameter = "dllexport_decl=LIBPROTOC_EXPORT";
ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter,
- &output_directory, &error));
-
- output_directory.ExpectFileMatches("google/protobuf/descriptor.pb.h",
- "google/protobuf/descriptor.pb.h");
- output_directory.ExpectFileMatches("google/protobuf/descriptor.pb.cc",
- "google/protobuf/descriptor.pb.cc");
- output_directory.ExpectFileMatches("google/protobuf/compiler/plugin.pb.h",
- "google/protobuf/compiler/plugin.pb.h");
- output_directory.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc",
- "google/protobuf/compiler/plugin.pb.cc");
+ &context, &error));
+
+ context.ExpectFileMatches("google/protobuf/descriptor.pb.h",
+ "google/protobuf/descriptor.pb.h");
+ context.ExpectFileMatches("google/protobuf/descriptor.pb.cc",
+ "google/protobuf/descriptor.pb.cc");
+ context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.h",
+ "google/protobuf/compiler/plugin.pb.h");
+ context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc",
+ "google/protobuf/compiler/plugin.pb.cc");
}
} // namespace
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc
index 76d2b79..c31cb5b 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -45,11 +45,27 @@ namespace protobuf {
namespace compiler {
namespace cpp {
+namespace {
+// The GOOGLE_ARRAYSIZE constant is the max enum value plus 1. If the max enum value
+// is kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the
+// generation of the GOOGLE_ARRAYSIZE constant.
+bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) {
+ int32 max_value = descriptor->value(0)->number();
+ for (int i = 0; i < descriptor->value_count(); i++) {
+ if (descriptor->value(i)->number() > max_value) {
+ max_value = descriptor->value(i)->number();
+ }
+ }
+ return max_value != kint32max;
+}
+} // namespace
+
EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
- const string& dllexport_decl)
+ const Options& options)
: descriptor_(descriptor),
classname_(ClassName(descriptor, false)),
- dllexport_decl_(dllexport_decl) {
+ options_(options),
+ generate_array_size_(ShouldGenerateArraySize(descriptor)) {
}
EnumGenerator::~EnumGenerator() {}
@@ -67,7 +83,10 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
for (int i = 0; i < descriptor_->value_count(); i++) {
vars["name"] = descriptor_->value(i)->name();
- vars["number"] = SimpleItoa(descriptor_->value(i)->number());
+ // In C++, an value of -2147483648 gets interpreted as the negative of
+ // 2147483648, and since 2147483648 can't fit in an integer, this produces a
+ // compiler warning. This works around that issue.
+ vars["number"] = Int32ToString(descriptor_->value(i)->number());
vars["prefix"] = (descriptor_->containing_type() == NULL) ?
"" : classname_ + "_";
@@ -88,18 +107,22 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
vars["min_name"] = min_value->name();
vars["max_name"] = max_value->name();
- if (dllexport_decl_.empty()) {
+ if (options_.dllexport_decl.empty()) {
vars["dllexport"] = "";
} else {
- vars["dllexport"] = dllexport_decl_ + " ";
+ vars["dllexport"] = options_.dllexport_decl + " ";
}
printer->Print(vars,
"$dllexport$bool $classname$_IsValid(int value);\n"
"const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n"
- "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n"
- "const int $prefix$$short_name$_ARRAYSIZE = $prefix$$short_name$_MAX + 1;\n"
- "\n");
+ "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n");
+
+ if (generate_array_size_) {
+ printer->Print(vars,
+ "const int $prefix$$short_name$_ARRAYSIZE = "
+ "$prefix$$short_name$_MAX + 1;\n\n");
+ }
if (HasDescriptorMethods(descriptor_->file())) {
printer->Print(vars,
@@ -123,6 +146,7 @@ void EnumGenerator::
GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
if (HasDescriptorMethods(descriptor_->file())) {
printer->Print(
+ "template <> struct is_proto_enum< $classname$> : ::google::protobuf::internal::true_type {};\n"
"template <>\n"
"inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n"
" return $classname$_descriptor();\n"
@@ -150,9 +174,12 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
"static const $nested_name$ $nested_name$_MIN =\n"
" $classname$_$nested_name$_MIN;\n"
"static const $nested_name$ $nested_name$_MAX =\n"
- " $classname$_$nested_name$_MAX;\n"
- "static const int $nested_name$_ARRAYSIZE =\n"
- " $classname$_$nested_name$_ARRAYSIZE;\n");
+ " $classname$_$nested_name$_MAX;\n");
+ if (generate_array_size_) {
+ printer->Print(vars,
+ "static const int $nested_name$_ARRAYSIZE =\n"
+ " $classname$_$nested_name$_ARRAYSIZE;\n");
+ }
if (HasDescriptorMethods(descriptor_->file())) {
printer->Print(vars,
@@ -218,7 +245,7 @@ void EnumGenerator::GenerateMethods(io::Printer* printer) {
iter != numbers.end(); ++iter) {
printer->Print(
" case $number$:\n",
- "number", SimpleItoa(*iter));
+ "number", Int32ToString(*iter));
}
printer->Print(vars,
@@ -245,8 +272,11 @@ void EnumGenerator::GenerateMethods(io::Printer* printer) {
}
printer->Print(vars,
"const $classname$ $parent$::$nested_name$_MIN;\n"
- "const $classname$ $parent$::$nested_name$_MAX;\n"
- "const int $parent$::$nested_name$_ARRAYSIZE;\n");
+ "const $classname$ $parent$::$nested_name$_MAX;\n");
+ if (generate_array_size_) {
+ printer->Print(vars,
+ "const int $parent$::$nested_name$_ARRAYSIZE;\n");
+ }
printer->Print("#endif // _MSC_VER\n");
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.h b/src/google/protobuf/compiler/cpp/cpp_enum.h
index 58f7721..1ebd7cf 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.h
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -36,8 +36,10 @@
#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
#include <string>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/descriptor.h>
+
namespace google {
namespace protobuf {
namespace io {
@@ -53,7 +55,7 @@ class EnumGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit EnumGenerator(const EnumDescriptor* descriptor,
- const string& dllexport_decl);
+ const Options& options);
~EnumGenerator();
// Header stuff.
@@ -86,7 +88,9 @@ class EnumGenerator {
private:
const EnumDescriptor* descriptor_;
string classname_;
- string dllexport_decl_;
+ Options options_;
+ // whether to generate the *_ARRAYSIZE constant.
+ 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 91ce493..20b18ad 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -46,11 +46,13 @@ namespace cpp {
namespace {
void SetEnumVariables(const FieldDescriptor* descriptor,
- map<string, string>* variables) {
- SetCommonFieldVariables(descriptor, variables);
+ map<string, string>* variables,
+ const Options& options) {
+ SetCommonFieldVariables(descriptor, variables, options);
const EnumValueDescriptor* default_value = descriptor->default_value_enum();
(*variables)["type"] = ClassName(descriptor->enum_type(), true);
- (*variables)["default"] = SimpleItoa(default_value->number());
+ (*variables)["default"] = Int32ToString(default_value->number());
+ (*variables)["full_name"] = descriptor->full_name();
}
} // namespace
@@ -58,9 +60,10 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
// ===================================================================
EnumFieldGenerator::
-EnumFieldGenerator(const FieldDescriptor* descriptor)
+EnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
: descriptor_(descriptor) {
- SetEnumVariables(descriptor, &variables_);
+ SetEnumVariables(descriptor, &variables_, options);
}
EnumFieldGenerator::~EnumFieldGenerator() {}
@@ -81,12 +84,14 @@ void EnumFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
printer->Print(variables_,
"inline $type$ $classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
" return static_cast< $type$ >($name$_);\n"
"}\n"
"inline void $classname$::set_$name$($type$ value) {\n"
- " GOOGLE_DCHECK($type$_IsValid(value));\n"
- " _set_bit($index$);\n"
+ " assert($type$_IsValid(value));\n"
+ " set_has_$name$();\n"
" $name$_ = value;\n"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n");
}
@@ -119,10 +124,15 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
" input, &value)));\n"
"if ($type$_IsValid(value)) {\n"
" set_$name$(static_cast< $type$ >(value));\n");
- if (HasUnknownFields(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file())) {
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");
}
printer->Print(variables_,
"}\n");
@@ -151,10 +161,57 @@ GenerateByteSize(io::Printer* printer) const {
// ===================================================================
+EnumOneofFieldGenerator::
+EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : EnumFieldGenerator(descriptor, options) {
+ SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {}
+
+void EnumOneofFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $classname$::$name$() const {\n"
+ " if (has_$name$()) {\n"
+ " return static_cast< $type$ >($oneof_prefix$$name$_);\n"
+ " }\n"
+ " return static_cast< $type$ >($default$);\n"
+ "}\n"
+ "inline void $classname$::set_$name$($type$ value) {\n"
+ " assert($type$_IsValid(value));\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " }\n"
+ " $oneof_prefix$$name$_ = value;\n"
+ "}\n");
+}
+
+void EnumOneofFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$oneof_prefix$$name$_ = $default$;\n");
+}
+
+void EnumOneofFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void EnumOneofFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ " $classname$_default_oneof_instance_->$name$_ = $default$;\n");
+}
+
+// ===================================================================
+
RepeatedEnumFieldGenerator::
-RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor)
+RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
: descriptor_(descriptor) {
- SetEnumVariables(descriptor, &variables_);
+ SetEnumVariables(descriptor, &variables_, options);
}
RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
@@ -163,7 +220,8 @@ void RepeatedEnumFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
printer->Print(variables_,
"::google::protobuf::RepeatedField<int> $name$_;\n");
- if (descriptor_->options().packed() && HasGeneratedMethods(descriptor_->file())) {
+ if (descriptor_->options().packed()
+ && HasGeneratedMethods(descriptor_->file())) {
printer->Print(variables_,
"mutable int _$name$_cached_byte_size_;\n");
}
@@ -184,23 +242,28 @@ void RepeatedEnumFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
printer->Print(variables_,
"inline $type$ $classname$::$name$(int index) const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
" return static_cast< $type$ >($name$_.Get(index));\n"
"}\n"
"inline void $classname$::set_$name$(int index, $type$ value) {\n"
- " GOOGLE_DCHECK($type$_IsValid(value));\n"
+ " assert($type$_IsValid(value));\n"
" $name$_.Set(index, value);\n"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
"inline void $classname$::add_$name$($type$ value) {\n"
- " GOOGLE_DCHECK($type$_IsValid(value));\n"
+ " assert($type$_IsValid(value));\n"
" $name$_.Add(value);\n"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
"}\n");
printer->Print(variables_,
"inline const ::google::protobuf::RepeatedField<int>&\n"
"$classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
" return $name$_;\n"
"}\n"
"inline ::google::protobuf::RepeatedField<int>*\n"
"$classname$::mutable_$name$() {\n"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
" return &$name$_;\n"
"}\n");
}
@@ -235,10 +298,15 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
" input, &value)));\n"
"if ($type$_IsValid(value)) {\n"
" add_$name$(static_cast< $type$ >(value));\n");
- if (HasUnknownFields(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file())) {
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");
}
printer->Print("}\n");
}
@@ -345,7 +413,9 @@ GenerateByteSize(io::Printer* printer) const {
" total_size += $tag_size$ +\n"
" ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
"}\n"
+ "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
"_$name$_cached_byte_size_ = data_size;\n"
+ "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
"total_size += data_size;\n");
} else {
printer->Print(variables_,
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/src/google/protobuf/compiler/cpp/cpp_enum_field.h
index 0793430..def2b23 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -46,7 +46,8 @@ namespace cpp {
class EnumFieldGenerator : public FieldGenerator {
public:
- explicit EnumFieldGenerator(const FieldDescriptor* descriptor);
+ explicit EnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~EnumFieldGenerator();
// implements FieldGenerator ---------------------------------------
@@ -62,16 +63,34 @@ class EnumFieldGenerator : public FieldGenerator {
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
void GenerateByteSize(io::Printer* printer) const;
- private:
+ protected:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
};
+class EnumOneofFieldGenerator : public EnumFieldGenerator {
+ public:
+ explicit EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~EnumOneofFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumOneofFieldGenerator);
+};
+
class RepeatedEnumFieldGenerator : public FieldGenerator {
public:
- explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor);
+ explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~RepeatedEnumFieldGenerator();
// implements FieldGenerator ---------------------------------------
diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc
index 658a707..468ca48 100644
--- a/src/google/protobuf/compiler/cpp/cpp_extension.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -57,9 +57,9 @@ string ExtendeeClassName(const FieldDescriptor* descriptor) {
} // anonymous namespace
ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
- const string& dllexport_decl)
+ const Options& options)
: descriptor_(descriptor),
- dllexport_decl_(dllexport_decl) {
+ options_(options) {
// Construct type_traits_.
if (descriptor_->is_repeated()) {
type_traits_ = "Repeated";
@@ -106,8 +106,8 @@ void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
// export/import specifier.
if (descriptor_->extension_scope() == NULL) {
vars["qualifier"] = "extern";
- if (!dllexport_decl_.empty()) {
- vars["qualifier"] = dllexport_decl_ + " " + vars["qualifier"];
+ if (!options_.dllexport_decl.empty()) {
+ vars["qualifier"] = options_.dllexport_decl + " " + vars["qualifier"];
}
} else {
vars["qualifier"] = "static";
diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.h b/src/google/protobuf/compiler/cpp/cpp_extension.h
index 3068b09..d354c16 100644
--- a/src/google/protobuf/compiler/cpp/cpp_extension.h
+++ b/src/google/protobuf/compiler/cpp/cpp_extension.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -37,6 +37,7 @@
#include <string>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
namespace google {
namespace protobuf {
@@ -56,8 +57,8 @@ namespace cpp {
class ExtensionGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
- explicit ExtensionGenerator(const FieldDescriptor* descriptor,
- const string& dllexport_decl);
+ explicit ExtensionGenerator(const FieldDescriptor* desycriptor,
+ const Options& options);
~ExtensionGenerator();
// Header stuff.
@@ -72,7 +73,7 @@ class ExtensionGenerator {
private:
const FieldDescriptor* descriptor_;
string type_traits_;
- string dllexport_decl_;
+ Options options_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
};
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc
index 103cac4..1e9a40a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_field.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,6 +33,8 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/cpp_field.h>
+#include <memory>
+
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
#include <google/protobuf/compiler/cpp/cpp_string_field.h>
@@ -52,7 +54,8 @@ namespace cpp {
using internal::WireFormat;
void SetCommonFieldVariables(const FieldDescriptor* descriptor,
- map<string, string>* variables) {
+ map<string, string>* variables,
+ const Options& options) {
(*variables)["name"] = FieldName(descriptor);
(*variables)["index"] = SimpleItoa(descriptor->index());
(*variables)["number"] = SimpleItoa(descriptor->number());
@@ -64,6 +67,13 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
(*variables)["deprecation"] = descriptor->options().deprecated()
? " PROTOBUF_DEPRECATED" : "";
+ (*variables)["cppget"] = "Get";
+}
+
+void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables) {
+ (*variables)["oneof_prefix"] = descriptor->containing_oneof()->name() + "_.";
+ (*variables)["oneof_name"] = descriptor->containing_oneof()->name();
}
FieldGenerator::~FieldGenerator() {}
@@ -80,46 +90,63 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
}
-FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
- : descriptor_(descriptor),
- field_generators_(
- new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
+FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor),
+ field_generators_(
+ new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
// Construct all the FieldGenerators.
for (int i = 0; i < descriptor->field_count(); i++) {
- field_generators_[i].reset(MakeGenerator(descriptor->field(i)));
+ field_generators_[i].reset(MakeGenerator(descriptor->field(i), options));
}
}
-FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) {
+FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
+ const Options& options) {
if (field->is_repeated()) {
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_MESSAGE:
- return new RepeatedMessageFieldGenerator(field);
+ return new RepeatedMessageFieldGenerator(field, options);
case FieldDescriptor::CPPTYPE_STRING:
switch (field->options().ctype()) {
default: // RepeatedStringFieldGenerator handles unknown ctypes.
case FieldOptions::STRING:
- return new RepeatedStringFieldGenerator(field);
+ return new RepeatedStringFieldGenerator(field, options);
+ }
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return new RepeatedEnumFieldGenerator(field, options);
+ default:
+ return new RepeatedPrimitiveFieldGenerator(field, options);
+ }
+ } else if (field->containing_oneof()) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return new MessageOneofFieldGenerator(field, options);
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // StringOneofFieldGenerator handles unknown ctypes.
+ case FieldOptions::STRING:
+ return new StringOneofFieldGenerator(field, options);
}
case FieldDescriptor::CPPTYPE_ENUM:
- return new RepeatedEnumFieldGenerator(field);
+ return new EnumOneofFieldGenerator(field, options);
default:
- return new RepeatedPrimitiveFieldGenerator(field);
+ return new PrimitiveOneofFieldGenerator(field, options);
}
} else {
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_MESSAGE:
- return new MessageFieldGenerator(field);
+ return new MessageFieldGenerator(field, options);
case FieldDescriptor::CPPTYPE_STRING:
switch (field->options().ctype()) {
default: // StringFieldGenerator handles unknown ctypes.
case FieldOptions::STRING:
- return new StringFieldGenerator(field);
+ return new StringFieldGenerator(field, options);
}
case FieldDescriptor::CPPTYPE_ENUM:
- return new EnumFieldGenerator(field);
+ return new EnumFieldGenerator(field, options);
default:
- return new PrimitiveFieldGenerator(field);
+ return new PrimitiveFieldGenerator(field, options);
}
}
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h
index c303a33..96c2963 100644
--- a/src/google/protobuf/compiler/cpp/cpp_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_field.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -36,10 +36,11 @@
#define GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
#include <map>
+#include <memory>
#include <string>
-#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
namespace google {
namespace protobuf {
@@ -57,7 +58,11 @@ namespace cpp {
// ['name', 'index', 'number', 'classname', 'declared_type', 'tag_size',
// 'deprecation'].
void SetCommonFieldVariables(const FieldDescriptor* descriptor,
- map<string, string>* variables);
+ map<string, string>* variables,
+ const Options& options);
+
+void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables);
class FieldGenerator {
public:
@@ -69,6 +74,11 @@ class FieldGenerator {
// class.
virtual void GeneratePrivateMembers(io::Printer* printer) const = 0;
+ // Generate static default variable for this field. These are placed inside
+ // the message class. Most field types don't need this, so the default
+ // implementation is empty.
+ virtual void GenerateStaticMembers(io::Printer* printer) const {}
+
// Generate prototypes for all of the accessor functions related to this
// field. These are placed inside the class definition.
virtual void GenerateAccessorDeclarations(io::Printer* printer) const = 0;
@@ -114,6 +124,13 @@ class FieldGenerator {
// Most field types don't need this, so the default implementation is empty.
virtual void GenerateDestructorCode(io::Printer* printer) const {}
+ // Generate code that allocates the fields's default instance.
+ virtual void GenerateDefaultInstanceAllocator(io::Printer* printer) const {}
+
+ // Generate code that should be run when ShutdownProtobufLibrary() is called,
+ // to delete all dynamically-allocated objects.
+ virtual void GenerateShutdownCode(io::Printer* printer) const {}
+
// Generate lines to decode this field, which will be placed inside the
// message's MergeFromCodedStream() method.
virtual void GenerateMergeFromCodedStream(io::Printer* printer) const = 0;
@@ -144,7 +161,7 @@ class FieldGenerator {
// Convenience class which constructs FieldGenerators for a Descriptor.
class FieldGeneratorMap {
public:
- explicit FieldGeneratorMap(const Descriptor* descriptor);
+ explicit FieldGeneratorMap(const Descriptor* descriptor, const Options& options);
~FieldGeneratorMap();
const FieldGenerator& get(const FieldDescriptor* field) const;
@@ -153,7 +170,8 @@ class FieldGeneratorMap {
const Descriptor* descriptor_;
scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
- static FieldGenerator* MakeGenerator(const FieldDescriptor* field);
+ static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
+ const Options& options);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
};
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 80da7e4..fa19427 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,6 +33,9 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/cpp_file.h>
+#include <memory>
+#include <set>
+
#include <google/protobuf/compiler/cpp/cpp_enum.h>
#include <google/protobuf/compiler/cpp/cpp_service.h>
#include <google/protobuf/compiler/cpp/cpp_extension.h>
@@ -50,37 +53,36 @@ namespace cpp {
// ===================================================================
-FileGenerator::FileGenerator(const FileDescriptor* file,
- const string& dllexport_decl)
- : file_(file),
- message_generators_(
- new scoped_ptr<MessageGenerator>[file->message_type_count()]),
- enum_generators_(
- new scoped_ptr<EnumGenerator>[file->enum_type_count()]),
- service_generators_(
- new scoped_ptr<ServiceGenerator>[file->service_count()]),
- extension_generators_(
- new scoped_ptr<ExtensionGenerator>[file->extension_count()]),
- dllexport_decl_(dllexport_decl) {
+FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
+ : file_(file),
+ message_generators_(
+ new scoped_ptr<MessageGenerator>[file->message_type_count()]),
+ enum_generators_(
+ new scoped_ptr<EnumGenerator>[file->enum_type_count()]),
+ service_generators_(
+ new scoped_ptr<ServiceGenerator>[file->service_count()]),
+ extension_generators_(
+ new scoped_ptr<ExtensionGenerator>[file->extension_count()]),
+ options_(options) {
for (int i = 0; i < file->message_type_count(); i++) {
message_generators_[i].reset(
- new MessageGenerator(file->message_type(i), dllexport_decl));
+ new MessageGenerator(file->message_type(i), options));
}
for (int i = 0; i < file->enum_type_count(); i++) {
enum_generators_[i].reset(
- new EnumGenerator(file->enum_type(i), dllexport_decl));
+ new EnumGenerator(file->enum_type(i), options));
}
for (int i = 0; i < file->service_count(); i++) {
service_generators_[i].reset(
- new ServiceGenerator(file->service(i), dllexport_decl));
+ new ServiceGenerator(file->service(i), options));
}
for (int i = 0; i < file->extension_count(); i++) {
extension_generators_[i].reset(
- new ExtensionGenerator(file->extension(i), dllexport_decl));
+ new ExtensionGenerator(file->extension(i), options));
}
SplitStringUsing(file_->package(), ".", &package_parts_);
@@ -104,6 +106,7 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
"filename", file_->name(),
"filename_identifier", filename_identifier);
+
printer->Print(
"#include <google/protobuf/stubs/common.h>\n"
"\n");
@@ -128,13 +131,23 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
// OK, it's now safe to #include other files.
printer->Print(
- "#include <google/protobuf/generated_message_util.h>\n"
+ "#include <google/protobuf/generated_message_util.h>\n");
+ if (file_->message_type_count() > 0) {
+ if (HasDescriptorMethods(file_)) {
+ printer->Print(
+ "#include <google/protobuf/message.h>\n");
+ } else {
+ printer->Print(
+ "#include <google/protobuf/message_lite.h>\n");
+ }
+ }
+ printer->Print(
"#include <google/protobuf/repeated_field.h>\n"
"#include <google/protobuf/extension_set.h>\n");
- if (HasDescriptorMethods(file_)) {
+ if (HasDescriptorMethods(file_) && HasEnumDefinitions(file_)) {
printer->Print(
- "#include <google/protobuf/generated_message_reflection.h>\n");
+ "#include <google/protobuf/generated_enum_reflection.h>\n");
}
if (HasGenericServices(file_)) {
@@ -142,16 +155,32 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
"#include <google/protobuf/service.h>\n");
}
+ if (UseUnknownFieldSet(file_) && file_->message_type_count() > 0) {
+ printer->Print(
+ "#include <google/protobuf/unknown_field_set.h>\n");
+ }
+
+
+ set<string> public_import_names;
+ for (int i = 0; i < file_->public_dependency_count(); i++) {
+ public_import_names.insert(file_->public_dependency(i)->name());
+ }
for (int i = 0; i < file_->dependency_count(); i++) {
+ const string& name = file_->dependency(i)->name();
+ bool public_import = (public_import_names.count(name) != 0);
+
+
printer->Print(
- "#include \"$dependency$.pb.h\"\n",
- "dependency", StripProto(file_->dependency(i)->name()));
+ "#include \"$dependency$.pb.h\"$iwyu$\n",
+ "dependency", StripProto(name),
+ "iwyu", (public_import) ? " // IWYU pragma: export" : "");
}
printer->Print(
"// @@protoc_insertion_point(includes)\n");
+
// Open namespace.
GenerateNamespaceOpeners(printer);
@@ -162,7 +191,7 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
"// Internal implementation detail -- do not call these.\n"
"void $dllexport_decl$ $adddescriptorsname$();\n",
"adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
- "dllexport_decl", dllexport_decl_);
+ "dllexport_decl", options_.dllexport_decl);
printer->Print(
// Note that we don't put dllexport_decl on these because they are only
@@ -230,6 +259,7 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
printer->Print(kThickSeparator);
printer->Print("\n");
+
// Generate class inline methods.
for (int i = 0; i < file_->message_type_count(); i++) {
if (i > 0) {
@@ -282,20 +312,33 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
void FileGenerator::GenerateSource(io::Printer* printer) {
printer->Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
"\n"
+
// The generated code calls accessors that might be deprecated. We don't
// want the compiler to warn in generated code.
"#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n"
"#include \"$basename$.pb.h\"\n"
-
+ "\n"
+ "#include <algorithm>\n" // for swap()
+ "\n"
+ "#include <google/protobuf/stubs/common.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(),
"basename", StripProto(file_->name()));
+ // Unknown fields implementation in lite mode uses StringOutputStream
+ if (!UseUnknownFieldSet(file_) && file_->message_type_count() > 0) {
+ printer->Print(
+ "#include <google/protobuf/io/zero_copy_stream_impl_lite.h>\n");
+ }
+
if (HasDescriptorMethods(file_)) {
printer->Print(
"#include <google/protobuf/descriptor.h>\n"
+ "#include <google/protobuf/generated_message_reflection.h>\n"
"#include <google/protobuf/reflection_ops.h>\n"
"#include <google/protobuf/wire_format.h>\n");
}
@@ -378,11 +421,12 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// AddDescriptors() is a file-level procedure which adds the encoded
- // FileDescriptorProto for this .proto file to the global DescriptorPool
- // for generated files (DescriptorPool::generated_pool()). It always runs
- // at static initialization time, so all files will be registered before
- // main() starts. This procedure also constructs default instances and
- // registers extensions.
+ // FileDescriptorProto for this .proto file to the global DescriptorPool for
+ // generated files (DescriptorPool::generated_pool()). It either runs at
+ // static initialization time (by default) or when default_instance() is
+ // called for the first time (in LITE_RUNTIME mode with
+ // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also
+ // constructs default instances and registers extensions.
//
// Its sibling, AssignDescriptors(), actually pulls the compiled
// FileDescriptor from the DescriptorPool and uses it to populate all of
@@ -486,22 +530,29 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
printer->Outdent();
printer->Print(
- "}\n");
+ "}\n\n");
// -----------------------------------------------------------------
// Now generate the AddDescriptors() function.
- printer->Print(
- "\n"
+ 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"
- // We don't need any special synchronization here because this code is
- // called at static init time before any threads exist.
" 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();
// Call the AddDescriptors() methods for all of our dependencies, to make
@@ -509,17 +560,12 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
for (int i = 0; i < file_->dependency_count(); i++) {
const FileDescriptor* dependency = file_->dependency(i);
// Print the namespace prefix for the dependency.
- vector<string> dependency_package_parts;
- SplitStringUsing(dependency->package(), ".", &dependency_package_parts);
- printer->Print("::");
- for (int i = 0; i < dependency_package_parts.size(); i++) {
- printer->Print("$name$::",
- "name", dependency_package_parts[i]);
- }
+ string add_desc_name = QualifiedFileLevelSymbol(
+ dependency->package(), GlobalAddDescriptorsName(dependency->name()));
// Call its AddDescriptors function.
printer->Print(
"$name$();\n",
- "name", GlobalAddDescriptorsName(dependency->name()));
+ "name", add_desc_name);
}
if (HasDescriptorMethods(file_)) {
@@ -538,10 +584,12 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
static const int kBytesPerLine = 40;
for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
printer->Print("\n \"$data$\"",
- "data", CEscape(file_data.substr(i, kBytesPerLine)));
+ "data",
+ EscapeTrigraphs(
+ CEscape(file_data.substr(i, kBytesPerLine))));
}
printer->Print(
- ", $size$);\n",
+ ", $size$);\n",
"size", SimpleItoa(file_data.size()));
// Call MessageFactory::InternalRegisterGeneratedFile().
@@ -569,17 +617,26 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
"shutdownfilename", GlobalShutdownFileName(file_->name()));
printer->Outdent();
-
printer->Print(
"}\n"
- "\n"
+ "\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"
- "\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()));
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h
index b4e0128..4e4d8b6 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.h
+++ b/src/google/protobuf/compiler/cpp/cpp_file.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,10 +35,12 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
+#include <memory>
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/cpp/cpp_field.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
namespace google {
namespace protobuf {
@@ -61,7 +63,7 @@ class FileGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit FileGenerator(const FileDescriptor* file,
- const string& dllexport_decl);
+ const Options& options);
~FileGenerator();
void GenerateHeader(io::Printer* printer);
@@ -84,8 +86,7 @@ class FileGenerator {
// E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}.
vector<string> package_parts_;
-
- string dllexport_decl_;
+ 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 d67d350..75d558e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_generator.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,6 +35,7 @@
#include <google/protobuf/compiler/cpp/cpp_generator.h>
#include <vector>
+#include <memory>
#include <utility>
#include <google/protobuf/compiler/cpp/cpp_file.h>
@@ -53,7 +54,7 @@ CppGenerator::~CppGenerator() {}
bool CppGenerator::Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
string* error) const {
vector<pair<string, string> > options;
ParseGeneratorParameter(parameter, &options);
@@ -78,11 +79,13 @@ bool CppGenerator::Generate(const FileDescriptor* file,
// }
// FOO_EXPORT is a macro which should expand to __declspec(dllexport) or
// __declspec(dllimport) depending on what is being compiled.
- string dllexport_decl;
+ Options file_options;
for (int i = 0; i < options.size(); i++) {
if (options[i].first == "dllexport_decl") {
- dllexport_decl = options[i].second;
+ file_options.dllexport_decl = options[i].second;
+ } else if (options[i].first == "safe_boundary_check") {
+ file_options.safe_boundary_check = true;
} else {
*error = "Unknown generator option: " + options[i].first;
return false;
@@ -95,12 +98,12 @@ bool CppGenerator::Generate(const FileDescriptor* file,
string basename = StripProto(file->name());
basename.append(".pb");
- FileGenerator file_generator(file, dllexport_decl);
+ FileGenerator file_generator(file, file_options);
// Generate header.
{
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(basename + ".h"));
+ generator_context->Open(basename + ".h"));
io::Printer printer(output.get(), '$');
file_generator.GenerateHeader(&printer);
}
@@ -108,7 +111,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
// Generate cc file.
{
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(basename + ".cc"));
+ generator_context->Open(basename + ".cc"));
io::Printer printer(output.get(), '$');
file_generator.GenerateSource(&printer);
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.h b/src/google/protobuf/compiler/cpp/cpp_generator.h
index f52e886..3d517cf 100644
--- a/src/google/protobuf/compiler/cpp/cpp_generator.h
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -57,7 +57,7 @@ class LIBPROTOC_EXPORT CppGenerator : public CodeGenerator {
// implements CodeGenerator ----------------------------------------
bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
string* error) const;
private:
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index e3df88b..b7a47ac 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,10 +33,12 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <limits>
+#include <map>
#include <vector>
#include <google/protobuf/stubs/hash.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
@@ -80,6 +82,22 @@ hash_set<string> MakeKeywordsMap() {
hash_set<string> kKeywords = MakeKeywordsMap();
+// Returns whether the provided descriptor has an extension. This includes its
+// nested types.
+bool HasExtension(const Descriptor* descriptor) {
+ if (descriptor->extension_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+ if (HasExtension(descriptor->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
string UnderscoresToCamelCase(const string& input, bool cap_next_letter) {
string result;
// Note: I distrust ctype.h due to locales.
@@ -105,8 +123,6 @@ string UnderscoresToCamelCase(const string& input, bool cap_next_letter) {
return result;
}
-} // namespace
-
const char kThickSeparator[] =
"// ===================================================================\n";
const char kThinSeparator[] =
@@ -132,7 +148,7 @@ string ClassName(const Descriptor* descriptor, bool qualified) {
string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) {
if (enum_descriptor->containing_type() == NULL) {
if (qualified) {
- return DotsToColons(enum_descriptor->full_name());
+ return "::" + DotsToColons(enum_descriptor->full_name());
} else {
return enum_descriptor->name();
}
@@ -240,14 +256,35 @@ const char* DeclaredTypeMethodName(FieldDescriptor::Type type) {
return "";
}
+string Int32ToString(int number) {
+ // gcc rejects the decimal form of kint32min.
+ if (number == kint32min) {
+ GOOGLE_COMPILE_ASSERT(kint32min == (~0x7fffffff), kint32min_value_error);
+ return "(~0x7fffffff)";
+ } else {
+ return SimpleItoa(number);
+ }
+}
+
+string Int64ToString(int64 number) {
+ // gcc rejects the decimal form of kint64min
+ if (number == kint64min) {
+ // Make sure we are in a 2's complement system.
+ GOOGLE_COMPILE_ASSERT(kint64min == GOOGLE_LONGLONG(~0x7fffffffffffffff),
+ kint64min_value_error);
+ return "GOOGLE_LONGLONG(~0x7fffffffffffffff)";
+ }
+ return "GOOGLE_LONGLONG(" + SimpleItoa(number) + ")";
+}
+
string DefaultValue(const FieldDescriptor* field) {
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32:
- return SimpleItoa(field->default_value_int32());
+ return Int32ToString(field->default_value_int32());
case FieldDescriptor::CPPTYPE_UINT32:
return SimpleItoa(field->default_value_uint32()) + "u";
case FieldDescriptor::CPPTYPE_INT64:
- return "GOOGLE_LONGLONG(" + SimpleItoa(field->default_value_int64()) + ")";
+ return Int64ToString(field->default_value_int64());
case FieldDescriptor::CPPTYPE_UINT64:
return "GOOGLE_ULONGLONG(" + SimpleItoa(field->default_value_uint64())+ ")";
case FieldDescriptor::CPPTYPE_DOUBLE: {
@@ -290,9 +327,11 @@ string DefaultValue(const FieldDescriptor* field) {
return strings::Substitute(
"static_cast< $0 >($1)",
ClassName(field->enum_type(), true),
- field->default_value_enum()->number());
+ Int32ToString(field->default_value_enum()->number()));
case FieldDescriptor::CPPTYPE_STRING:
- return "\"" + CEscape(field->default_value_string()) + "\"";
+ return "\"" + EscapeTrigraphs(
+ CEscape(field->default_value_string())) +
+ "\"";
case FieldDescriptor::CPPTYPE_MESSAGE:
return FieldMessageTypeName(field) + "::default_instance()";
}
@@ -335,6 +374,120 @@ string GlobalShutdownFileName(const string& filename) {
return "protobuf_ShutdownFile_" + FilenameIdentifier(filename);
}
+// Return the qualified C++ name for a file level symbol.
+string QualifiedFileLevelSymbol(const string& package, const string& name) {
+ if (package.empty()) {
+ return StrCat("::", name);
+ }
+ return StrCat("::", DotsToColons(package), "::", name);
+}
+
+// Escape C++ trigraphs by escaping question marks to \?
+string EscapeTrigraphs(const string& to_escape) {
+ return StringReplace(to_escape, "?", "\\?", true);
+}
+
+// Escaped function name to eliminate naming conflict.
+string SafeFunctionName(const Descriptor* descriptor,
+ const FieldDescriptor* field,
+ const string& prefix) {
+ // Do not use FieldName() since it will escape keywords.
+ string name = field->name();
+ LowerString(&name);
+ string function_name = prefix + name;
+ if (descriptor->FindFieldByName(function_name)) {
+ // Single underscore will also make it conflicting with the private data
+ // member. We use double underscore to escape function names.
+ function_name.append("__");
+ } else if (kKeywords.count(name) > 0) {
+ // If the field name is a keyword, we append the underscore back to keep it
+ // consistent with other function names.
+ function_name.append("_");
+ }
+ return function_name;
+}
+
+bool StaticInitializersForced(const FileDescriptor* file) {
+ if (HasDescriptorMethods(file) || file->extension_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ if (HasExtension(file->message_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void PrintHandlingOptionalStaticInitializers(
+ const FileDescriptor* file, 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) {
+ map<string, string> vars;
+ if (var1) {
+ vars[var1] = val1;
+ }
+ if (var2) {
+ vars[var2] = val2;
+ }
+ PrintHandlingOptionalStaticInitializers(
+ vars, file, 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)) {
+ printer->Print(vars, with_static_init);
+ } else {
+ printer->Print(vars, (string(
+ "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n") +
+ without_static_init +
+ "#else\n" +
+ with_static_init +
+ "#endif\n").c_str());
+ }
+}
+
+
+static bool HasEnumDefinitions(const Descriptor* message_type) {
+ if (message_type->enum_type_count() > 0) return true;
+ for (int i = 0; i < message_type->nested_type_count(); ++i) {
+ if (HasEnumDefinitions(message_type->nested_type(i))) return true;
+ }
+ return false;
+}
+
+bool HasEnumDefinitions(const FileDescriptor* file) {
+ if (file->enum_type_count() > 0) return true;
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ if (HasEnumDefinitions(file->message_type(i))) return true;
+ }
+ return false;
+}
+
+bool IsStringOrMessage(const FieldDescriptor* field) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ case FieldDescriptor::CPPTYPE_INT64:
+ case FieldDescriptor::CPPTYPE_UINT32:
+ case FieldDescriptor::CPPTYPE_UINT64:
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ case FieldDescriptor::CPPTYPE_BOOL:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return false;
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return true;
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
} // namespace cpp
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
index f99b5fe..5d30240 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,12 +35,18 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
+#include <map>
#include <string>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
namespace google {
namespace protobuf {
+
+namespace io {
+class Printer;
+}
+
namespace compiler {
namespace cpp {
@@ -97,6 +103,12 @@ const char* PrimitiveTypeName(FieldDescriptor::CppType type);
// methods of WireFormat. For example, TYPE_INT32 becomes "Int32".
const char* DeclaredTypeMethodName(FieldDescriptor::Type type);
+// Return the code that evaluates to the number when compiled.
+string Int32ToString(int number);
+
+// Return the code that evaluates to the number when compiled.
+string Int64ToString(int64 number);
+
// Get code that evaluates to the field's default value.
string DefaultValue(const FieldDescriptor* field);
@@ -109,27 +121,43 @@ string GlobalAddDescriptorsName(const string& filename);
// Return the name of the AssignDescriptors() function for a given file.
string GlobalAssignDescriptorsName(const string& filename);
+// Return the qualified C++ name for a file level symbol.
+string QualifiedFileLevelSymbol(const string& package, const string& name);
+
// Return the name of the ShutdownFile() function for a given file.
string GlobalShutdownFileName(const string& filename);
-// Do message classes in this file keep track of unknown fields?
-inline bool HasUnknownFields(const FileDescriptor *file) {
+// Escape C++ trigraphs by escaping question marks to \?
+string EscapeTrigraphs(const string& to_escape);
+
+// Escaped function name to eliminate naming conflict.
+string SafeFunctionName(const Descriptor* descriptor,
+ const FieldDescriptor* field,
+ const string& prefix);
+
+// Do message classes in this file use UnknownFieldSet?
+// Otherwise, messages will store unknown fields in a string
+inline bool UseUnknownFieldSet(const FileDescriptor* file) {
return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
}
+
+// Does this file have any enum type definitions?
+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) {
+inline bool HasGeneratedMethods(const FileDescriptor* file) {
return file->options().optimize_for() != FileOptions::CODE_SIZE;
}
-// Do message classes in this file have descriptor and refelction methods?
-inline bool HasDescriptorMethods(const FileDescriptor *file) {
+// 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;
}
// Should we generate generic services for this file?
-inline bool HasGenericServices(const FileDescriptor *file) {
+inline bool HasGenericServices(const FileDescriptor* file) {
return file->service_count() > 0 &&
file->options().optimize_for() != FileOptions::LITE_RUNTIME &&
file->options().cc_generic_services();
@@ -147,6 +175,28 @@ inline bool HasFastArraySerialization(const FileDescriptor* file) {
return file->options().optimize_for() == FileOptions::SPEED;
}
+// Returns whether we have to generate code with static initializers.
+bool StaticInitializersForced(const FileDescriptor* file);
+
+// 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 char* with_static_init, const char* without_static_init,
+ 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);
+
+
+// Returns true if the field's CPPTYPE is string or message.
+bool IsStringOrMessage(const FieldDescriptor* field);
+
+string UnderscoresToCamelCase(const string& input, bool cap_next_letter);
} // namespace cpp
} // namespace compiler
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index cbdcce8..3a9d263 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,6 +35,9 @@
#include <algorithm>
#include <google/protobuf/stubs/hash.h>
#include <map>
+#include <memory>
+#include <set>
+#include <utility>
#include <vector>
#include <google/protobuf/compiler/cpp/cpp_message.h>
#include <google/protobuf/compiler/cpp/cpp_field.h>
@@ -47,6 +50,7 @@
#include <google/protobuf/wire_format.h>
#include <google/protobuf/descriptor.pb.h>
+
namespace google {
namespace protobuf {
namespace compiler {
@@ -72,15 +76,6 @@ struct FieldOrderingByNumber {
}
};
-const char* kWireTypeNames[] = {
- "VARINT",
- "FIXED64",
- "LENGTH_DELIMITED",
- "START_GROUP",
- "END_GROUP",
- "FIXED32",
-};
-
// Sort the fields of the given Descriptor by number into a new[]'d array
// and return it.
const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
@@ -102,6 +97,13 @@ struct ExtensionRangeSorter {
}
};
+// Returns true if the "required" restriction check should be ignored for the
+// given field.
+inline static bool ShouldIgnoreRequiredFieldCheck(
+ const FieldDescriptor* field) {
+ return false;
+}
+
// Returns true if the message type has any required fields. If it doesn't,
// we can optimize out calls to its IsInitialized() method.
//
@@ -128,7 +130,8 @@ static bool HasRequiredFields(
if (field->is_required()) {
return true;
}
- if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !ShouldIgnoreRequiredFieldCheck(field)) {
if (HasRequiredFields(field->message_type(), already_seen)) {
return true;
}
@@ -143,36 +146,171 @@ static bool HasRequiredFields(const Descriptor* type) {
return HasRequiredFields(type, &already_seen);
}
+// This returns an estimate of the compiler's alignment for the field. This
+// can't guarantee to be correct because the generated code could be compiled on
+// different systems with different alignment rules. The estimates below assume
+// 64-bit pointers.
+int EstimateAlignmentSize(const FieldDescriptor* field) {
+ if (field == NULL) return 0;
+ if (field->is_repeated()) return 8;
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return 1;
+
+ case FieldDescriptor::CPPTYPE_INT32:
+ case FieldDescriptor::CPPTYPE_UINT32:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return 4;
+
+ case FieldDescriptor::CPPTYPE_INT64:
+ case FieldDescriptor::CPPTYPE_UINT64:
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return 8;
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return -1; // Make compiler happy.
+}
+
+// FieldGroup is just a helper for OptimizePadding below. It holds a vector of
+// fields that are grouped together because they have compatible alignment, and
+// a preferred location in the final field ordering.
+class FieldGroup {
+ public:
+ FieldGroup()
+ : preferred_location_(0) {}
+
+ // A group with a single field.
+ FieldGroup(float preferred_location, const FieldDescriptor* field)
+ : preferred_location_(preferred_location),
+ fields_(1, field) {}
+
+ // Append the fields in 'other' to this group.
+ void Append(const FieldGroup& other) {
+ if (other.fields_.empty()) {
+ return;
+ }
+ // Preferred location is the average among all the fields, so we weight by
+ // the number of fields on each FieldGroup object.
+ preferred_location_ =
+ (preferred_location_ * fields_.size() +
+ (other.preferred_location_ * other.fields_.size())) /
+ (fields_.size() + other.fields_.size());
+ fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
+ }
+
+ void SetPreferredLocation(float location) { preferred_location_ = location; }
+ const vector<const FieldDescriptor*>& fields() const { return fields_; }
+
+ // FieldGroup objects sort by their preferred location.
+ bool operator<(const FieldGroup& other) const {
+ return preferred_location_ < other.preferred_location_;
+ }
+
+ private:
+ // "preferred_location_" is an estimate of where this group should go in the
+ // final list of fields. We compute this by taking the average index of each
+ // field in this group in the original ordering of fields. This is very
+ // approximate, but should put this group close to where its member fields
+ // originally went.
+ float preferred_location_;
+ vector<const FieldDescriptor*> fields_;
+ // We rely on the default copy constructor and operator= so this type can be
+ // used in a vector.
+};
+
+// Reorder 'fields' so that if the fields are output into a c++ class in the new
+// order, the alignment padding is minimized. We try to do this while keeping
+// each field as close as possible to its original position so that we don't
+// reduce cache locality much for function that access each field in order.
+void OptimizePadding(vector<const FieldDescriptor*>* fields) {
+ // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
+ vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8;
+ for (int i = 0; i < fields->size(); ++i) {
+ switch (EstimateAlignmentSize((*fields)[i])) {
+ case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break;
+ case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break;
+ case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break;
+ default:
+ GOOGLE_LOG(FATAL) << "Unknown alignment size.";
+ }
+ }
+
+ // Now group fields aligned to 1 byte into sets of 4, and treat those like a
+ // single field aligned to 4 bytes.
+ for (int i = 0; i < aligned_to_1.size(); i += 4) {
+ FieldGroup field_group;
+ for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) {
+ field_group.Append(aligned_to_1[j]);
+ }
+ aligned_to_4.push_back(field_group);
+ }
+ // Sort by preferred location to keep fields as close to their original
+ // location as possible. Using stable_sort ensures that the output is
+ // consistent across runs.
+ stable_sort(aligned_to_4.begin(), aligned_to_4.end());
+
+ // Now group fields aligned to 4 bytes (or the 4-field groups created above)
+ // into pairs, and treat those like a single field aligned to 8 bytes.
+ for (int i = 0; i < aligned_to_4.size(); i += 2) {
+ FieldGroup field_group;
+ for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) {
+ field_group.Append(aligned_to_4[j]);
+ }
+ if (i == aligned_to_4.size() - 1) {
+ // Move incomplete 4-byte block to the end.
+ field_group.SetPreferredLocation(fields->size() + 1);
+ }
+ aligned_to_8.push_back(field_group);
+ }
+ // Sort by preferred location.
+ stable_sort(aligned_to_8.begin(), aligned_to_8.end());
+
+ // Now pull out all the FieldDescriptors in order.
+ fields->clear();
+ for (int i = 0; i < aligned_to_8.size(); ++i) {
+ fields->insert(fields->end(),
+ aligned_to_8[i].fields().begin(),
+ aligned_to_8[i].fields().end());
+ }
+}
+
+string MessageTypeProtoName(const FieldDescriptor* field) {
+ return field->message_type()->full_name();
+}
+
}
// ===================================================================
MessageGenerator::MessageGenerator(const Descriptor* descriptor,
- const string& dllexport_decl)
- : descriptor_(descriptor),
- classname_(ClassName(descriptor, false)),
- dllexport_decl_(dllexport_decl),
- field_generators_(descriptor),
- nested_generators_(new scoped_ptr<MessageGenerator>[
- descriptor->nested_type_count()]),
- enum_generators_(new scoped_ptr<EnumGenerator>[
- descriptor->enum_type_count()]),
- extension_generators_(new scoped_ptr<ExtensionGenerator>[
- descriptor->extension_count()]) {
+ const Options& options)
+ : descriptor_(descriptor),
+ classname_(ClassName(descriptor, false)),
+ options_(options),
+ field_generators_(descriptor, options),
+ nested_generators_(new scoped_ptr<
+ MessageGenerator>[descriptor->nested_type_count()]),
+ enum_generators_(
+ new scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]),
+ extension_generators_(new scoped_ptr<
+ ExtensionGenerator>[descriptor->extension_count()]) {
for (int i = 0; i < descriptor->nested_type_count(); i++) {
nested_generators_[i].reset(
- new MessageGenerator(descriptor->nested_type(i), dllexport_decl));
+ new MessageGenerator(descriptor->nested_type(i), options));
}
for (int i = 0; i < descriptor->enum_type_count(); i++) {
enum_generators_[i].reset(
- new EnumGenerator(descriptor->enum_type(i), dllexport_decl));
+ new EnumGenerator(descriptor->enum_type(i), options));
}
for (int i = 0; i < descriptor->extension_count(); i++) {
extension_generators_[i].reset(
- new ExtensionGenerator(descriptor->extension(i), dllexport_decl));
+ new ExtensionGenerator(descriptor->extension(i), options));
}
}
@@ -217,7 +355,7 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) {
PrintFieldComment(printer, field);
map<string, string> vars;
- SetCommonFieldVariables(field, &vars);
+ SetCommonFieldVariables(field, &vars, options_);
vars["constant_name"] = FieldConstantName(field);
if (field->is_repeated()) {
@@ -242,6 +380,14 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) {
"GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
"classname", classname_);
}
+
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "inline $camel_oneof_name$Case $oneof_name$_case() const;\n",
+ "camel_oneof_name",
+ UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true),
+ "oneof_name", descriptor_->oneof_decl(i)->name());
+ }
}
void MessageGenerator::
@@ -254,7 +400,7 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) {
PrintFieldComment(printer, field);
map<string, string> vars;
- SetCommonFieldVariables(field, &vars);
+ SetCommonFieldVariables(field, &vars, options_);
// Generate has_$name$() or $name$_size().
if (field->is_repeated()) {
@@ -262,12 +408,34 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) {
"inline int $classname$::$name$_size() const {\n"
" return $name$_.size();\n"
"}\n");
+ } else if (field->containing_oneof()) {
+ // Singular field in a oneof
+ vars["field_name"] = UnderscoresToCamelCase(field->name(), true);
+ vars["oneof_name"] = field->containing_oneof()->name();
+ vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index());
+ printer->Print(vars,
+ "inline bool $classname$::has_$name$() const {\n"
+ " return $oneof_name$_case() == k$field_name$;\n"
+ "}\n"
+ "inline void $classname$::set_has_$name$() {\n"
+ " _oneof_case_[$oneof_index$] = k$field_name$;\n"
+ "}\n");
} else {
// Singular field.
+ char buffer[kFastToBufferSize];
+ vars["has_array_index"] = SimpleItoa(field->index() / 32);
+ vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer);
printer->Print(vars,
"inline bool $classname$::has_$name$() const {\n"
- " return _has_bit($index$);\n"
- "}\n");
+ " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
+ "}\n"
+ "inline void $classname$::set_has_$name$() {\n"
+ " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n"
+ "}\n"
+ "inline void $classname$::clear_has_$name$() {\n"
+ " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"
+ "}\n"
+ );
}
// Generate clear_$name$()
@@ -275,13 +443,27 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) {
"inline void $classname$::clear_$name$() {\n");
printer->Indent();
- field_generators_.get(field).GenerateClearingCode(printer);
- printer->Outdent();
- if (!field->is_repeated()) {
- printer->Print(vars, " _clear_bit($index$);\n");
+ if (field->containing_oneof()) {
+ // Clear this field only if it is the active field in this oneof,
+ // otherwise ignore
+ printer->Print(vars,
+ "if (has_$name$()) {\n");
+ printer->Indent();
+ field_generators_.get(field).GenerateClearingCode(printer);
+ printer->Print(vars,
+ "clear_has_$oneof_name$();\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ } else {
+ field_generators_.get(field).GenerateClearingCode(printer);
+ if (!field->is_repeated()) {
+ printer->Print(vars,
+ "clear_has_$name$();\n");
+ }
}
+ printer->Outdent();
printer->Print("}\n");
// Generate type-specific accessors.
@@ -289,6 +471,49 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) {
printer->Print("\n");
}
+
+ // Generate has_$name$() and clear_has_$name$() functions for oneofs
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ map<string, string> vars;
+ vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
+ vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
+ vars["cap_oneof_name"] =
+ ToUpper(descriptor_->oneof_decl(i)->name());
+ vars["classname"] = classname_;
+ printer->Print(
+ vars,
+ "inline bool $classname$::has_$oneof_name$() {\n"
+ " return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
+ "}\n"
+ "inline void $classname$::clear_has_$oneof_name$() {\n"
+ " _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
+ "}\n");
+ }
+}
+
+// Helper for the code that emits the Clear() method.
+static bool CanClearByZeroing(const FieldDescriptor* field) {
+ if (field->is_repeated() || field->is_extension()) return false;
+ switch (field->cpp_type()) {
+ case internal::WireFormatLite::CPPTYPE_ENUM:
+ return field->default_value_enum()->number() == 0;
+ case internal::WireFormatLite::CPPTYPE_INT32:
+ return field->default_value_int32() == 0;
+ case internal::WireFormatLite::CPPTYPE_INT64:
+ return field->default_value_int64() == 0;
+ case internal::WireFormatLite::CPPTYPE_UINT32:
+ return field->default_value_uint32() == 0;
+ case internal::WireFormatLite::CPPTYPE_UINT64:
+ return field->default_value_uint64() == 0;
+ case internal::WireFormatLite::CPPTYPE_FLOAT:
+ return field->default_value_float() == 0;
+ case internal::WireFormatLite::CPPTYPE_DOUBLE:
+ return field->default_value_double() == 0;
+ case internal::WireFormatLite::CPPTYPE_BOOL:
+ return field->default_value_bool() == false;
+ default:
+ return false;
+ }
}
void MessageGenerator::
@@ -303,10 +528,11 @@ GenerateClassDefinition(io::Printer* printer) {
map<string, string> vars;
vars["classname"] = classname_;
vars["field_count"] = SimpleItoa(descriptor_->field_count());
- if (dllexport_decl_.empty()) {
+ vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count());
+ if (options_.dllexport_decl.empty()) {
vars["dllexport"] = "";
} else {
- vars["dllexport"] = dllexport_decl_ + " ";
+ vars["dllexport"] = options_.dllexport_decl + " ";
}
vars["superclass"] = SuperClassName(descriptor_);
@@ -327,7 +553,7 @@ GenerateClassDefinition(io::Printer* printer) {
"}\n"
"\n");
- if (HasUnknownFields(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file())) {
printer->Print(
"inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
" return _unknown_fields_;\n"
@@ -337,6 +563,16 @@ GenerateClassDefinition(io::Printer* printer) {
" return &_unknown_fields_;\n"
"}\n"
"\n");
+ } else {
+ printer->Print(
+ "inline const ::std::string& unknown_fields() const {\n"
+ " return _unknown_fields_;\n"
+ "}\n"
+ "\n"
+ "inline ::std::string* mutable_unknown_fields() {\n"
+ " return &_unknown_fields_;\n"
+ "}\n"
+ "\n");
}
// Only generate this member if it's not disabled.
@@ -350,6 +586,47 @@ GenerateClassDefinition(io::Printer* printer) {
"static const $classname$& default_instance();\n"
"\n");
+ // Generate enum values for every field in oneofs. One list is generated for
+ // each oneof with an additional *_NOT_SET value.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "enum $camel_oneof_name$Case {\n",
+ "camel_oneof_name",
+ UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
+ printer->Indent();
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ printer->Print(
+ "k$field_name$ = $field_number$,\n",
+ "field_name",
+ UnderscoresToCamelCase(
+ descriptor_->oneof_decl(i)->field(j)->name(), true),
+ "field_number",
+ SimpleItoa(descriptor_->oneof_decl(i)->field(j)->number()));
+ }
+ printer->Print(
+ "$cap_oneof_name$_NOT_SET = 0,\n",
+ "cap_oneof_name",
+ ToUpper(descriptor_->oneof_decl(i)->name()));
+ printer->Outdent();
+ printer->Print(
+ "};\n"
+ "\n");
+ }
+
+ if (!StaticInitializersForced(descriptor_->file())) {
+ printer->Print(vars,
+ "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
+ "// Returns the internal default instance pointer. This function can\n"
+ "// return NULL thus should not be used by the user. This is intended\n"
+ "// for Protobuf internal code. Please use default_instance() declared\n"
+ "// above instead.\n"
+ "static inline const $classname$* internal_default_instance() {\n"
+ " return default_instance_;\n"
+ "}\n"
+ "#endif\n"
+ "\n");
+ }
+
printer->Print(vars,
"void Swap($classname$* other);\n"
@@ -379,20 +656,50 @@ GenerateClassDefinition(io::Printer* printer) {
" ::google::protobuf::io::CodedInputStream* input);\n"
"void SerializeWithCachedSizes(\n"
" ::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())) {
+ printer->Print(
+ "void DiscardUnknownFields();\n");
+ }
if (HasFastArraySerialization(descriptor_->file())) {
printer->Print(
"::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
}
}
- printer->Print(vars,
+ // Check all FieldDescriptors including those in oneofs to estimate
+ // whether ::std::string is likely to be used, and depending on that
+ // estimate, set uses_string_ to true or false. That contols
+ // whether to force initialization of empty_string_ in SharedCtor().
+ // It's often advantageous to do so to keep "is empty_string_
+ // inited?" code from appearing all over the place.
+ vector<const FieldDescriptor*> descriptors;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ descriptors.push_back(descriptor_->field(i));
+ }
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ descriptors.push_back(descriptor_->oneof_decl(i)->field(j));
+ }
+ }
+ uses_string_ = false;
+ for (int i = 0; i < descriptors.size(); i++) {
+ const FieldDescriptor* field = descriptors[i];
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ switch (field->options().ctype()) {
+ default: uses_string_ = true; break;
+ }
+ }
+ }
+
+ printer->Print(
"int GetCachedSize() const { return _cached_size_; }\n"
"private:\n"
"void SharedCtor();\n"
"void SharedDtor();\n"
"void SetCachedSize(int size) const;\n"
- "public:\n"
- "\n");
+ "public:\n");
if (HasDescriptorMethods(descriptor_->file())) {
printer->Print(
@@ -444,38 +751,172 @@ GenerateClassDefinition(io::Printer* printer) {
"// @@protoc_insertion_point(class_scope:$full_name$)\n",
"full_name", descriptor_->full_name());
- // Generate private members for fields.
+ // Generate private members.
printer->Outdent();
printer->Print(" private:\n");
printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!descriptor_->field(i)->is_repeated()) {
+ printer->Print(
+ "inline void set_has_$name$();\n",
+ "name", FieldName(descriptor_->field(i)));
+ if (!descriptor_->field(i)->containing_oneof()) {
+ printer->Print(
+ "inline void clear_has_$name$();\n",
+ "name", FieldName(descriptor_->field(i)));
+ }
+ }
+ }
+ printer->Print("\n");
+
+ // Generate oneof function declarations
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "inline bool has_$oneof_name$();\n"
+ "void clear_$oneof_name$();\n"
+ "inline void clear_has_$oneof_name$();\n\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name());
+ }
+
+ // Prepare decls for _cached_size_ and _has_bits_. Their position in the
+ // output will be determined later.
+
+ bool need_to_emit_cached_size = true;
+ // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it.
+ const string cached_size_decl = "mutable int _cached_size_;\n";
+
+ // TODO(jieluo) - Optimize _has_bits_ for repeated and oneof fields.
+ size_t sizeof_has_bits = (descriptor_->field_count() + 31) / 32 * 4;
+ if (descriptor_->field_count() == 0) {
+ // Zero-size arrays aren't technically allowed, and MSVC in particular
+ // doesn't like them. We still need to declare these arrays to make
+ // other code compile. Since this is an uncommon case, we'll just declare
+ // them with size 1 and waste some space. Oh well.
+ sizeof_has_bits = 4;
+ }
+ const string has_bits_decl = sizeof_has_bits == 0 ? "" :
+ "::google::protobuf::uint32 _has_bits_[" + SimpleItoa(sizeof_has_bits / 4) + "];\n";
+
+
+ // To minimize padding, data members are divided into three sections:
+ // (1) members assumed to align to 8 bytes
+ // (2) members corresponding to message fields, re-ordered to optimize
+ // alignment.
+ // (3) members assumed to align to 4 bytes.
+
+ // Members assumed to align to 8 bytes:
+
if (descriptor_->extension_range_count() > 0) {
printer->Print(
- "::google::protobuf::internal::ExtensionSet _extensions_;\n");
+ "::google::protobuf::internal::ExtensionSet _extensions_;\n"
+ "\n");
}
- if (HasUnknownFields(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file())) {
printer->Print(
- "::google::protobuf::UnknownFieldSet _unknown_fields_;\n");
+ "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
+ "\n");
+ } else {
+ printer->Print(
+ "::std::string _unknown_fields_;\n"
+ "\n");
}
- // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it.
- printer->Print(
- "mutable int _cached_size_;\n"
- "\n");
+ // _has_bits_ is frequently accessed, so to reduce code size and improve
+ // speed, it should be close to the start of the object. But, try not to
+ // waste space:_has_bits_ by itself always makes sense if its size is a
+ // multiple of 8, but, otherwise, maybe _has_bits_ and cached_size_ together
+ // will work well.
+ printer->Print(has_bits_decl.c_str());
+ if ((sizeof_has_bits % 8) != 0) {
+ printer->Print(cached_size_decl.c_str());
+ need_to_emit_cached_size = false;
+ }
+
+ // Field members:
+
+ // List fields which doesn't belong to any oneof
+ vector<const FieldDescriptor*> fields;
+ hash_map<string, int> fieldname_to_chunk;
for (int i = 0; i < descriptor_->field_count(); i++) {
- field_generators_.get(descriptor_->field(i))
- .GeneratePrivateMembers(printer);
+ if (!descriptor_->field(i)->containing_oneof()) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ fields.push_back(field);
+ fieldname_to_chunk[FieldName(field)] = i / 8;
+ }
+ }
+ OptimizePadding(&fields);
+ // Emit some private and static members
+ runs_of_fields_ = vector< vector<string> >(1);
+ for (int i = 0; i < fields.size(); ++i) {
+ const FieldDescriptor* field = fields[i];
+ const FieldGenerator& generator = field_generators_.get(field);
+ generator.GenerateStaticMembers(printer);
+ generator.GeneratePrivateMembers(printer);
+ if (CanClearByZeroing(field)) {
+ const string& fieldname = FieldName(field);
+ if (!runs_of_fields_.back().empty() &&
+ (fieldname_to_chunk[runs_of_fields_.back().back()] !=
+ fieldname_to_chunk[fieldname])) {
+ runs_of_fields_.push_back(vector<string>());
+ }
+ runs_of_fields_.back().push_back(fieldname);
+ } else if (!runs_of_fields_.back().empty()) {
+ runs_of_fields_.push_back(vector<string>());
+ }
+ }
+
+ // For each oneof generate a union
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "union $camel_oneof_name$Union {\n",
+ "camel_oneof_name",
+ UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
+ printer->Indent();
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ field_generators_.get(descriptor_->oneof_decl(i)->
+ field(j)).GeneratePrivateMembers(printer);
+ }
+ printer->Outdent();
+ printer->Print(
+ "} $oneof_name$_;\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name());
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ field_generators_.get(descriptor_->oneof_decl(i)->
+ field(j)).GenerateStaticMembers(printer);
+ }
+ }
+
+ // Members assumed to align to 4 bytes:
+
+ if (need_to_emit_cached_size) {
+ printer->Print(cached_size_decl.c_str());
+ need_to_emit_cached_size = false;
+ }
+
+ // Generate _oneof_case_.
+ if (descriptor_->oneof_decl_count() > 0) {
+ printer->Print(vars,
+ "::google::protobuf::uint32 _oneof_case_[$oneof_decl_count$];\n"
+ "\n");
}
// Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
// friends so that they can access private static variables like
// default_instance_ and reflection_.
- printer->Print(
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
"friend void $dllexport_decl$ $adddescriptorsname$();\n",
- "dllexport_decl", dllexport_decl_,
+ // Without.
+ "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
+ // Vars.
+ "dllexport_decl", options_.dllexport_decl,
"adddescriptorsname",
- GlobalAddDescriptorsName(descriptor_->file()->name()));
+ GlobalAddDescriptorsName(descriptor_->file()->name()));
+
printer->Print(
"friend void $assigndescriptorsname$();\n"
"friend void $shutdownfilename$();\n"
@@ -484,38 +925,14 @@ GenerateClassDefinition(io::Printer* printer) {
GlobalAssignDescriptorsName(descriptor_->file()->name()),
"shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
- // Generate offsets and _has_bits_ boilerplate.
- if (descriptor_->field_count() > 0) {
- printer->Print(vars,
- "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n");
- } else {
- // Zero-size arrays aren't technically allowed, and MSVC in particular
- // doesn't like them. We still need to declare these arrays to make
- // other code compile. Since this is an uncommon case, we'll just declare
- // them with size 1 and waste some space. Oh well.
- printer->Print(
- "::google::protobuf::uint32 _has_bits_[1];\n");
- }
-
printer->Print(
- "\n"
- "// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?\n"
- "inline bool _has_bit(int index) const {\n"
- " return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;\n"
- "}\n"
- "inline void _set_bit(int index) {\n"
- " _has_bits_[index / 32] |= (1u << (index % 32));\n"
- "}\n"
- "inline void _clear_bit(int index) {\n"
- " _has_bits_[index / 32] &= ~(1u << (index % 32));\n"
- "}\n"
- "\n"
"void InitAsDefaultInstance();\n"
"static $classname$* default_instance_;\n",
"classname", classname_);
printer->Outdent();
printer->Print(vars, "};");
+ GOOGLE_DCHECK(!need_to_emit_cached_size);
}
void MessageGenerator::
@@ -527,6 +944,23 @@ GenerateInlineMethods(io::Printer* printer) {
}
GenerateFieldAccessorDefinitions(printer);
+
+ // Generate oneof_case() functions.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ map<string, string> vars;
+ vars["class_name"] = classname_;
+ vars["camel_oneof_name"] = UnderscoresToCamelCase(
+ descriptor_->oneof_decl(i)->name(), true);
+ vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
+ vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
+ printer->Print(
+ vars,
+ "inline $class_name$::$camel_oneof_name$Case $class_name$::"
+ "$oneof_name$_case() const {\n"
+ " return $class_name$::$camel_oneof_name$Case("
+ "_oneof_case_[$oneof_index$]);\n"
+ "}\n");
+ }
}
void MessageGenerator::
@@ -537,6 +971,25 @@ GenerateDescriptorDeclarations(io::Printer* printer) {
" $name$_reflection_ = NULL;\n",
"name", classname_);
+ // Generate oneof default instance for reflection usage.
+ if (descriptor_->oneof_decl_count() > 0) {
+ printer->Print("struct $name$OneofInstance {\n",
+ "name", classname_);
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+ printer->Print(" ");
+ if (IsStringOrMessage(field)) {
+ printer->Print("const ");
+ }
+ field_generators_.get(field).GeneratePrivateMembers(printer);
+ }
+ }
+
+ printer->Print("}* $name$_default_oneof_instance_ = NULL;\n",
+ "name", classname_);
+ }
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->GenerateDescriptorDeclarations(printer);
}
@@ -589,9 +1042,19 @@ GenerateDescriptorInitializer(io::Printer* printer, int index) {
printer->Print(vars,
" -1,\n");
}
+
+ if (descriptor_->oneof_decl_count() > 0) {
+ printer->Print(vars,
+ " $classname$_default_oneof_instance_,\n"
+ " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
+ "$classname$, _oneof_case_[0]),\n");
+ }
+
+ printer->Print(
+ " ::google::protobuf::DescriptorPool::generated_pool(),\n");
+ printer->Print(vars,
+ " ::google::protobuf::MessageFactory::generated_factory(),\n");
printer->Print(vars,
- " ::google::protobuf::DescriptorPool::generated_pool(),\n"
- " ::google::protobuf::MessageFactory::generated_factory(),\n"
" sizeof($classname$));\n");
// Handle nested types.
@@ -620,6 +1083,13 @@ GenerateTypeRegistrations(io::Printer* printer) {
void MessageGenerator::
GenerateDefaultInstanceAllocator(io::Printer* printer) {
+ // Construct the default instances of all fields, as they will be used
+ // when creating the default instance of the entire message.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateDefaultInstanceAllocator(printer);
+ }
+
// Construct the default instance. We can't call InitAsDefaultInstance() yet
// because we need to make sure all default instances that this one might
// depend on are constructed first.
@@ -627,6 +1097,13 @@ GenerateDefaultInstanceAllocator(io::Printer* printer) {
"$classname$::default_instance_ = new $classname$();\n",
"classname", classname_);
+ if ((descriptor_->oneof_decl_count() > 0) &&
+ HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(
+ "$classname$_default_oneof_instance_ = new $classname$OneofInstance;\n",
+ "classname", classname_);
+ }
+
// Handle nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
@@ -658,11 +1135,22 @@ GenerateShutdownCode(io::Printer* printer) {
"classname", classname_);
if (HasDescriptorMethods(descriptor_->file())) {
+ if (descriptor_->oneof_decl_count() > 0) {
+ printer->Print(
+ "delete $classname$_default_oneof_instance_;\n",
+ "classname", classname_);
+ }
printer->Print(
"delete $classname$_reflection_;\n",
"classname", classname_);
}
+ // Handle default instances of fields.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateShutdownCode(printer);
+ }
+
// Handle nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->GenerateShutdownCode(printer);
@@ -709,6 +1197,11 @@ GenerateClassMethods(io::Printer* printer) {
GenerateStructors(printer);
printer->Print("\n");
+ if (descriptor_->oneof_decl_count() > 0) {
+ GenerateOneofClear(printer);
+ printer->Print("\n");
+ }
+
if (HasGeneratedMethods(descriptor_->file())) {
GenerateClear(printer);
printer->Print("\n");
@@ -768,15 +1261,33 @@ GenerateOffsets(io::Printer* printer) {
printer->Print(
"static const int $classname$_offsets_[$field_count$] = {\n",
"classname", classname_,
- "field_count", SimpleItoa(max(1, descriptor_->field_count())));
+ "field_count", SimpleItoa(max(
+ 1, descriptor_->field_count() + descriptor_->oneof_decl_count())));
printer->Indent();
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
+ if (field->containing_oneof()) {
+ printer->Print(
+ "PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET("
+ "$classname$_default_oneof_instance_, $name$_),\n",
+ "classname", classname_,
+ "name", FieldName(field));
+ } else {
+ printer->Print(
+ "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
+ "$name$_),\n",
+ "classname", classname_,
+ "name", FieldName(field));
+ }
+ }
+
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
printer->Print(
"GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
"classname", classname_,
- "name", FieldName(field));
+ "name", oneof->name());
}
printer->Outdent();
@@ -790,17 +1301,26 @@ GenerateSharedConstructorCode(io::Printer* printer) {
"classname", classname_);
printer->Indent();
- printer->Print(
- "_cached_size_ = 0;\n");
+ printer->Print(StrCat(
+ uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "",
+ "_cached_size_ = 0;\n").c_str());
for (int i = 0; i < descriptor_->field_count(); i++) {
- field_generators_.get(descriptor_->field(i))
- .GenerateConstructorCode(printer);
+ if (!descriptor_->field(i)->containing_oneof()) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateConstructorCode(printer);
+ }
}
printer->Print(
"::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "clear_has_$oneof_name$();\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name());
+ }
+
printer->Outdent();
printer->Print("}\n\n");
}
@@ -811,14 +1331,29 @@ GenerateSharedDestructorCode(io::Printer* printer) {
"void $classname$::SharedDtor() {\n",
"classname", classname_);
printer->Indent();
- // Write the destructors for each field.
+ // Write the destructors for each field except oneof members.
for (int i = 0; i < descriptor_->field_count(); i++) {
- field_generators_.get(descriptor_->field(i))
- .GenerateDestructorCode(printer);
+ if (!descriptor_->field(i)->containing_oneof()) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateDestructorCode(printer);
+ }
}
- printer->Print(
- "if (this != default_instance_) {\n");
+ // Generate code to destruct oneofs. Clearing should do the work.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "if (has_$oneof_name$()) {\n"
+ " clear_$oneof_name$();\n"
+ "}\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name());
+ }
+
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), 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
@@ -829,8 +1364,12 @@ GenerateSharedDestructorCode(io::Printer* printer) {
if (!field->is_repeated() &&
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- printer->Print(" delete $name$_;\n",
- "name", FieldName(field));
+ // Skip oneof members
+ if (!field->containing_oneof()) {
+ printer->Print(
+ " delete $name$_;\n",
+ "name", FieldName(field));
+ }
}
}
@@ -850,9 +1389,11 @@ GenerateStructors(io::Printer* printer) {
"$classname$::$classname$()\n"
" : $superclass$() {\n"
" SharedCtor();\n"
+ " // @@protoc_insertion_point(constructor:$full_name$)\n"
"}\n",
"classname", classname_,
- "superclass", superclass);
+ "superclass", superclass,
+ "full_name", descriptor_->full_name());
printer->Print(
"\n"
@@ -869,11 +1410,28 @@ GenerateStructors(io::Printer* printer) {
const FieldDescriptor* field = descriptor_->field(i);
if (!field->is_repeated() &&
- field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- printer->Print(
- " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
- "name", FieldName(field),
- "type", FieldMessageTypeName(field));
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ (field->containing_oneof() == NULL ||
+ HasDescriptorMethods(descriptor_->file()))) {
+ 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));
+ } else if (field->containing_oneof() &&
+ HasDescriptorMethods(descriptor_->file())) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateConstructorCode(printer);
}
}
printer->Print(
@@ -886,10 +1444,12 @@ GenerateStructors(io::Printer* printer) {
" : $superclass$() {\n"
" SharedCtor();\n"
" MergeFrom(from);\n"
+ " // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
"}\n"
"\n",
"classname", classname_,
- "superclass", superclass);
+ "superclass", superclass,
+ "full_name", descriptor_->full_name());
// Generate the shared constructor code.
GenerateSharedConstructorCode(printer);
@@ -897,10 +1457,12 @@ GenerateStructors(io::Printer* printer) {
// Generate the destructor.
printer->Print(
"$classname$::~$classname$() {\n"
+ " // @@protoc_insertion_point(destructor:$full_name$)\n"
" SharedDtor();\n"
"}\n"
"\n",
- "classname", classname_);
+ "classname", classname_,
+ "full_name", descriptor_->full_name());
// Generate the shared destructor code.
GenerateSharedDestructorCode(printer);
@@ -929,86 +1491,178 @@ GenerateStructors(io::Printer* printer) {
}
printer->Print(
- "const $classname$& $classname$::default_instance() {\n"
- " if (default_instance_ == NULL) $adddescriptorsname$();"
+ "const $classname$& $classname$::default_instance() {\n",
+ "classname", classname_);
+
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), 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"
"}\n"
"\n"
"$classname$* $classname$::default_instance_ = NULL;\n"
- "\n"
+ "\n",
+ "classname", classname_);
+
+ printer->Print(
"$classname$* $classname$::New() const {\n"
" return new $classname$;\n"
"}\n",
- "classname", classname_,
- "adddescriptorsname",
- GlobalAddDescriptorsName(descriptor_->file()->name()));
+ "classname", classname_);
}
+// Return the number of bits set in n, a non-negative integer.
+static int popcnt(uint32 n) {
+ int result = 0;
+ while (n != 0) {
+ result += (n & 1);
+ n = n / 2;
+ }
+ return result;
+}
+
void MessageGenerator::
GenerateClear(io::Printer* printer) {
printer->Print("void $classname$::Clear() {\n",
"classname", classname_);
printer->Indent();
- int last_index = -1;
-
+ // Step 1: Extensions
if (descriptor_->extension_range_count() > 0) {
printer->Print("_extensions_.Clear();\n");
}
+ // Step 2: Everything but extensions, repeateds, unions.
+ // These are handled in chunks of 8. The first chunk is
+ // the non-extensions-non-repeateds-non-unions in
+ // descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7),
+ // and the second chunk is the same for
+ // descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15),
+ // etc.
+ set<int> step2_indices;
+ hash_map<string, int> fieldname_to_chunk;
+ hash_map<int, string> memsets_for_chunk;
+ hash_map<int, int> memset_field_count_for_chunk;
+ hash_set<string> handled; // fields that appear anywhere in memsets_for_chunk
+ hash_map<int, uint32> fields_mask_for_chunk;
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
+ if (!field->is_repeated() && !field->containing_oneof()) {
+ step2_indices.insert(i);
+ int chunk = i / 8;
+ fieldname_to_chunk[FieldName(field)] = chunk;
+ fields_mask_for_chunk[chunk] |= static_cast<uint32>(1) << (i % 32);
+ }
+ }
- if (!field->is_repeated()) {
- map<string, string> vars;
- vars["index"] = SimpleItoa(field->index());
-
- // We can use the fact that _has_bits_ is a giant bitfield to our
- // advantage: We can check up to 32 bits at a time for equality to
- // zero, and skip the whole range if so. This can improve the speed
- // of Clear() for messages which contain a very large number of
- // optional fields of which only a few are used at a time. Here,
- // we've chosen to check 8 bits at a time rather than 32.
- if (i / 8 != last_index / 8 || last_index < 0) {
- if (last_index >= 0) {
- printer->Outdent();
- printer->Print("}\n");
- }
- printer->Print(vars,
- "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n");
- printer->Indent();
+ // Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0.
+ // The generated code uses two macros to help it clear runs of fields:
+ // OFFSET_OF_FIELD_ computes the offset (in bytes) of a field in the Message.
+ // ZR_ zeroes a non-empty range of fields via memset.
+ const char* macros =
+ "#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \\\n"
+ " &reinterpret_cast<$classname$*>(16)->f) - \\\n"
+ " reinterpret_cast<char*>(16))\n\n"
+ "#define ZR_(first, last) do { \\\n"
+ " size_t f = OFFSET_OF_FIELD_(first); \\\n"
+ " size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \\\n"
+ " ::memset(&first, 0, n); \\\n"
+ " } while (0)\n\n";
+ for (int i = 0; i < runs_of_fields_.size(); i++) {
+ const vector<string>& run = runs_of_fields_[i];
+ if (run.size() < 2) continue;
+ const string& first_field_name = run[0];
+ const string& last_field_name = run.back();
+ int chunk = fieldname_to_chunk[run[0]];
+ memsets_for_chunk[chunk].append(
+ "ZR_(" + first_field_name + "_, " + last_field_name + "_);\n");
+ for (int j = 0; j < run.size(); j++) {
+ GOOGLE_DCHECK_EQ(chunk, fieldname_to_chunk[run[j]]);
+ handled.insert(run[j]);
+ }
+ memset_field_count_for_chunk[chunk] += run.size();
+ }
+ const bool macros_are_needed = handled.size() > 0;
+ if (macros_are_needed) {
+ printer->Outdent();
+ printer->Print(macros,
+ "classname", classname_);
+ printer->Indent();
+ }
+ // Step 2b: Finish step 2, ignoring fields handled in step 2a.
+ int last_index = -1;
+ bool chunk_block_in_progress = false;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (step2_indices.count(i) == 0) continue;
+ const FieldDescriptor* field = descriptor_->field(i);
+ const string fieldname = FieldName(field);
+ if (i / 8 != last_index / 8 || last_index < 0) {
+ // End previous chunk, if there was one.
+ if (chunk_block_in_progress) {
+ printer->Outdent();
+ printer->Print("}\n");
+ chunk_block_in_progress = false;
}
- last_index = i;
-
- // It's faster to just overwrite primitive types, but we should
- // only clear strings and messages if they were set.
- // TODO(kenton): Let the CppFieldGenerator decide this somehow.
- bool should_check_bit =
- field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
- field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
-
- if (should_check_bit) {
- printer->Print(vars, "if (_has_bit($index$)) {\n");
+ // Start chunk.
+ const string& memsets = memsets_for_chunk[i / 8];
+ uint32 mask = fields_mask_for_chunk[i / 8];
+ int count = popcnt(mask);
+ if (count == 1 ||
+ (count <= 4 && count == memset_field_count_for_chunk[i / 8])) {
+ // No "if" here because the chunk is trivial.
+ } else {
+ printer->Print(
+ "if (_has_bits_[$index$ / 32] & $mask$) {\n",
+ "index", SimpleItoa(i / 8 * 8),
+ "mask", SimpleItoa(mask));
printer->Indent();
+ chunk_block_in_progress = true;
}
+ printer->Print(memsets.c_str());
+ }
+ last_index = i;
+ if (handled.count(fieldname) > 0) continue;
+
+ // It's faster to just overwrite primitive types, but we should
+ // only clear strings and messages if they were set.
+ // TODO(kenton): Let the CppFieldGenerator decide this somehow.
+ bool should_check_bit =
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
+ field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
+
+ if (should_check_bit) {
+ printer->Print("if (has_$name$()) {\n", "name", fieldname);
+ printer->Indent();
+ }
- field_generators_.get(field).GenerateClearingCode(printer);
+ field_generators_.get(field).GenerateClearingCode(printer);
- if (should_check_bit) {
- printer->Outdent();
- printer->Print("}\n");
- }
+ if (should_check_bit) {
+ printer->Outdent();
+ printer->Print("}\n");
}
}
- if (last_index >= 0) {
+ if (chunk_block_in_progress) {
printer->Outdent();
printer->Print("}\n");
}
+ if (macros_are_needed) {
+ printer->Outdent();
+ printer->Print("\n#undef OFFSET_OF_FIELD_\n#undef ZR_\n\n");
+ printer->Indent();
+ }
- // Repeated fields don't use _has_bits_ so we clear them in a separate
- // pass.
+ // Step 3: Repeated fields don't use _has_bits_; emit code to clear them here.
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
@@ -1017,12 +1671,23 @@ GenerateClear(io::Printer* printer) {
}
}
+ // Step 4: Unions.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "clear_$oneof_name$();\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name());
+ }
+
+ // Step 5: Everything else.
printer->Print(
"::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
- if (HasUnknownFields(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file())) {
printer->Print(
"mutable_unknown_fields()->Clear();\n");
+ } else {
+ printer->Print(
+ "mutable_unknown_fields()->clear();\n");
}
printer->Outdent();
@@ -1030,6 +1695,58 @@ GenerateClear(io::Printer* printer) {
}
void MessageGenerator::
+GenerateOneofClear(io::Printer* printer) {
+ // Generated function clears the active field and union case (e.g. foo_case_).
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "void $classname$::clear_$oneofname$() {\n",
+ "classname", classname_,
+ "oneofname", descriptor_->oneof_decl(i)->name());
+ printer->Indent();
+ printer->Print(
+ "switch($oneofname$_case()) {\n",
+ "oneofname", 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(
+ "case k$field_name$: {\n",
+ "field_name", UnderscoresToCamelCase(field->name(), true));
+ printer->Indent();
+ // We clear only allocated objects in oneofs
+ if (!IsStringOrMessage(field)) {
+ printer->Print(
+ "// No need to clear\n");
+ } else {
+ field_generators_.get(field).GenerateClearingCode(printer);
+ }
+ printer->Print(
+ "break;\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+ printer->Print(
+ "case $cap_oneof_name$_NOT_SET: {\n"
+ " break;\n"
+ "}\n",
+ "cap_oneof_name",
+ ToUpper(descriptor_->oneof_decl(i)->name()));
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n",
+ "oneof_index", SimpleItoa(i),
+ "cap_oneof_name",
+ ToUpper(descriptor_->oneof_decl(i)->name()));
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+ }
+}
+
+void MessageGenerator::
GenerateSwap(io::Printer* printer) {
// Generate the Swap member function.
printer->Print("void $classname$::Swap($classname$* other) {\n",
@@ -1044,13 +1761,23 @@ GenerateSwap(io::Printer* printer) {
field_generators_.get(field).GenerateSwappingCode(printer);
}
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "std::swap($oneof_name$_, other->$oneof_name$_);\n"
+ "std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name(),
+ "i", SimpleItoa(i));
+ }
+
for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
"i", SimpleItoa(i));
}
- if (HasUnknownFields(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file())) {
printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
+ } else {
+ 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) {
@@ -1122,31 +1849,60 @@ GenerateMergeFrom(io::Printer* printer) {
}
}
+ // Merge oneof fields. Oneof field requires oneof case check.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
+ printer->Print(
+ "switch (from.$oneofname$_case()) {\n",
+ "oneofname", 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(
+ "case k$field_name$: {\n",
+ "field_name", UnderscoresToCamelCase(field->name(), true));
+ printer->Indent();
+ field_generators_.get(field).GenerateMergingCode(printer);
+ printer->Print(
+ "break;\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+ printer->Print(
+ "case $cap_oneof_name$_NOT_SET: {\n"
+ " break;\n"
+ "}\n",
+ "cap_oneof_name",
+ ToUpper(descriptor_->oneof_decl(i)->name()));
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+
// Merge Optional and Required fields (after a _has_bit check).
int last_index = -1;
for (int i = 0; i < descriptor_->field_count(); ++i) {
const FieldDescriptor* field = descriptor_->field(i);
- if (!field->is_repeated()) {
- map<string, string> vars;
- vars["index"] = SimpleItoa(field->index());
-
+ if (!field->is_repeated() && !field->containing_oneof()) {
// See above in GenerateClear for an explanation of this.
if (i / 8 != last_index / 8 || last_index < 0) {
if (last_index >= 0) {
printer->Outdent();
printer->Print("}\n");
}
- printer->Print(vars,
- "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n");
+ printer->Print(
+ "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
+ "index", SimpleItoa(field->index()));
printer->Indent();
}
last_index = i;
- printer->Print(vars,
- "if (from._has_bit($index$)) {\n");
+ printer->Print(
+ "if (from.has_$name$()) {\n",
+ "name", FieldName(field));
printer->Indent();
field_generators_.get(field).GenerateMergingCode(printer);
@@ -1165,9 +1921,12 @@ GenerateMergeFrom(io::Printer* printer) {
printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
}
- if (HasUnknownFields(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file())) {
printer->Print(
"mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
+ } else {
+ printer->Print(
+ "mutable_unknown_fields()->append(from.unknown_fields());\n");
}
printer->Outdent();
@@ -1214,25 +1973,61 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
// Special-case MessageSet.
printer->Print(
"bool $classname$::MergePartialFromCodedStream(\n"
- " ::google::protobuf::io::CodedInputStream* input) {\n"
+ " ::google::protobuf::io::CodedInputStream* input) {\n",
+ "classname", classname_);
+
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
" return _extensions_.ParseMessageSet(input, default_instance_,\n"
- " mutable_unknown_fields());\n"
- "}\n",
+ " mutable_unknown_fields());\n",
+ // Without.
+ " return _extensions_.ParseMessageSet(input, &default_instance(),\n"
+ " mutable_unknown_fields());\n",
+ // Vars.
"classname", classname_);
+
+ printer->Print(
+ "}\n");
return;
}
printer->Print(
"bool $classname$::MergePartialFromCodedStream(\n"
" ::google::protobuf::io::CodedInputStream* input) {\n"
- "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n"
- " ::google::protobuf::uint32 tag;\n"
- " while ((tag = input->ReadTag()) != 0) {\n",
+ "#define DO_(EXPRESSION) if (!(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"
+ " ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
+ " &unknown_fields_string);\n");
+ }
+
+ printer->Print(
+ " // @@protoc_insertion_point(parse_start:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
printer->Indent();
+ printer->Print("for (;;) {\n");
printer->Indent();
+ scoped_array<const FieldDescriptor*> ordered_fields(
+ SortFieldsByNumber(descriptor_));
+ uint32 maxtag = descriptor_->field_count() == 0 ? 0 :
+ WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]);
+ const int kCutoff0 = 127; // fits in 1-byte varint
+ const int kCutoff1 = (127 << 7) + 127; // fits in 2-byte varint
+ printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = "
+ "input->ReadTagWithCutoff($max$);\n"
+ "tag = p.first;\n"
+ "if (!p.second) goto handle_unusual;\n",
+ "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 :
+ (maxtag <= kCutoff1 ? kCutoff1 :
+ maxtag)));
if (descriptor_->field_count() > 0) {
// We don't even want to print the switch() if we have no fields because
// MSVC dislikes switch() statements that contain only a default value.
@@ -1242,14 +2037,11 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
// of each case. However, this is actually a bit slower in practice as it
// creates a jump table that is 8x larger and sparser, and meanwhile the
// if()s are highly predictable.
- printer->Print(
- "switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {\n");
+ printer->Print("switch (::google::protobuf::internal::WireFormatLite::"
+ "GetTagFieldNumber(tag)) {\n");
printer->Indent();
- scoped_array<const FieldDescriptor*> ordered_fields(
- SortFieldsByNumber(descriptor_));
-
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = ordered_fields[i];
@@ -1262,10 +2054,8 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
const FieldGenerator& field_generator = field_generators_.get(field);
// Emit code to parse the common, expected case.
- printer->Print(
- "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
- " ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n",
- "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]);
+ printer->Print("if (tag == $commontag$) {\n",
+ "commontag", SimpleItoa(WireFormat::MakeTag(field)));
if (i > 0 || (field->is_repeated() && !field->options().packed())) {
printer->Print(
@@ -1283,20 +2073,22 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
// Emit code to parse unexpectedly packed or unpacked values.
if (field->is_packable() && field->options().packed()) {
- printer->Print(
- "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
- " == ::google::protobuf::internal::WireFormatLite::\n"
- " WIRETYPE_$wiretype$) {\n",
- "wiretype",
- kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]);
+ internal::WireFormatLite::WireType wiretype =
+ WireFormat::WireTypeForFieldType(field->type());
+ printer->Print("} else if (tag == $uncommontag$) {\n",
+ "uncommontag", SimpleItoa(
+ internal::WireFormatLite::MakeTag(
+ field->number(), wiretype)));
printer->Indent();
field_generator.GenerateMergeFromCodedStream(printer);
printer->Outdent();
} else if (field->is_packable() && !field->options().packed()) {
- printer->Print(
- "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
- " == ::google::protobuf::internal::WireFormatLite::\n"
- " WIRETYPE_LENGTH_DELIMITED) {\n");
+ internal::WireFormatLite::WireType wiretype =
+ internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
+ printer->Print("} else if (tag == $uncommontag$) {\n",
+ "uncommontag", SimpleItoa(
+ internal::WireFormatLite::MakeTag(
+ field->number(), wiretype)));
printer->Indent();
field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
printer->Outdent();
@@ -1304,7 +2096,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
printer->Print(
"} else {\n"
- " goto handle_uninterpreted;\n"
+ " goto handle_unusual;\n"
"}\n");
// switch() is slow since it can't be predicted well. Insert some if()s
@@ -1328,7 +2120,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
// Expect EOF.
// TODO(kenton): Expect group end-tag?
printer->Print(
- "if (input->ExpectAtEnd()) return true;\n");
+ "if (input->ExpectAtEnd()) goto success;\n");
}
printer->Print(
@@ -1338,17 +2130,19 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
printer->Print("}\n\n");
}
- printer->Print(
- "default: {\n"
- "handle_uninterpreted:\n");
+ printer->Print("default: {\n");
printer->Indent();
}
- // Is this an end-group tag? If so, this must be the end of the message.
+ printer->Outdent();
+ printer->Print("handle_unusual:\n");
+ printer->Indent();
+ // If tag is 0 or an end-group tag then this must be the end of the message.
printer->Print(
- "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
+ "if (tag == 0 ||\n"
+ " ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
" ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
- " return true;\n"
+ " goto success;\n"
"}\n");
// Handle extension ranges.
@@ -1377,13 +2171,24 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
}
}
printer->Print(") {\n");
- if (HasUnknownFields(descriptor_->file())) {
- printer->Print(
+ if (UseUnknownFieldSet(descriptor_->file())) {
+ 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");
} else {
- printer->Print(
- " DO_(_extensions_.ParseField(tag, input, default_instance_));\n");
+ 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");
}
printer->Print(
" continue;\n"
@@ -1391,13 +2196,14 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
}
// We really don't recognize this tag. Skip it.
- if (HasUnknownFields(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file())) {
printer->Print(
"DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
" input, tag, mutable_unknown_fields()));\n");
} else {
printer->Print(
- "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n");
+ "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n"
+ " input, tag, &unknown_fields_stream));\n");
}
if (descriptor_->field_count() > 0) {
@@ -1411,10 +2217,15 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
printer->Outdent();
printer->Outdent();
printer->Print(
- " }\n" // while
+ " }\n" // for (;;)
+ "success:\n"
+ " // @@protoc_insertion_point(parse_success:$full_name$)\n"
" return true;\n"
+ "failure:\n"
+ " // @@protoc_insertion_point(parse_failure:$full_name$)\n"
+ " return false;\n"
"#undef DO_\n"
- "}\n");
+ "}\n", "full_name", descriptor_->full_name());
}
void MessageGenerator::GenerateSerializeOneField(
@@ -1423,8 +2234,8 @@ void MessageGenerator::GenerateSerializeOneField(
if (!field->is_repeated()) {
printer->Print(
- "if (_has_bit($index$)) {\n",
- "index", SimpleItoa(field->index()));
+ "if (has_$name$()) {\n",
+ "name", FieldName(field));
printer->Indent();
}
@@ -1470,11 +2281,10 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) {
" ::google::protobuf::io::CodedOutputStream* output) const {\n"
" _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
"classname", classname_);
- if (HasUnknownFields(descriptor_->file())) {
- printer->Print(
- " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
- " unknown_fields(), output);\n");
- }
+ GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
+ printer->Print(
+ " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
+ " unknown_fields(), output);\n");
printer->Print(
"}\n");
return;
@@ -1486,8 +2296,16 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) {
"classname", classname_);
printer->Indent();
+ printer->Print(
+ "// @@protoc_insertion_point(serialize_start:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
GenerateSerializeWithCachedSizesBody(printer, false);
+ printer->Print(
+ "// @@protoc_insertion_point(serialize_end:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
printer->Outdent();
printer->Print(
"}\n");
@@ -1503,12 +2321,11 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
" target =\n"
" _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
"classname", classname_);
- if (HasUnknownFields(descriptor_->file())) {
- printer->Print(
- " target = ::google::protobuf::internal::WireFormat::\n"
- " SerializeUnknownMessageSetItemsToArray(\n"
- " unknown_fields(), target);\n");
- }
+ GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
+ printer->Print(
+ " target = ::google::protobuf::internal::WireFormat::\n"
+ " SerializeUnknownMessageSetItemsToArray(\n"
+ " unknown_fields(), target);\n");
printer->Print(
" return target;\n"
"}\n");
@@ -1521,8 +2338,16 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
"classname", classname_);
printer->Indent();
+ printer->Print(
+ "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
GenerateSerializeWithCachedSizesBody(printer, true);
+ printer->Print(
+ "// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
printer->Outdent();
printer->Print(
" return target;\n"
@@ -1532,7 +2357,7 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
void MessageGenerator::
GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
scoped_array<const FieldDescriptor*> ordered_fields(
- SortFieldsByNumber(descriptor_));
+ SortFieldsByNumber(descriptor_));
vector<const Descriptor::ExtensionRange*> sorted_extensions;
for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
@@ -1561,7 +2386,7 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
}
}
- if (HasUnknownFields(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file())) {
printer->Print("if (!unknown_fields().empty()) {\n");
printer->Indent();
if (to_array) {
@@ -1578,6 +2403,10 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
printer->Print(
"}\n");
+ } else {
+ printer->Print(
+ "output->WriteRaw(unknown_fields().data(),\n"
+ " unknown_fields().size());\n");
}
}
@@ -1589,11 +2418,10 @@ GenerateByteSize(io::Printer* printer) {
"int $classname$::ByteSize() const {\n"
" int total_size = _extensions_.MessageSetByteSize();\n",
"classname", classname_);
- if (HasUnknownFields(descriptor_->file())) {
- printer->Print(
- " total_size += ::google::protobuf::internal::WireFormat::\n"
- " ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
- }
+ GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
+ printer->Print(
+ " total_size += ::google::protobuf::internal::WireFormat::\n"
+ " ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
printer->Print(
" GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
" _cached_size_ = total_size;\n"
@@ -1616,7 +2444,7 @@ GenerateByteSize(io::Printer* printer) {
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
- if (!field->is_repeated()) {
+ if (!field->is_repeated() && !field->containing_oneof()) {
// See above in GenerateClear for an explanation of this.
// TODO(kenton): Share code? Unclear how to do so without
// over-engineering.
@@ -1666,13 +2494,45 @@ GenerateByteSize(io::Printer* printer) {
}
}
+ // Fields inside a oneof don't use _has_bits_ so we count them in a separate
+ // pass.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "switch ($oneofname$_case()) {\n",
+ "oneofname", 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);
+ PrintFieldComment(printer, field);
+ printer->Print(
+ "case k$field_name$: {\n",
+ "field_name", UnderscoresToCamelCase(field->name(), true));
+ printer->Indent();
+ field_generators_.get(field).GenerateByteSize(printer);
+ printer->Print(
+ "break;\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+ printer->Print(
+ "case $cap_oneof_name$_NOT_SET: {\n"
+ " break;\n"
+ "}\n",
+ "cap_oneof_name",
+ ToUpper(descriptor_->oneof_decl(i)->name()));
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+
if (descriptor_->extension_range_count() > 0) {
printer->Print(
"total_size += _extensions_.ByteSize();\n"
"\n");
}
- if (HasUnknownFields(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file())) {
printer->Print("if (!unknown_fields().empty()) {\n");
printer->Indent();
printer->Print(
@@ -1681,6 +2541,10 @@ GenerateByteSize(io::Printer* printer) {
" unknown_fields());\n");
printer->Outdent();
printer->Print("}\n");
+ } else {
+ printer->Print(
+ "total_size += unknown_fields().size();\n"
+ "\n");
}
// We update _cached_size_ even though this is a const method. In theory,
@@ -1734,19 +2598,30 @@ 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())) {
if (field->is_repeated()) {
printer->Print(
- "for (int i = 0; i < $name$_size(); i++) {\n"
- " if (!this->$name$(i).IsInitialized()) return false;\n"
- "}\n",
+ "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))"
+ " return false;\n",
"name", FieldName(field));
} else {
- printer->Print(
- "if (has_$name$()) {\n"
- " if (!this->$name$().IsInitialized()) return false;\n"
- "}\n",
- "name", FieldName(field));
+ if (field->options().weak()) {
+ // For weak fields, use the data member (google::protobuf::Message*) instead
+ // of the getter to avoid a link dependency on the weak message type
+ // which is only forward declared.
+ printer->Print(
+ "if (has_$name$()) {\n"
+ " if (!this->$name$_->IsInitialized()) return false;\n"
+ "}\n",
+ "name", FieldName(field));
+ } else {
+ printer->Print(
+ "if (has_$name$()) {\n"
+ " if (!this->$name$().IsInitialized()) return false;\n"
+ "}\n",
+ "name", FieldName(field));
+ }
}
}
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h
index 04778f6..bfd3cec 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,9 +35,11 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
+#include <memory>
#include <string>
-#include <google/protobuf/stubs/common.h>
+#include <vector>
#include <google/protobuf/compiler/cpp/cpp_field.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
namespace google {
namespace protobuf {
@@ -57,7 +59,7 @@ class MessageGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit MessageGenerator(const Descriptor* descriptor,
- const string& dllexport_decl);
+ const Options& options);
~MessageGenerator();
// Header stuff.
@@ -131,6 +133,7 @@ class MessageGenerator {
// Generate standard Message methods.
void GenerateClear(io::Printer* printer);
+ void GenerateOneofClear(io::Printer* printer);
void GenerateMergeFromCodedStream(io::Printer* printer);
void GenerateSerializeWithCachedSizes(io::Printer* printer);
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer);
@@ -153,11 +156,13 @@ class MessageGenerator {
const Descriptor* descriptor_;
string classname_;
- string dllexport_decl_;
+ Options options_;
FieldGeneratorMap field_generators_;
+ vector< vector<string> > runs_of_fields_; // that might be trivially cleared
scoped_array<scoped_ptr<MessageGenerator> > nested_generators_;
scoped_array<scoped_ptr<EnumGenerator> > enum_generators_;
scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_;
+ bool uses_string_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
};
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index c04bdc6..6ac15a5 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -45,13 +45,20 @@ namespace cpp {
namespace {
void SetMessageVariables(const FieldDescriptor* descriptor,
- map<string, string>* variables) {
- SetCommonFieldVariables(descriptor, variables);
+ map<string, string>* variables,
+ const Options& options) {
+ SetCommonFieldVariables(descriptor, variables, options);
(*variables)["type"] = FieldMessageTypeName(descriptor);
(*variables)["stream_writer"] = (*variables)["declared_type"] +
(HasFastArraySerialization(descriptor->message_type()->file()) ?
"MaybeToArray" :
"");
+ // NOTE: Escaped here to unblock proto1->proto2 migration.
+ // TODO(liujisi): Extend this to apply for other conflicting methods.
+ (*variables)["release_name"] =
+ SafeFunctionName(descriptor->containing_type(),
+ descriptor, "release_");
+ (*variables)["full_name"] = descriptor->full_name();
}
} // namespace
@@ -59,9 +66,10 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
// ===================================================================
MessageFieldGenerator::
-MessageFieldGenerator(const FieldDescriptor* descriptor)
+MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
: descriptor_(descriptor) {
- SetMessageVariables(descriptor, &variables_);
+ SetMessageVariables(descriptor, &variables_, options);
}
MessageFieldGenerator::~MessageFieldGenerator() {}
@@ -75,19 +83,47 @@ void MessageFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
"inline const $type$& $name$() const$deprecation$;\n"
- "inline $type$* mutable_$name$()$deprecation$;\n");
+ "inline $type$* mutable_$name$()$deprecation$;\n"
+ "inline $type$* $release_name$()$deprecation$;\n"
+ "inline void set_allocated_$name$($type$* $name$)$deprecation$;\n");
}
void MessageFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
printer->Print(variables_,
"inline const $type$& $classname$::$name$() const {\n"
- " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n"
+ " // @@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");
+
+ printer->Print(variables_,
"}\n"
"inline $type$* $classname$::mutable_$name$() {\n"
- " _set_bit($index$);\n"
+ " set_has_$name$();\n"
" if ($name$_ == NULL) $name$_ = new $type$;\n"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return $name$_;\n"
+ "}\n"
+ "inline $type$* $classname$::$release_name$() {\n"
+ " clear_has_$name$();\n"
+ " $type$* temp = $name$_;\n"
+ " $name$_ = NULL;\n"
+ " return temp;\n"
+ "}\n"
+ "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
+ " delete $name$_;\n"
+ " $name$_ = $name$;\n"
+ " if ($name$) {\n"
+ " set_has_$name$();\n"
+ " } else {\n"
+ " clear_has_$name$();\n"
+ " }\n"
+ " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
"}\n");
}
@@ -151,10 +187,74 @@ GenerateByteSize(io::Printer* printer) const {
// ===================================================================
+MessageOneofFieldGenerator::
+MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : MessageFieldGenerator(descriptor, options) {
+ SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
+
+void MessageOneofFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const $type$& $classname$::$name$() const {\n"
+ " return has_$name$() ? *$oneof_prefix$$name$_\n"
+ " : $type$::default_instance();\n"
+ "}\n"
+ "inline $type$* $classname$::mutable_$name$() {\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " $oneof_prefix$$name$_ = new $type$;\n"
+ " }\n"
+ " return $oneof_prefix$$name$_;\n"
+ "}\n"
+ "inline $type$* $classname$::$release_name$() {\n"
+ " if (has_$name$()) {\n"
+ " clear_has_$oneof_name$();\n"
+ " $type$* temp = $oneof_prefix$$name$_;\n"
+ " $oneof_prefix$$name$_ = NULL;\n"
+ " return temp;\n"
+ " } else {\n"
+ " return NULL;\n"
+ " }\n"
+ "}\n"
+ "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
+ " clear_$oneof_name$();\n"
+ " if ($name$) {\n"
+ " set_has_$name$();\n"
+ " $oneof_prefix$$name$_ = $name$;\n"
+ " }\n"
+ "}\n");
+}
+
+void MessageOneofFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ // if it is the active field, it cannot be NULL.
+ printer->Print(variables_,
+ "delete $oneof_prefix$$name$_;\n");
+}
+
+void MessageOneofFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void MessageOneofFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ // Don't print any constructor code. The field is in a union. We allocate
+ // space only when this field is used.
+}
+
+// ===================================================================
+
RepeatedMessageFieldGenerator::
-RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor)
+RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
: descriptor_(descriptor) {
- SetMessageVariables(descriptor, &variables_);
+ SetMessageVariables(descriptor, &variables_, options);
}
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
@@ -182,21 +282,26 @@ void RepeatedMessageFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
printer->Print(variables_,
"inline const $type$& $classname$::$name$(int index) const {\n"
- " return $name$_.Get(index);\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return $name$_.$cppget$(index);\n"
"}\n"
"inline $type$* $classname$::mutable_$name$(int index) {\n"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return $name$_.Mutable(index);\n"
"}\n"
"inline $type$* $classname$::add_$name$() {\n"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
" return $name$_.Add();\n"
"}\n");
printer->Print(variables_,
"inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
"$classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
" return $name$_;\n"
"}\n"
"inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
"$classname$::mutable_$name$() {\n"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
" return &$name$_;\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 f514727..2dff314 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -46,7 +46,8 @@ namespace cpp {
class MessageFieldGenerator : public FieldGenerator {
public:
- explicit MessageFieldGenerator(const FieldDescriptor* descriptor);
+ explicit MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~MessageFieldGenerator();
// implements FieldGenerator ---------------------------------------
@@ -62,16 +63,34 @@ class MessageFieldGenerator : public FieldGenerator {
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
void GenerateByteSize(io::Printer* printer) const;
- private:
+ protected:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
};
+class MessageOneofFieldGenerator : public MessageFieldGenerator {
+ public:
+ explicit MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~MessageOneofFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator);
+};
+
class RepeatedMessageFieldGenerator : public FieldGenerator {
public:
- explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor);
+ explicit 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
new file mode 100644
index 0000000..0c99cff
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_options.h
@@ -0,0 +1,58 @@
+// 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: rennie@google.com (Jeffrey Rennie)
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Generator options:
+struct Options {
+ Options() : safe_boundary_check(false) {
+ }
+ string dllexport_decl;
+ bool safe_boundary_check;
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
index 440b716..2dbf14c 100644
--- a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -34,6 +34,8 @@
// It seemed like parameterizing it would add more complexity than it is
// worth.
+#include <memory>
+
#include <google/protobuf/compiler/cpp/cpp_generator.h>
#include <google/protobuf/compiler/command_line_interface.h>
#include <google/protobuf/io/zero_copy_stream.h>
@@ -56,24 +58,24 @@ class TestGenerator : public CodeGenerator {
virtual bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
- TryInsert("test.pb.h", "includes", output_directory);
- TryInsert("test.pb.h", "namespace_scope", output_directory);
- TryInsert("test.pb.h", "global_scope", output_directory);
- TryInsert("test.pb.h", "class_scope:foo.Bar", output_directory);
- TryInsert("test.pb.h", "class_scope:foo.Bar.Baz", output_directory);
-
- TryInsert("test.pb.cc", "includes", output_directory);
- TryInsert("test.pb.cc", "namespace_scope", output_directory);
- TryInsert("test.pb.cc", "global_scope", output_directory);
+ TryInsert("test.pb.h", "includes", context);
+ TryInsert("test.pb.h", "namespace_scope", context);
+ TryInsert("test.pb.h", "global_scope", context);
+ TryInsert("test.pb.h", "class_scope:foo.Bar", context);
+ TryInsert("test.pb.h", "class_scope:foo.Bar.Baz", context);
+
+ TryInsert("test.pb.cc", "includes", context);
+ TryInsert("test.pb.cc", "namespace_scope", context);
+ TryInsert("test.pb.cc", "global_scope", context);
return true;
}
void TryInsert(const string& filename, const string& insertion_point,
- OutputDirectory* output_directory) const {
+ GeneratorContext* context) const {
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->OpenForInsert(filename, insertion_point));
+ context->OpenForInsert(filename, insertion_point));
io::Printer printer(output.get(), '$');
printer.Print("// inserted $name$\n", "name", insertion_point);
}
@@ -83,13 +85,13 @@ class TestGenerator : public CodeGenerator {
// not verify that they are correctly-placed; that would require actually
// compiling the output which is a bit more than I care to do for this test.
TEST(CppPluginTest, PluginTest) {
- File::WriteStringToFileOrDie(
- "syntax = \"proto2\";\n"
- "package foo;\n"
- "message Bar {\n"
- " message Baz {}\n"
- "}\n",
- TestTempDir() + "/test.proto");
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto",
+ "syntax = \"proto2\";\n"
+ "package foo;\n"
+ "message Bar {\n"
+ " message Baz {}\n"
+ "}\n",
+ true));
google::protobuf::compiler::CommandLineInterface cli;
cli.SetInputsAreProtoPathRelative(true);
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
index a69c48b..44290a3 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -80,8 +80,9 @@ int FixedSize(FieldDescriptor::Type type) {
}
void SetPrimitiveVariables(const FieldDescriptor* descriptor,
- map<string, string>* variables) {
- SetCommonFieldVariables(descriptor, variables);
+ map<string, string>* variables,
+ const Options& options) {
+ SetCommonFieldVariables(descriptor, variables, options);
(*variables)["type"] = PrimitiveTypeName(descriptor->cpp_type());
(*variables)["default"] = DefaultValue(descriptor);
(*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
@@ -92,6 +93,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
(*variables)["wire_format_field_type"] =
"::google::protobuf::internal::WireFormatLite::" + FieldDescriptorProto_Type_Name(
static_cast<FieldDescriptorProto_Type>(descriptor->type()));
+ (*variables)["full_name"] = descriptor->full_name();
}
} // namespace
@@ -99,9 +101,10 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
// ===================================================================
PrimitiveFieldGenerator::
-PrimitiveFieldGenerator(const FieldDescriptor* descriptor)
+PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
: descriptor_(descriptor) {
- SetPrimitiveVariables(descriptor, &variables_);
+ SetPrimitiveVariables(descriptor, &variables_, options);
}
PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
@@ -122,11 +125,13 @@ void PrimitiveFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
printer->Print(variables_,
"inline $type$ $classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
" return $name$_;\n"
"}\n"
"inline void $classname$::set_$name$($type$ value) {\n"
- " _set_bit($index$);\n"
+ " set_has_$name$();\n"
" $name$_ = value;\n"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n");
}
@@ -156,7 +161,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
"DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
" $type$, $wire_format_field_type$>(\n"
" input, &$name$_)));\n"
- "_set_bit($index$);\n");
+ "set_has_$name$();\n");
}
void PrimitiveFieldGenerator::
@@ -189,10 +194,67 @@ GenerateByteSize(io::Printer* printer) const {
// ===================================================================
+PrimitiveOneofFieldGenerator::
+PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : PrimitiveFieldGenerator(descriptor, options) {
+ SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {}
+
+void PrimitiveOneofFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $classname$::$name$() const {\n"
+ " if (has_$name$()) {\n"
+ " return $oneof_prefix$$name$_;\n"
+ " }\n"
+ " return $default$;\n"
+ "}\n"
+ "inline void $classname$::set_$name$($type$ value) {\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " }\n"
+ " $oneof_prefix$$name$_ = value;\n"
+ "}\n");
+}
+
+void PrimitiveOneofFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$oneof_prefix$$name$_ = $default$;\n");
+}
+
+void PrimitiveOneofFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void PrimitiveOneofFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ " $classname$_default_oneof_instance_->$name$_ = $default$;\n");
+}
+
+void PrimitiveOneofFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ printer->Print(variables_,
+ "clear_$oneof_name$();\n"
+ "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+ " $type$, $wire_format_field_type$>(\n"
+ " input, &$oneof_prefix$$name$_)));\n"
+ "set_has_$name$();\n");
+}
+
+// ===================================================================
+
RepeatedPrimitiveFieldGenerator::
-RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor)
+RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
: descriptor_(descriptor) {
- SetPrimitiveVariables(descriptor, &variables_);
+ SetPrimitiveVariables(descriptor, &variables_, options);
if (descriptor->options().packed()) {
variables_["packed_reader"] = "ReadPackedPrimitive";
@@ -232,21 +294,26 @@ void RepeatedPrimitiveFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
printer->Print(variables_,
"inline $type$ $classname$::$name$(int index) const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
" return $name$_.Get(index);\n"
"}\n"
"inline void $classname$::set_$name$(int index, $type$ value) {\n"
" $name$_.Set(index, value);\n"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
"inline void $classname$::add_$name$($type$ value) {\n"
" $name$_.Add(value);\n"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
"}\n");
printer->Print(variables_,
"inline const ::google::protobuf::RepeatedField< $type$ >&\n"
"$classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
" return $name$_;\n"
"}\n"
"inline ::google::protobuf::RepeatedField< $type$ >*\n"
"$classname$::mutable_$name$() {\n"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
" return &$name$_;\n"
"}\n");
}
@@ -366,7 +433,9 @@ GenerateByteSize(io::Printer* printer) const {
" total_size += $tag_size$ +\n"
" ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
"}\n"
+ "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
"_$name$_cached_byte_size_ = data_size;\n"
+ "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
"total_size += data_size;\n");
} else {
printer->Print(variables_,
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
index 8fcd74a..97b5e86 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -46,7 +46,8 @@ namespace cpp {
class PrimitiveFieldGenerator : public FieldGenerator {
public:
- explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+ explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~PrimitiveFieldGenerator();
// implements FieldGenerator ---------------------------------------
@@ -62,16 +63,35 @@ class PrimitiveFieldGenerator : public FieldGenerator {
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
void GenerateByteSize(io::Printer* printer) const;
- private:
+ protected:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
};
+class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
+ public:
+ explicit PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~PrimitiveOneofFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveOneofFieldGenerator);
+};
+
class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
public:
- explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+ explicit 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 c282568..a8f303d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_service.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_service.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -43,14 +43,14 @@ namespace compiler {
namespace cpp {
ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor,
- const string& dllexport_decl)
+ const Options& options)
: descriptor_(descriptor) {
vars_["classname"] = descriptor_->name();
vars_["full_name"] = descriptor_->full_name();
- if (dllexport_decl.empty()) {
+ if (options.dllexport_decl.empty()) {
vars_["dllexport"] = "";
} else {
- vars_["dllexport"] = dllexport_decl + " ";
+ vars_["dllexport"] = options.dllexport_decl + " ";
}
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_service.h b/src/google/protobuf/compiler/cpp/cpp_service.h
index 10e9dd3..ede2fd8 100644
--- a/src/google/protobuf/compiler/cpp/cpp_service.h
+++ b/src/google/protobuf/compiler/cpp/cpp_service.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -37,7 +37,7 @@
#include <map>
#include <string>
-#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/descriptor.h>
namespace google {
@@ -55,7 +55,7 @@ class ServiceGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit ServiceGenerator(const ServiceDescriptor* descriptor,
- const string& dllexport_decl);
+ const Options& options);
~ServiceGenerator();
// Header stuff.
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index ea6809a..180d236 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -46,12 +46,23 @@ namespace cpp {
namespace {
void SetStringVariables(const FieldDescriptor* descriptor,
- map<string, string>* variables) {
- SetCommonFieldVariables(descriptor, variables);
- (*variables)["default"] =
- "\"" + CEscape(descriptor->default_value_string()) + "\"";
+ map<string, string>* variables,
+ const Options& options) {
+ SetCommonFieldVariables(descriptor, variables, options);
+ (*variables)["default"] = DefaultValue(descriptor);
+ (*variables)["default_length"] =
+ SimpleItoa(descriptor->default_value_string().length());
+ (*variables)["default_variable"] = descriptor->default_value_string().empty()
+ ? "&::google::protobuf::internal::GetEmptyStringAlreadyInited()"
+ : "_default_" + FieldName(descriptor) + "_";
(*variables)["pointer_type"] =
descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
+ // NOTE: Escaped here to unblock proto1->proto2 migration.
+ // TODO(liujisi): Extend this to apply for other conflicting methods.
+ (*variables)["release_name"] =
+ SafeFunctionName(descriptor->containing_type(),
+ descriptor, "release_");
+ (*variables)["full_name"] = descriptor->full_name();
}
} // namespace
@@ -59,18 +70,24 @@ void SetStringVariables(const FieldDescriptor* descriptor,
// ===================================================================
StringFieldGenerator::
-StringFieldGenerator(const FieldDescriptor* descriptor)
+StringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
: descriptor_(descriptor) {
- SetStringVariables(descriptor, &variables_);
+ SetStringVariables(descriptor, &variables_, options);
}
StringFieldGenerator::~StringFieldGenerator() {}
void StringFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
- printer->Print(variables_,
- "::std::string* $name$_;\n"
- "static const ::std::string _default_$name$_;\n");
+ printer->Print(variables_, "::std::string* $name$_;\n");
+}
+
+void StringFieldGenerator::
+GenerateStaticMembers(io::Printer* printer) const {
+ if (!descriptor_->default_value_string().empty()) {
+ printer->Print(variables_, "static ::std::string* $default_variable$;\n");
+ }
}
void StringFieldGenerator::
@@ -105,7 +122,10 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
"inline void set_$name$(const char* value)$deprecation$;\n"
"inline void set_$name$(const $pointer_type$* value, size_t size)"
"$deprecation$;\n"
- "inline ::std::string* mutable_$name$()$deprecation$;\n");
+ "inline ::std::string* mutable_$name$()$deprecation$;\n"
+ "inline ::std::string* $release_name$()$deprecation$;\n"
+ "inline void set_allocated_$name$(::std::string* $name$)$deprecation$;\n");
+
if (descriptor_->options().ctype() != FieldOptions::STRING) {
printer->Outdent();
@@ -118,54 +138,80 @@ void StringFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
printer->Print(variables_,
"inline const ::std::string& $classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
" return *$name$_;\n"
"}\n"
"inline void $classname$::set_$name$(const ::std::string& value) {\n"
- " _set_bit($index$);\n"
- " if ($name$_ == &_default_$name$_) {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == $default_variable$) {\n"
" $name$_ = new ::std::string;\n"
" }\n"
" $name$_->assign(value);\n"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
"inline void $classname$::set_$name$(const char* value) {\n"
- " _set_bit($index$);\n"
- " if ($name$_ == &_default_$name$_) {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == $default_variable$) {\n"
" $name$_ = new ::std::string;\n"
" }\n"
" $name$_->assign(value);\n"
+ " // @@protoc_insertion_point(field_set_char:$full_name$)\n"
"}\n"
"inline "
"void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
- " _set_bit($index$);\n"
- " if ($name$_ == &_default_$name$_) {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == $default_variable$) {\n"
" $name$_ = new ::std::string;\n"
" }\n"
" $name$_->assign(reinterpret_cast<const char*>(value), size);\n"
+ " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
"}\n"
"inline ::std::string* $classname$::mutable_$name$() {\n"
- " _set_bit($index$);\n"
- " if ($name$_ == &_default_$name$_) {\n");
+ " set_has_$name$();\n"
+ " if ($name$_ == $default_variable$) {\n");
if (descriptor_->default_value_string().empty()) {
printer->Print(variables_,
" $name$_ = new ::std::string;\n");
} else {
printer->Print(variables_,
- " $name$_ = new ::std::string(_default_$name$_);\n");
+ " $name$_ = new ::std::string(*$default_variable$);\n");
}
printer->Print(variables_,
" }\n"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return $name$_;\n"
+ "}\n"
+ "inline ::std::string* $classname$::$release_name$() {\n"
+ " clear_has_$name$();\n"
+ " if ($name$_ == $default_variable$) {\n"
+ " return NULL;\n"
+ " } else {\n"
+ " ::std::string* temp = $name$_;\n"
+ " $name$_ = const_cast< ::std::string*>($default_variable$);\n"
+ " return temp;\n"
+ " }\n"
+ "}\n"
+ "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
+ " if ($name$_ != $default_variable$) {\n"
+ " delete $name$_;\n"
+ " }\n"
+ " if ($name$) {\n"
+ " set_has_$name$();\n"
+ " $name$_ = $name$;\n"
+ " } else {\n"
+ " clear_has_$name$();\n"
+ " $name$_ = const_cast< ::std::string*>($default_variable$);\n"
+ " }\n"
+ " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
"}\n");
}
void StringFieldGenerator::
GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
- if (descriptor_->default_value_string().empty()) {
- printer->Print(variables_,
- "const ::std::string $classname$::_default_$name$_;\n");
- } else {
+ if (!descriptor_->default_value_string().empty()) {
+ // Initialized in GenerateDefaultInstanceAllocator.
printer->Print(variables_,
- "const ::std::string $classname$::_default_$name$_($default$);\n");
+ "::std::string* $classname$::$default_variable$ = NULL;\n");
}
}
@@ -173,13 +219,13 @@ void StringFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
if (descriptor_->default_value_string().empty()) {
printer->Print(variables_,
- "if ($name$_ != &_default_$name$_) {\n"
+ "if ($name$_ != $default_variable$) {\n"
" $name$_->clear();\n"
"}\n");
} else {
printer->Print(variables_,
- "if ($name$_ != &_default_$name$_) {\n"
- " $name$_->assign(_default_$name$_);\n"
+ "if ($name$_ != $default_variable$) {\n"
+ " $name$_->assign(*$default_variable$);\n"
"}\n");
}
}
@@ -197,18 +243,35 @@ GenerateSwappingCode(io::Printer* printer) const {
void StringFieldGenerator::
GenerateConstructorCode(io::Printer* printer) const {
printer->Print(variables_,
- "$name$_ = const_cast< ::std::string*>(&_default_$name$_);\n");
+ "$name$_ = const_cast< ::std::string*>($default_variable$);\n");
}
void StringFieldGenerator::
GenerateDestructorCode(io::Printer* printer) const {
printer->Print(variables_,
- "if ($name$_ != &_default_$name$_) {\n"
+ "if ($name$_ != $default_variable$) {\n"
" delete $name$_;\n"
"}\n");
}
void StringFieldGenerator::
+GenerateDefaultInstanceAllocator(io::Printer* printer) const {
+ if (!descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ "$classname$::$default_variable$ =\n"
+ " new ::std::string($default$, $default_length$);\n");
+ }
+}
+
+void StringFieldGenerator::
+GenerateShutdownCode(io::Printer* printer) const {
+ if (!descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ "delete $classname$::$default_variable$;\n");
+ }
+}
+
+void StringFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
printer->Print(variables_,
"DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
@@ -216,9 +279,10 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
if (HasUtf8Verification(descriptor_->file()) &&
descriptor_->type() == FieldDescriptor::TYPE_STRING) {
printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
" this->$name$().data(), this->$name$().length(),\n"
- " ::google::protobuf::internal::WireFormat::PARSE);\n");
+ " ::google::protobuf::internal::WireFormat::PARSE,\n"
+ " \"$name$\");\n");
}
}
@@ -227,12 +291,13 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const {
if (HasUtf8Verification(descriptor_->file()) &&
descriptor_->type() == FieldDescriptor::TYPE_STRING) {
printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
" this->$name$().data(), this->$name$().length(),\n"
- " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
+ " ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
+ " \"$name$\");\n");
}
printer->Print(variables_,
- "::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
+ "::google::protobuf::internal::WireFormatLite::Write$declared_type$MaybeAliased(\n"
" $number$, this->$name$(), output);\n");
}
@@ -241,9 +306,10 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
if (HasUtf8Verification(descriptor_->file()) &&
descriptor_->type() == FieldDescriptor::TYPE_STRING) {
printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
" this->$name$().data(), this->$name$().length(),\n"
- " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
+ " ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
+ " \"$name$\");\n");
}
printer->Print(variables_,
"target =\n"
@@ -261,10 +327,130 @@ GenerateByteSize(io::Printer* printer) const {
// ===================================================================
+StringOneofFieldGenerator::
+StringOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : StringFieldGenerator(descriptor, options) {
+ SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+StringOneofFieldGenerator::~StringOneofFieldGenerator() {}
+
+void StringOneofFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const ::std::string& $classname$::$name$() const {\n"
+ " if (has_$name$()) {\n"
+ " return *$oneof_prefix$$name$_;\n"
+ " }\n");
+ if (descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ " return ::google::protobuf::internal::GetEmptyStringAlreadyInited();\n");
+ } else {
+ printer->Print(variables_,
+ " return *$default_variable$;\n");
+ }
+ printer->Print(variables_,
+ "}\n"
+ "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " $oneof_prefix$$name$_ = new ::std::string;\n"
+ " }\n"
+ " $oneof_prefix$$name$_->assign(value);\n"
+ "}\n"
+ "inline void $classname$::set_$name$(const char* value) {\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " $oneof_prefix$$name$_ = new ::std::string;\n"
+ " }\n"
+ " $oneof_prefix$$name$_->assign(value);\n"
+ "}\n"
+ "inline "
+ "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " $oneof_prefix$$name$_ = new ::std::string;\n"
+ " }\n"
+ " $oneof_prefix$$name$_->assign(\n"
+ " reinterpret_cast<const char*>(value), size);\n"
+ "}\n"
+ "inline ::std::string* $classname$::mutable_$name$() {\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n");
+ if (descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ " $oneof_prefix$$name$_ = new ::std::string;\n");
+ } else {
+ printer->Print(variables_,
+ " $oneof_prefix$$name$_ = new ::std::string(*$default_variable$);\n");
+ }
+ printer->Print(variables_,
+ " }\n"
+ " return $oneof_prefix$$name$_;\n"
+ "}\n"
+ "inline ::std::string* $classname$::$release_name$() {\n"
+ " if (has_$name$()) {\n"
+ " clear_has_$oneof_name$();\n"
+ " ::std::string* temp = $oneof_prefix$$name$_;\n"
+ " $oneof_prefix$$name$_ = NULL;\n"
+ " return temp;\n"
+ " } else {\n"
+ " return NULL;\n"
+ " }\n"
+ "}\n"
+ "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
+ " clear_$oneof_name$();\n"
+ " if ($name$) {\n"
+ " set_has_$name$();\n"
+ " $oneof_prefix$$name$_ = $name$;\n"
+ " }\n"
+ "}\n");
+}
+
+void StringOneofFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "delete $oneof_prefix$$name$_;\n");
+}
+
+void StringOneofFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void StringOneofFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ if (!descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ " $classname$_default_oneof_instance_->$name$_ = "
+ "$classname$::$default_variable$;\n");
+ } else {
+ printer->Print(variables_,
+ " $classname$_default_oneof_instance_->$name$_ = "
+ "$default_variable$;\n");
+ }
+}
+
+void StringOneofFieldGenerator::
+GenerateDestructorCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (has_$name$()) {\n"
+ " delete $oneof_prefix$$name$_;\n"
+ "}\n");
+}
+
+// ===================================================================
+
RepeatedStringFieldGenerator::
-RepeatedStringFieldGenerator(const FieldDescriptor* descriptor)
+RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
: descriptor_(descriptor) {
- SetStringVariables(descriptor, &variables_);
+ SetStringVariables(descriptor, &variables_, options);
}
RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
@@ -317,43 +503,53 @@ void RepeatedStringFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
printer->Print(variables_,
"inline const ::std::string& $classname$::$name$(int index) const {\n"
- " return $name$_.Get(index);\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return $name$_.$cppget$(index);\n"
"}\n"
"inline ::std::string* $classname$::mutable_$name$(int index) {\n"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return $name$_.Mutable(index);\n"
"}\n"
"inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
" $name$_.Mutable(index)->assign(value);\n"
"}\n"
"inline void $classname$::set_$name$(int index, const char* value) {\n"
" $name$_.Mutable(index)->assign(value);\n"
+ " // @@protoc_insertion_point(field_set_char:$full_name$)\n"
"}\n"
"inline void "
"$classname$::set_$name$"
"(int index, const $pointer_type$* value, size_t size) {\n"
" $name$_.Mutable(index)->assign(\n"
" reinterpret_cast<const char*>(value), size);\n"
+ " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
"}\n"
"inline ::std::string* $classname$::add_$name$() {\n"
" return $name$_.Add();\n"
"}\n"
"inline void $classname$::add_$name$(const ::std::string& value) {\n"
" $name$_.Add()->assign(value);\n"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
"}\n"
"inline void $classname$::add_$name$(const char* value) {\n"
" $name$_.Add()->assign(value);\n"
+ " // @@protoc_insertion_point(field_add_char:$full_name$)\n"
"}\n"
"inline void "
"$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
" $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
+ " // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
"}\n");
printer->Print(variables_,
"inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n"
"$classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
" return $name$_;\n"
"}\n"
"inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n"
"$classname$::mutable_$name$() {\n"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
" return &$name$_;\n"
"}\n");
}
@@ -386,9 +582,11 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
if (HasUtf8Verification(descriptor_->file()) &&
descriptor_->type() == FieldDescriptor::TYPE_STRING) {
printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
- " this->$name$(0).data(), this->$name$(0).length(),\n"
- " ::google::protobuf::internal::WireFormat::PARSE);\n");
+ "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
+ " this->$name$(this->$name$_size() - 1).data(),\n"
+ " this->$name$(this->$name$_size() - 1).length(),\n"
+ " ::google::protobuf::internal::WireFormat::PARSE,\n"
+ " \"$name$\");\n");
}
}
@@ -399,9 +597,10 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const {
if (HasUtf8Verification(descriptor_->file()) &&
descriptor_->type() == FieldDescriptor::TYPE_STRING) {
printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
" this->$name$(i).data(), this->$name$(i).length(),\n"
- " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
+ " ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
+ " \"$name$\");\n");
}
printer->Print(variables_,
" ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
@@ -416,9 +615,10 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
if (HasUtf8Verification(descriptor_->file()) &&
descriptor_->type() == FieldDescriptor::TYPE_STRING) {
printer->Print(variables_,
- " ::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ " ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
" this->$name$(i).data(), this->$name$(i).length(),\n"
- " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
+ " ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
+ " \"$name$\");\n");
}
printer->Print(variables_,
" target = ::google::protobuf::internal::WireFormatLite::\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h
index 7f45107..86da38f 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -46,11 +46,13 @@ namespace cpp {
class StringFieldGenerator : public FieldGenerator {
public:
- explicit StringFieldGenerator(const FieldDescriptor* descriptor);
+ explicit StringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~StringFieldGenerator();
// implements FieldGenerator ---------------------------------------
void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateStaticMembers(io::Printer* printer) const;
void GenerateAccessorDeclarations(io::Printer* printer) const;
void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
@@ -59,21 +61,42 @@ class StringFieldGenerator : public FieldGenerator {
void GenerateSwappingCode(io::Printer* printer) const;
void GenerateConstructorCode(io::Printer* printer) const;
void GenerateDestructorCode(io::Printer* printer) const;
+ void GenerateDefaultInstanceAllocator(io::Printer* printer) const;
+ void GenerateShutdownCode(io::Printer* printer) const;
void GenerateMergeFromCodedStream(io::Printer* printer) const;
void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
void GenerateByteSize(io::Printer* printer) const;
- private:
+ protected:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator);
};
+class StringOneofFieldGenerator : public StringFieldGenerator {
+ public:
+ explicit StringOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~StringOneofFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateDestructorCode(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOneofFieldGenerator);
+};
+
class RepeatedStringFieldGenerator : public FieldGenerator {
public:
- explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor);
+ explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~RepeatedStringFieldGenerator();
// implements FieldGenerator ---------------------------------------
diff --git a/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
index 79971a9..6b7f830 100644
--- a/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
+++ b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -36,6 +36,10 @@
// though the same identifiers are used internally by the C++ code generator.
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+
// 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;
@@ -94,14 +98,33 @@ message TestConflictingSymbolNames {
// Some keywords.
optional uint32 int = 30;
optional uint32 friend = 31;
+ optional uint32 class = 37;
// The generator used to #define a macro called "DO" inside the .cc file.
message DO {}
optional DO do = 32;
+ // Some template parameter names for extensions.
+ optional int32 field_type = 33;
+ optional bool is_packed = 34;
+
+ // test conflicting release_$name$. "length" and "do" field in this message
+ // must remain string or message fields to make the test valid.
+ optional string release_length = 35;
+ // A more extreme case, the field name "do" here is a keyword, which will be
+ // escaped to "do_" already. Test there is no conflict even with escaped field
+ // names.
+ optional DO release_do = 36;
+
extensions 1000 to max;
}
+message TestConflictingSymbolNamesExtension {
+ extend TestConflictingSymbolNames {
+ repeated int32 repeated_int32_ext = 20423638 [packed=true];
+ }
+}
+
message DummyMessage {}
service TestConflictingMethodNames {
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index a7e852d..93e1c3f 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -44,6 +44,9 @@
// correctly and produces the interfaces we expect, which is why this test
// is written this way.
+#include <google/protobuf/compiler/cpp/cpp_unittest.h>
+
+#include <memory>
#include <vector>
#include <google/protobuf/unittest.pb.h>
@@ -51,6 +54,7 @@
#include <google/protobuf/unittest_embed_optimize_for.pb.h>
#include <google/protobuf/unittest_no_generic_services.pb.h>
#include <google/protobuf/test_util.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h>
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/io/coded_stream.h>
@@ -64,7 +68,7 @@
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
@@ -74,6 +78,8 @@ namespace cpp {
// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
namespace cpp_unittest {
+namespace protobuf_unittest = ::protobuf_unittest;
+
class MockErrorCollector : public MultiFileErrorCollector {
public:
@@ -144,6 +150,19 @@ TEST(GeneratedMessageTest, Defaults) {
&message.optional_import_message());
}
+TEST(GeneratedMessageTest, Int32StringConversion) {
+ EXPECT_EQ("971", Int32ToString(971));
+ EXPECT_EQ("(~0x7fffffff)", Int32ToString(kint32min));
+ EXPECT_EQ("2147483647", Int32ToString(kint32max));
+}
+
+TEST(GeneratedMessageTest, Int64StringConversion) {
+ EXPECT_EQ("GOOGLE_LONGLONG(971)", Int64ToString(971));
+ EXPECT_EQ("GOOGLE_LONGLONG(-2147483648)", Int64ToString(kint32min));
+ EXPECT_EQ("GOOGLE_LONGLONG(~0x7fffffffffffffff)", Int64ToString(kint64min));
+ EXPECT_EQ("GOOGLE_LONGLONG(9223372036854775807)", Int64ToString(kint64max));
+}
+
TEST(GeneratedMessageTest, FloatingPointDefaults) {
const unittest::TestExtremeDefaultValues& extreme_default =
unittest::TestExtremeDefaultValues::default_instance();
@@ -167,6 +186,22 @@ TEST(GeneratedMessageTest, FloatingPointDefaults) {
EXPECT_TRUE(extreme_default.nan_float() != extreme_default.nan_float());
}
+TEST(GeneratedMessageTest, Trigraph) {
+ const unittest::TestExtremeDefaultValues& extreme_default =
+ unittest::TestExtremeDefaultValues::default_instance();
+
+ EXPECT_EQ("? ? ?? ?? ??? ?\?/ ?\?-", extreme_default.cpp_trigraph());
+}
+
+TEST(GeneratedMessageTest, ExtremeSmallIntegerDefault) {
+ const unittest::TestExtremeDefaultValues& extreme_default =
+ unittest::TestExtremeDefaultValues::default_instance();
+ EXPECT_EQ(~0x7fffffff, kint32min);
+ EXPECT_EQ(GOOGLE_LONGLONG(~0x7fffffffffffffff), kint64min);
+ EXPECT_EQ(kint32min, extreme_default.really_small_int32());
+ EXPECT_EQ(kint64min, extreme_default.really_small_int64());
+}
+
TEST(GeneratedMessageTest, Accessors) {
// Set every field to a unique value then go back and check all those
// values.
@@ -195,6 +230,96 @@ TEST(GeneratedMessageTest, MutableStringDefault) {
EXPECT_EQ("hello", *message.mutable_default_string());
}
+TEST(GeneratedMessageTest, StringDefaults) {
+ unittest::TestExtremeDefaultValues message;
+ // Check if '\000' can be used in default string value.
+ EXPECT_EQ(string("hel\000lo", 6), message.string_with_zero());
+ EXPECT_EQ(string("wor\000ld", 6), message.bytes_with_zero());
+}
+
+TEST(GeneratedMessageTest, ReleaseString) {
+ // Check that release_foo() starts out NULL, and gives us a value
+ // that we can delete after it's been set.
+ unittest::TestAllTypes message;
+
+ EXPECT_EQ(NULL, message.release_default_string());
+ EXPECT_FALSE(message.has_default_string());
+ EXPECT_EQ("hello", message.default_string());
+
+ message.set_default_string("blah");
+ EXPECT_TRUE(message.has_default_string());
+ scoped_ptr<string> str(message.release_default_string());
+ EXPECT_FALSE(message.has_default_string());
+ ASSERT_TRUE(str != NULL);
+ EXPECT_EQ("blah", *str);
+
+ EXPECT_EQ(NULL, message.release_default_string());
+ EXPECT_FALSE(message.has_default_string());
+ EXPECT_EQ("hello", message.default_string());
+}
+
+TEST(GeneratedMessageTest, ReleaseMessage) {
+ // Check that release_foo() starts out NULL, and gives us a value
+ // that we can delete after it's been set.
+ unittest::TestAllTypes message;
+
+ EXPECT_EQ(NULL, message.release_optional_nested_message());
+ EXPECT_FALSE(message.has_optional_nested_message());
+
+ message.mutable_optional_nested_message()->set_bb(1);
+ scoped_ptr<unittest::TestAllTypes::NestedMessage> nest(
+ message.release_optional_nested_message());
+ EXPECT_FALSE(message.has_optional_nested_message());
+ ASSERT_TRUE(nest != NULL);
+ EXPECT_EQ(1, nest->bb());
+
+ EXPECT_EQ(NULL, message.release_optional_nested_message());
+ EXPECT_FALSE(message.has_optional_nested_message());
+}
+
+TEST(GeneratedMessageTest, SetAllocatedString) {
+ // Check that set_allocated_foo() works for strings.
+ unittest::TestAllTypes message;
+
+ EXPECT_FALSE(message.has_optional_string());
+ const string kHello("hello");
+ message.set_optional_string(kHello);
+ EXPECT_TRUE(message.has_optional_string());
+
+ message.set_allocated_optional_string(NULL);
+ EXPECT_FALSE(message.has_optional_string());
+ EXPECT_EQ("", message.optional_string());
+
+ message.set_allocated_optional_string(new string(kHello));
+ EXPECT_TRUE(message.has_optional_string());
+ EXPECT_EQ(kHello, message.optional_string());
+}
+
+TEST(GeneratedMessageTest, SetAllocatedMessage) {
+ // Check that set_allocated_foo() can be called in all cases.
+ unittest::TestAllTypes message;
+
+ EXPECT_FALSE(message.has_optional_nested_message());
+
+ message.mutable_optional_nested_message()->set_bb(1);
+ EXPECT_TRUE(message.has_optional_nested_message());
+
+ message.set_allocated_optional_nested_message(NULL);
+ EXPECT_FALSE(message.has_optional_nested_message());
+ EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &message.optional_nested_message());
+
+ message.mutable_optional_nested_message()->set_bb(1);
+ unittest::TestAllTypes::NestedMessage* nest =
+ message.release_optional_nested_message();
+ ASSERT_TRUE(nest != NULL);
+ EXPECT_FALSE(message.has_optional_nested_message());
+
+ message.set_allocated_optional_nested_message(nest);
+ EXPECT_TRUE(message.has_optional_nested_message());
+ EXPECT_EQ(1, message.optional_nested_message().bb());
+}
+
TEST(GeneratedMessageTest, Clear) {
// Set every field to a unique value, clear the message, then check that
// it is cleared.
@@ -282,6 +407,7 @@ TEST(GeneratedMessageTest, CopyFrom) {
TestUtil::ExpectAllFieldsSet(message2);
}
+
TEST(GeneratedMessageTest, SwapWithEmpty) {
unittest::TestAllTypes message1, message2;
TestUtil::SetAllFields(&message1);
@@ -376,10 +502,12 @@ TEST(GeneratedMessageTest, CopyAssignmentOperator) {
TestUtil::ExpectAllFieldsSet(message2);
// Make sure that self-assignment does something sane.
- message2 = message2;
+ message2.operator=(message2);
TestUtil::ExpectAllFieldsSet(message2);
}
+#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || \
+ !defined(GOOGLE_PROTOBUF_NO_RTTI)
TEST(GeneratedMessageTest, UpcastCopyFrom) {
// Test the CopyFrom method that takes in the generic const Message&
// parameter.
@@ -392,6 +520,7 @@ TEST(GeneratedMessageTest, UpcastCopyFrom) {
TestUtil::ExpectAllFieldsSet(message2);
}
+#endif
#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
@@ -443,7 +572,9 @@ TEST(GeneratedMessageTest, NonEmptyMergeFrom) {
TestUtil::ExpectAllFieldsSet(message1);
}
-#ifdef GTEST_HAS_DEATH_TEST
+#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || \
+ !defined(GOOGLE_PROTOBUF_NO_RTTI)
+#ifdef PROTOBUF_HAS_DEATH_TEST
TEST(GeneratedMessageTest, MergeFromSelf) {
unittest::TestAllTypes message;
@@ -452,7 +583,8 @@ TEST(GeneratedMessageTest, MergeFromSelf) {
"&from");
}
-#endif // GTEST_HAS_DEATH_TEST
+#endif // PROTOBUF_HAS_DEATH_TEST
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS || !GOOGLE_PROTOBUF_NO_RTTI
// Test the generated SerializeWithCachedSizesToArray(),
TEST(GeneratedMessageTest, SerializationToArray) {
@@ -645,6 +777,16 @@ TEST(GeneratedMessageTest, TestConflictingSymbolNames) {
message.set_friend_(5);
EXPECT_EQ(5, message.friend_());
+
+ message.set_class_(6);
+ EXPECT_EQ(6, message.class_());
+
+ // Instantiate extension template functions to test conflicting template
+ // parameter names.
+ typedef protobuf_unittest::TestConflictingSymbolNamesExtension ExtensionMessage;
+ message.AddExtension(ExtensionMessage::repeated_int32_ext, 123);
+ EXPECT_EQ(123,
+ message.GetExtension(ExtensionMessage::repeated_int32_ext, 0));
}
#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
@@ -716,8 +858,43 @@ TEST(GeneratedMessageTest, TestSpaceUsed) {
message1.SpaceUsed());
}
+TEST(GeneratedMessageTest, TestOneofSpaceUsed) {
+ unittest::TestOneof2 message1;
+ EXPECT_LE(sizeof(unittest::TestOneof2), message1.SpaceUsed());
+
+ const int empty_message_size = message1.SpaceUsed();
+ // Setting primitive types shouldn't affect the space used.
+ message1.set_foo_int(123);
+ message1.set_bar_int(12345);
+ EXPECT_EQ(empty_message_size, message1.SpaceUsed());
+
+ // Setting a string in oneof to a small value should only increase SpaceUsed()
+ // by the size of a string object.
+ message1.set_foo_string("abc");
+ EXPECT_LE(empty_message_size + sizeof(string), message1.SpaceUsed());
+
+ // Setting a string in oneof to a value larger than the string object itself
+ // should increase SpaceUsed(), because it cannot store the value internally.
+ message1.set_foo_string(string(sizeof(string) + 1, 'x'));
+ int min_expected_increase = message1.foo_string().capacity() +
+ sizeof(string);
+ EXPECT_LE(empty_message_size + min_expected_increase,
+ message1.SpaceUsed());
+
+ // Setting a message in oneof should delete the other fields and increase the
+ // size by the size of the nested message type. NestedMessage is simple enough
+ // that it is equal to sizeof(NestedMessage)
+ message1.mutable_foo_message();
+ ASSERT_EQ(sizeof(unittest::TestOneof2::NestedMessage),
+ message1.foo_message().SpaceUsed());
+ EXPECT_EQ(empty_message_size +
+ sizeof(unittest::TestOneof2::NestedMessage),
+ message1.SpaceUsed());
+}
+
#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
TEST(GeneratedMessageTest, FieldConstantValues) {
unittest::TestRequired message;
EXPECT_EQ(unittest::TestAllTypes_NestedMessage::kBbFieldNumber, 1);
@@ -762,6 +939,9 @@ TEST(GeneratedEnumTest, EnumValuesAsSwitchCases) {
case unittest::TestAllTypes::BAZ:
i = 3;
break;
+ case unittest::TestAllTypes::NEG:
+ i = -1;
+ break;
// no default case: We want to make sure the compiler recognizes that
// all cases are covered. (GCC warns if you do not cover all cases of
// an enum in a switch.)
@@ -790,7 +970,7 @@ TEST(GeneratedEnumTest, IsValidValue) {
}
TEST(GeneratedEnumTest, MinAndMax) {
- EXPECT_EQ(unittest::TestAllTypes::FOO,
+ EXPECT_EQ(unittest::TestAllTypes::NEG,
unittest::TestAllTypes::NestedEnum_MIN);
EXPECT_EQ(unittest::TestAllTypes::BAZ,
unittest::TestAllTypes::NestedEnum_MAX);
@@ -809,20 +989,19 @@ TEST(GeneratedEnumTest, MinAndMax) {
EXPECT_EQ(12589235, unittest::TestSparseEnum_ARRAYSIZE);
// Make sure we can take the address of _MIN, _MAX and _ARRAYSIZE.
- void* nullptr = 0; // NULL may be integer-type, not pointer-type.
- EXPECT_NE(nullptr, &unittest::TestAllTypes::NestedEnum_MIN);
- EXPECT_NE(nullptr, &unittest::TestAllTypes::NestedEnum_MAX);
- EXPECT_NE(nullptr, &unittest::TestAllTypes::NestedEnum_ARRAYSIZE);
+ void* null_pointer = 0; // NULL may be integer-type, not pointer-type.
+ EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_MIN);
+ EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_MAX);
+ EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_ARRAYSIZE);
- EXPECT_NE(nullptr, &unittest::ForeignEnum_MIN);
- EXPECT_NE(nullptr, &unittest::ForeignEnum_MAX);
- EXPECT_NE(nullptr, &unittest::ForeignEnum_ARRAYSIZE);
+ EXPECT_NE(null_pointer, &unittest::ForeignEnum_MIN);
+ EXPECT_NE(null_pointer, &unittest::ForeignEnum_MAX);
+ EXPECT_NE(null_pointer, &unittest::ForeignEnum_ARRAYSIZE);
- // Make sure we can use _MIN, _MAX and _ARRAYSIZE as switch cases.
+ // Make sure we can use _MIN and _MAX as switch cases.
switch (unittest::SPARSE_A) {
case unittest::TestSparseEnum_MIN:
case unittest::TestSparseEnum_MAX:
- case unittest::TestSparseEnum_ARRAYSIZE:
break;
default:
break;
@@ -865,6 +1044,20 @@ TEST(GeneratedEnumTest, GetEnumDescriptor) {
GetEnumDescriptor<unittest::TestSparseEnum>());
}
+enum NonProtoEnum {
+ kFoo = 1,
+};
+
+TEST(GeneratedEnumTest, IsProtoEnumTypeTrait) {
+ EXPECT_TRUE(is_proto_enum<unittest::TestAllTypes::NestedEnum>::value);
+ EXPECT_TRUE(is_proto_enum<unittest::ForeignEnum>::value);
+ EXPECT_TRUE(is_proto_enum<unittest::TestEnumWithDupValue>::value);
+ EXPECT_TRUE(is_proto_enum<unittest::TestSparseEnum>::value);
+
+ EXPECT_FALSE(is_proto_enum<int>::value);
+ EXPECT_FALSE(is_proto_enum<NonProtoEnum>::value);
+}
+
#endif // PROTOBUF_TEST_NO_DESCRIPTORS
// ===================================================================
@@ -1079,7 +1272,7 @@ TEST_F(GeneratedServiceTest, CallMethod) {
TEST_F(GeneratedServiceTest, CallMethodTypeFailure) {
// Verify death if we call Foo() with Bar's message types.
-#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet
+#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet
EXPECT_DEBUG_DEATH(
mock_service_.CallMethod(foo_, &mock_controller_,
&foo_request_, &bar_response_, done_.get()),
@@ -1090,7 +1283,7 @@ TEST_F(GeneratedServiceTest, CallMethodTypeFailure) {
mock_service_.CallMethod(foo_, &mock_controller_,
&bar_request_, &foo_response_, done_.get()),
"dynamic_cast");
-#endif // GTEST_HAS_DEATH_TEST
+#endif // PROTOBUF_HAS_DEATH_TEST
}
TEST_F(GeneratedServiceTest, GetPrototypes) {
@@ -1164,6 +1357,657 @@ TEST_F(GeneratedServiceTest, NotImplemented) {
EXPECT_TRUE(controller.called_);
}
+// ===================================================================
+
+class OneofTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ }
+
+ void ExpectEnumCasesWork(const unittest::TestOneof2 &message) {
+ switch (message.foo_case()) {
+ case unittest::TestOneof2::kFooInt:
+ EXPECT_TRUE(message.has_foo_int());
+ break;
+ case unittest::TestOneof2::kFooString:
+ EXPECT_TRUE(message.has_foo_string());
+ break;
+ case unittest::TestOneof2::kFooBytes:
+ EXPECT_TRUE(message.has_foo_bytes());
+ break;
+ case unittest::TestOneof2::kFooEnum:
+ EXPECT_TRUE(message.has_foo_enum());
+ break;
+ case unittest::TestOneof2::kFooMessage:
+ EXPECT_TRUE(message.has_foo_message());
+ break;
+ case unittest::TestOneof2::kFoogroup:
+ EXPECT_TRUE(message.has_foogroup());
+ break;
+ case unittest::TestOneof2::FOO_NOT_SET:
+ break;
+ }
+ }
+};
+
+TEST_F(OneofTest, SettingOneFieldClearsOthers) {
+ unittest::TestOneof2 message;
+
+ message.set_foo_int(123);
+ EXPECT_TRUE(message.has_foo_int());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+ message.set_foo_string("foo");
+ EXPECT_TRUE(message.has_foo_string());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+
+ message.set_foo_bytes("qux");
+ EXPECT_TRUE(message.has_foo_bytes());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+ message.set_foo_enum(unittest::TestOneof2::FOO);
+ EXPECT_TRUE(message.has_foo_enum());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+ message.mutable_foo_message()->set_qux_int(234);
+ EXPECT_TRUE(message.has_foo_message());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+ message.mutable_foogroup()->set_a(345);
+ EXPECT_TRUE(message.has_foogroup());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+
+ // we repeat this because we didn't test if this properly clears other fields
+ // at the beginning.
+ message.set_foo_int(123);
+ EXPECT_TRUE(message.has_foo_int());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+}
+
+TEST_F(OneofTest, EnumCases) {
+ unittest::TestOneof2 message;
+
+ message.set_foo_int(123);
+ ExpectEnumCasesWork(message);
+ message.set_foo_string("foo");
+ ExpectEnumCasesWork(message);
+ message.set_foo_bytes("qux");
+ ExpectEnumCasesWork(message);
+ message.set_foo_enum(unittest::TestOneof2::FOO);
+ ExpectEnumCasesWork(message);
+ message.mutable_foo_message()->set_qux_int(234);
+ ExpectEnumCasesWork(message);
+ message.mutable_foogroup()->set_a(345);
+ ExpectEnumCasesWork(message);
+}
+
+TEST_F(OneofTest, PrimitiveType) {
+ unittest::TestOneof2 message;
+ // Unset field returns default value
+ EXPECT_EQ(message.foo_int(), 0);
+
+ message.set_foo_int(123);
+ EXPECT_TRUE(message.has_foo_int());
+ EXPECT_EQ(message.foo_int(), 123);
+ message.clear_foo_int();
+ EXPECT_FALSE(message.has_foo_int());
+}
+
+TEST_F(OneofTest, EnumType) {
+ unittest::TestOneof2 message;
+ // Unset field returns default value
+ EXPECT_EQ(message.foo_enum(), 1);
+
+ message.set_foo_enum(unittest::TestOneof2::FOO);
+ EXPECT_TRUE(message.has_foo_enum());
+ EXPECT_EQ(message.foo_enum(), unittest::TestOneof2::FOO);
+ message.clear_foo_enum();
+ EXPECT_FALSE(message.has_foo_enum());
+}
+
+TEST_F(OneofTest, SetString) {
+ // Check that setting a string field in various ways works
+ unittest::TestOneof2 message;
+
+ // Unset field returns default value
+ EXPECT_EQ(message.foo_string(), "");
+
+ message.set_foo_string("foo");
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "foo");
+ message.clear_foo_string();
+ EXPECT_FALSE(message.has_foo_string());
+
+ message.set_foo_string(string("bar"));
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "bar");
+ message.clear_foo_string();
+ EXPECT_FALSE(message.has_foo_string());
+
+
+ message.set_foo_string("qux", 3);
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "qux");
+ message.clear_foo_string();
+ EXPECT_FALSE(message.has_foo_string());
+
+ message.mutable_foo_string()->assign("quux");
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "quux");
+ message.clear_foo_string();
+ EXPECT_FALSE(message.has_foo_string());
+
+ message.set_foo_string("corge");
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "corge");
+ message.clear_foo_string();
+ EXPECT_FALSE(message.has_foo_string());
+}
+
+TEST_F(OneofTest, ReleaseString) {
+ // Check that release_foo() starts out NULL, and gives us a value
+ // that we can delete after it's been set.
+ unittest::TestOneof2 message;
+
+ EXPECT_EQ(NULL, message.release_foo_string());
+ EXPECT_FALSE(message.has_foo_string());
+
+ message.set_foo_string("blah");
+ EXPECT_TRUE(message.has_foo_string());
+ scoped_ptr<string> str(message.release_foo_string());
+ EXPECT_FALSE(message.has_foo_string());
+ ASSERT_TRUE(str != NULL);
+ EXPECT_EQ("blah", *str);
+
+ EXPECT_EQ(NULL, message.release_foo_string());
+ EXPECT_FALSE(message.has_foo_string());
+}
+
+TEST_F(OneofTest, SetAllocatedString) {
+ // Check that set_allocated_foo() works for strings.
+ unittest::TestOneof2 message;
+
+ EXPECT_FALSE(message.has_foo_string());
+ const string kHello("hello");
+ message.set_foo_string(kHello);
+ EXPECT_TRUE(message.has_foo_string());
+
+ message.set_allocated_foo_string(NULL);
+ EXPECT_FALSE(message.has_foo_string());
+ EXPECT_EQ("", message.foo_string());
+
+ message.set_allocated_foo_string(new string(kHello));
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(kHello, message.foo_string());
+}
+
+
+TEST_F(OneofTest, SetMessage) {
+ // Check that setting a message field works
+ unittest::TestOneof2 message;
+
+ // Unset field returns default instance
+ EXPECT_EQ(&message.foo_message(),
+ &unittest::TestOneof2_NestedMessage::default_instance());
+ EXPECT_EQ(message.foo_message().qux_int(), 0);
+
+ message.mutable_foo_message()->set_qux_int(234);
+ EXPECT_TRUE(message.has_foo_message());
+ EXPECT_EQ(message.foo_message().qux_int(), 234);
+ message.clear_foo_message();
+ EXPECT_FALSE(message.has_foo_message());
+}
+
+TEST_F(OneofTest, ReleaseMessage) {
+ // Check that release_foo() starts out NULL, and gives us a value
+ // that we can delete after it's been set.
+ unittest::TestOneof2 message;
+
+ EXPECT_EQ(NULL, message.release_foo_message());
+ EXPECT_FALSE(message.has_foo_message());
+
+ message.mutable_foo_message()->set_qux_int(1);
+ EXPECT_TRUE(message.has_foo_message());
+ scoped_ptr<unittest::TestOneof2_NestedMessage> mes(
+ message.release_foo_message());
+ EXPECT_FALSE(message.has_foo_message());
+ ASSERT_TRUE(mes != NULL);
+ EXPECT_EQ(1, mes->qux_int());
+
+ EXPECT_EQ(NULL, message.release_foo_message());
+ EXPECT_FALSE(message.has_foo_message());
+}
+
+TEST_F(OneofTest, SetAllocatedMessage) {
+ // Check that set_allocated_foo() works for messages.
+ unittest::TestOneof2 message;
+
+ EXPECT_FALSE(message.has_foo_message());
+
+ message.mutable_foo_message()->set_qux_int(1);
+ EXPECT_TRUE(message.has_foo_message());
+
+ message.set_allocated_foo_message(NULL);
+ EXPECT_FALSE(message.has_foo_message());
+ EXPECT_EQ(&message.foo_message(),
+ &unittest::TestOneof2_NestedMessage::default_instance());
+
+ message.mutable_foo_message()->set_qux_int(1);
+ unittest::TestOneof2_NestedMessage* mes = message.release_foo_message();
+ ASSERT_TRUE(mes != NULL);
+ EXPECT_FALSE(message.has_foo_message());
+
+ message.set_allocated_foo_message(mes);
+ EXPECT_TRUE(message.has_foo_message());
+ EXPECT_EQ(1, message.foo_message().qux_int());
+}
+
+
+TEST_F(OneofTest, Clear) {
+ unittest::TestOneof2 message;
+
+ message.set_foo_int(1);
+ EXPECT_TRUE(message.has_foo_int());
+ message.clear_foo_int();
+ EXPECT_FALSE(message.has_foo_int());
+}
+
+TEST_F(OneofTest, Defaults) {
+ unittest::TestOneof2 message;
+
+ EXPECT_FALSE(message.has_foo_int());
+ EXPECT_EQ(message.foo_int(), 0);
+
+ EXPECT_FALSE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "");
+
+
+ EXPECT_FALSE(message.has_foo_bytes());
+ EXPECT_EQ(message.foo_bytes(), "");
+
+ EXPECT_FALSE(message.has_foo_enum());
+ EXPECT_EQ(message.foo_enum(), 1);
+
+ EXPECT_FALSE(message.has_foo_message());
+ EXPECT_EQ(message.foo_message().qux_int(), 0);
+
+ EXPECT_FALSE(message.has_foogroup());
+ EXPECT_EQ(message.foogroup().a(), 0);
+
+
+ EXPECT_FALSE(message.has_bar_int());
+ EXPECT_EQ(message.bar_int(), 5);
+
+ EXPECT_FALSE(message.has_bar_string());
+ EXPECT_EQ(message.bar_string(), "STRING");
+
+
+ EXPECT_FALSE(message.has_bar_bytes());
+ EXPECT_EQ(message.bar_bytes(), "BYTES");
+
+ EXPECT_FALSE(message.has_bar_enum());
+ EXPECT_EQ(message.bar_enum(), 2);
+}
+
+TEST_F(OneofTest, SwapWithEmpty) {
+ unittest::TestOneof2 message1, message2;
+ message1.set_foo_string("FOO");
+ EXPECT_TRUE(message1.has_foo_string());
+ message1.Swap(&message2);
+ EXPECT_FALSE(message1.has_foo_string());
+ EXPECT_TRUE(message2.has_foo_string());
+ EXPECT_EQ(message2.foo_string(), "FOO");
+}
+
+TEST_F(OneofTest, SwapWithSelf) {
+ unittest::TestOneof2 message;
+ message.set_foo_string("FOO");
+ EXPECT_TRUE(message.has_foo_string());
+ message.Swap(&message);
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "FOO");
+}
+
+TEST_F(OneofTest, SwapBothHasFields) {
+ unittest::TestOneof2 message1, message2;
+
+ message1.set_foo_string("FOO");
+ EXPECT_TRUE(message1.has_foo_string());
+ message2.mutable_foo_message()->set_qux_int(1);
+ EXPECT_TRUE(message2.has_foo_message());
+
+ message1.Swap(&message2);
+ EXPECT_FALSE(message1.has_foo_string());
+ EXPECT_FALSE(message2.has_foo_message());
+ EXPECT_TRUE(message1.has_foo_message());
+ EXPECT_EQ(message1.foo_message().qux_int(), 1);
+ EXPECT_TRUE(message2.has_foo_string());
+ EXPECT_EQ(message2.foo_string(), "FOO");
+}
+
+TEST_F(OneofTest, CopyContructor) {
+ unittest::TestOneof2 message1;
+ message1.set_foo_bytes("FOO");
+
+ unittest::TestOneof2 message2(message1);
+ EXPECT_TRUE(message2.has_foo_bytes());
+ EXPECT_EQ(message2.foo_bytes(), "FOO");
+}
+
+TEST_F(OneofTest, CopyFrom) {
+ unittest::TestOneof2 message1, message2;
+ message1.set_foo_enum(unittest::TestOneof2::BAR);
+ EXPECT_TRUE(message1.has_foo_enum());
+
+ message2.CopyFrom(message1);
+ EXPECT_TRUE(message2.has_foo_enum());
+ EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::BAR);
+
+ // Copying from self should be a no-op.
+ message2.CopyFrom(message2);
+ EXPECT_TRUE(message2.has_foo_enum());
+ EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::BAR);
+}
+
+TEST_F(OneofTest, CopyAssignmentOperator) {
+ unittest::TestOneof2 message1;
+ message1.mutable_foo_message()->set_qux_int(123);
+ EXPECT_TRUE(message1.has_foo_message());
+
+ unittest::TestOneof2 message2;
+ message2 = message1;
+ EXPECT_EQ(message2.foo_message().qux_int(), 123);
+
+ // Make sure that self-assignment does something sane.
+ message2 = message2;
+ EXPECT_EQ(message2.foo_message().qux_int(), 123);
+}
+
+TEST_F(OneofTest, UpcastCopyFrom) {
+ // Test the CopyFrom method that takes in the generic const Message&
+ // parameter.
+ unittest::TestOneof2 message1, message2;
+ message1.mutable_foogroup()->set_a(123);
+ EXPECT_TRUE(message1.has_foogroup());
+
+ const Message* source = implicit_cast<const Message*>(&message1);
+ message2.CopyFrom(*source);
+
+ EXPECT_TRUE(message2.has_foogroup());
+ EXPECT_EQ(message2.foogroup().a(), 123);
+}
+
+// Test the generated SerializeWithCachedSizesToArray(),
+// This indirectly tests MergePartialFromCodedStream()
+// We have to test each field type separately because we cannot set them at the
+// same time
+TEST_F(OneofTest, SerializationToArray) {
+ // Primitive type
+ {
+ unittest::TestOneof2 message1, message2;
+ string data;
+ message1.set_foo_int(123);
+ int size = message1.ByteSize();
+ data.resize(size);
+ uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+ uint8* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_int(), 123);
+ }
+
+ // String
+ {
+ unittest::TestOneof2 message1, message2;
+ string data;
+ message1.set_foo_string("foo");
+ int size = message1.ByteSize();
+ data.resize(size);
+ uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+ uint8* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_string(), "foo");
+ }
+
+
+ // Bytes
+ {
+ unittest::TestOneof2 message1, message2;
+ string data;
+ message1.set_foo_bytes("qux");
+ int size = message1.ByteSize();
+ data.resize(size);
+ uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+ uint8* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_bytes(), "qux");
+ }
+
+ // Enum
+ {
+ unittest::TestOneof2 message1, message2;
+ string data;
+ message1.set_foo_enum(unittest::TestOneof2::FOO);
+ int size = message1.ByteSize();
+ data.resize(size);
+ uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+ uint8* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::FOO);
+ }
+
+ // Message
+ {
+ unittest::TestOneof2 message1, message2;
+ string data;
+ message1.mutable_foo_message()->set_qux_int(234);
+ int size = message1.ByteSize();
+ data.resize(size);
+ uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+ uint8* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_message().qux_int(), 234);
+ }
+
+ // Group
+ {
+ unittest::TestOneof2 message1, message2;
+ string data;
+ message1.mutable_foogroup()->set_a(345);
+ int size = message1.ByteSize();
+ data.resize(size);
+ uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+ uint8* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foogroup().a(), 345);
+ }
+
+}
+
+// Test the generated SerializeWithCachedSizes() by forcing the buffer to write
+// one byte at a time.
+// This indirectly tests MergePartialFromCodedStream()
+// We have to test each field type separately because we cannot set them at the
+// same time
+TEST_F(OneofTest, SerializationToStream) {
+ // Primitive type
+ {
+ unittest::TestOneof2 message1, message2;
+ string data;
+ message1.set_foo_int(123);
+ int size = message1.ByteSize();
+ data.resize(size);
+
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_int(), 123);
+ }
+
+ // String
+ {
+ unittest::TestOneof2 message1, message2;
+ string data;
+ message1.set_foo_string("foo");
+ int size = message1.ByteSize();
+ data.resize(size);
+
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_string(), "foo");
+ }
+
+
+ // Bytes
+ {
+ unittest::TestOneof2 message1, message2;
+ string data;
+ message1.set_foo_bytes("qux");
+ int size = message1.ByteSize();
+ data.resize(size);
+
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_bytes(), "qux");
+ }
+
+ // Enum
+ {
+ unittest::TestOneof2 message1, message2;
+ string data;
+ message1.set_foo_enum(unittest::TestOneof2::FOO);
+ int size = message1.ByteSize();
+ data.resize(size);
+
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::FOO);
+ }
+
+ // Message
+ {
+ unittest::TestOneof2 message1, message2;
+ string data;
+ message1.mutable_foo_message()->set_qux_int(234);
+ int size = message1.ByteSize();
+ data.resize(size);
+
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_message().qux_int(), 234);
+ }
+
+ // Group
+ {
+ unittest::TestOneof2 message1, message2;
+ string data;
+ message1.mutable_foogroup()->set_a(345);
+ int size = message1.ByteSize();
+ data.resize(size);
+
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foogroup().a(), 345);
+ }
+
+}
+
+TEST_F(OneofTest, MergeFrom) {
+ unittest::TestOneof2 message1, message2;
+
+ message1.set_foo_int(123);
+ message2.MergeFrom(message1);
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+ EXPECT_TRUE(message2.has_foo_int());
+ EXPECT_EQ(message2.foo_int(), 123);
+
+ message1.set_foo_string("foo");
+ message2.MergeFrom(message1);
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+ EXPECT_TRUE(message2.has_foo_string());
+ EXPECT_EQ(message2.foo_string(), "foo");
+
+
+ message1.set_foo_bytes("qux");
+ message2.MergeFrom(message1);
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+ EXPECT_TRUE(message2.has_foo_bytes());
+ EXPECT_EQ(message2.foo_bytes(), "qux");
+
+ message1.set_foo_enum(unittest::TestOneof2::FOO);
+ message2.MergeFrom(message1);
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+ EXPECT_TRUE(message2.has_foo_enum());
+ EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::FOO);
+
+ message1.mutable_foo_message()->set_qux_int(234);
+ message2.MergeFrom(message1);
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+ EXPECT_TRUE(message2.has_foo_message());
+ EXPECT_EQ(message2.foo_message().qux_int(), 234);
+
+ message1.mutable_foogroup()->set_a(345);
+ message2.MergeFrom(message1);
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+ EXPECT_TRUE(message2.has_foogroup());
+ EXPECT_EQ(message2.foogroup().a(), 345);
+
+}
+
} // namespace cpp_unittest
} // namespace cpp
} // namespace compiler
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.h b/src/google/protobuf/compiler/cpp/cpp_unittest.h
new file mode 100644
index 0000000..69c8f44
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.h
@@ -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.
+
+// This header declares the namespace google::protobuf::protobuf_unittest in order to expose
+// any problems with the generated class names. We use this header to ensure
+// unittest.cc will declare the namespace prior to other includes, while obeying
+// normal include ordering.
+//
+// When generating a class name of "foo.Bar" we must ensure we prefix the class
+// name with "::", in case the namespace google::protobuf::foo exists. We intentionally
+// trigger that case here by declaring google::protobuf::protobuf_unittest.
+//
+// See ClassName in helpers.h for more details.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
+
+namespace google {
+namespace protobuf {
+namespace protobuf_unittest {}
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc
index 7689ce9..e6c446a 100644
--- a/src/google/protobuf/compiler/importer.cc
+++ b/src/google/protobuf/compiler/importer.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -43,6 +43,7 @@
#include <errno.h>
#include <algorithm>
+#include <memory>
#include <google/protobuf/compiler/importer.h>
@@ -124,7 +125,8 @@ bool SourceTreeDescriptorDatabase::FindFileByName(
scoped_ptr<io::ZeroCopyInputStream> input(source_tree_->Open(filename));
if (input == NULL) {
if (error_collector_ != NULL) {
- error_collector_->AddError(filename, -1, 0, "File not found.");
+ error_collector_->AddError(filename, -1, 0,
+ source_tree_->GetLastErrorMessage());
}
return false;
}
@@ -186,6 +188,7 @@ Importer::Importer(SourceTree* source_tree,
MultiFileErrorCollector* error_collector)
: database_(source_tree),
pool_(&database_, database_.GetValidationErrorCollector()) {
+ pool_.EnforceWeakDependencies(true);
database_.RecordErrorsTo(error_collector);
}
@@ -195,10 +198,22 @@ const FileDescriptor* Importer::Import(const string& filename) {
return pool_.FindFileByName(filename);
}
+void Importer::AddUnusedImportTrackFile(const string& file_name) {
+ pool_.AddUnusedImportTrackFile(file_name);
+}
+
+void Importer::ClearUnusedImportTrackFiles() {
+ pool_.ClearUnusedImportTrackFiles();
+}
+
// ===================================================================
SourceTree::~SourceTree() {}
+string SourceTree::GetLastErrorMessage() {
+ return "File not found.";
+}
+
DiskSourceTree::DiskSourceTree() {}
DiskSourceTree::~DiskSourceTree() {}
@@ -231,12 +246,17 @@ static string CanonicalizePath(string path) {
// The Win32 API accepts forward slashes as a path delimiter even though
// backslashes are standard. Let's avoid confusion and use only forward
// slashes.
- path = StringReplace(path, "\\", "/", true);
+ if (HasPrefixString(path, "\\\\")) {
+ // Avoid converting two leading backslashes.
+ path = "\\\\" + StringReplace(path.substr(2), "\\", "/", true);
+ } else {
+ path = StringReplace(path, "\\", "/", true);
+ }
#endif
- vector<string> parts;
vector<string> canonical_parts;
- SplitStringUsing(path, "/", &parts); // Note: Removes empty parts.
+ vector<string> parts = Split(
+ path, "/", true); // Note: Removes empty parts.
for (int i = 0; i < parts.size(); i++) {
if (parts[i] == ".") {
// Ignore.
@@ -244,7 +264,7 @@ static string CanonicalizePath(string path) {
canonical_parts.push_back(parts[i]);
}
}
- string result = JoinStrings(canonical_parts, "/");
+ string result = Join(canonical_parts, "/");
if (!path.empty() && path[0] == '/') {
// Restore leading slash.
result = '/' + result;
@@ -390,8 +410,8 @@ DiskSourceTree::DiskFileToVirtualFile(
bool DiskSourceTree::VirtualFileToDiskFile(const string& virtual_file,
string* disk_file) {
- scoped_ptr<io::ZeroCopyInputStream> stream(OpenVirtualFile(virtual_file,
- disk_file));
+ scoped_ptr<io::ZeroCopyInputStream> stream(
+ OpenVirtualFile(virtual_file, disk_file));
return stream != NULL;
}
@@ -399,6 +419,10 @@ io::ZeroCopyInputStream* DiskSourceTree::Open(const string& filename) {
return OpenVirtualFile(filename, NULL);
}
+string DiskSourceTree::GetLastErrorMessage() {
+ return last_error_message_;
+}
+
io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile(
const string& virtual_file,
string* disk_file) {
@@ -407,6 +431,8 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile(
// We do not allow importing of paths containing things like ".." or
// consecutive slashes since the compiler expects files to be uniquely
// identified by file name.
+ last_error_message_ = "Backslashes, consecutive slashes, \".\", or \"..\" "
+ "are not allowed in the virtual path";
return NULL;
}
@@ -424,13 +450,13 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile(
if (errno == EACCES) {
// The file exists but is not readable.
- // TODO(kenton): Find a way to report this more nicely.
- GOOGLE_LOG(WARNING) << "Read access is denied for file: " << temp_disk_file;
+ last_error_message_ = "Read access is denied for file: " +
+ temp_disk_file;
return NULL;
}
}
}
-
+ last_error_message_ = "File not found.";
return NULL;
}
diff --git a/src/google/protobuf/compiler/importer.h b/src/google/protobuf/compiler/importer.h
index 7a2efc2..f010fd0 100644
--- a/src/google/protobuf/compiler/importer.h
+++ b/src/google/protobuf/compiler/importer.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -166,6 +166,9 @@ class LIBPROTOBUF_EXPORT Importer {
return &pool_;
}
+ void AddUnusedImportTrackFile(const string& file_name);
+ void ClearUnusedImportTrackFiles();
+
private:
SourceTreeDescriptorDatabase database_;
DescriptorPool pool_;
@@ -204,6 +207,13 @@ class LIBPROTOBUF_EXPORT SourceTree {
// contain "." or ".." components.
virtual io::ZeroCopyInputStream* Open(const string& filename) = 0;
+ // If Open() returns NULL, calling this method immediately will return an
+ // description of the error.
+ // Subclasses should implement this method and return a meaningful value for
+ // better error reporting.
+ // TODO(xiaofeng): change this to a pure virtual function.
+ virtual string GetLastErrorMessage();
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceTree);
};
@@ -273,17 +283,21 @@ class LIBPROTOBUF_EXPORT DiskSourceTree : public SourceTree {
bool VirtualFileToDiskFile(const string& virtual_file, string* disk_file);
// implements SourceTree -------------------------------------------
- io::ZeroCopyInputStream* Open(const string& filename);
+ virtual io::ZeroCopyInputStream* Open(const string& filename);
+
+ virtual string GetLastErrorMessage();
private:
struct Mapping {
string virtual_path;
string disk_path;
- inline Mapping(const string& virtual_path, const string& disk_path)
- : virtual_path(virtual_path), disk_path(disk_path) {}
+ inline Mapping(const string& virtual_path_param,
+ const string& disk_path_param)
+ : virtual_path(virtual_path_param), disk_path(disk_path_param) {}
};
vector<Mapping> mappings_;
+ string last_error_message_;
// Like Open(), but returns the on-disk path in disk_file if disk_file is
// non-NULL and the file could be successfully opened.
diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc
index 56fad56..387f135 100644
--- a/src/google/protobuf/compiler/importer_unittest.cc
+++ b/src/google/protobuf/compiler/importer_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,12 +33,13 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/stubs/hash.h>
+#include <memory>
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
-#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/map_util.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/stubs/strutil.h>
@@ -92,6 +93,10 @@ class MockSourceTree : public SourceTree {
}
}
+ string GetLastErrorMessage() {
+ return "File not found.";
+ }
+
private:
hash_map<string, const char*> files_;
};
@@ -324,6 +329,7 @@ TEST_F(ImporterTest, MapFieldKeyNotScalar) {
EXPECT_SUBSTRING("must name a scalar or string", error());
}
+
// ===================================================================
class DiskSourceTreeTest : public testing::Test {
@@ -336,7 +342,7 @@ class DiskSourceTreeTest : public testing::Test {
if (File::Exists(dirnames_[i])) {
File::DeleteRecursively(dirnames_[i], NULL, NULL);
}
- GOOGLE_CHECK(File::CreateDir(dirnames_[i].c_str(), DEFAULT_FILE_MODE));
+ GOOGLE_CHECK_OK(File::CreateDir(dirnames_[i], 0777));
}
}
@@ -347,11 +353,11 @@ class DiskSourceTreeTest : public testing::Test {
}
void AddFile(const string& filename, const char* contents) {
- File::WriteStringToFileOrDie(contents, filename);
+ GOOGLE_CHECK_OK(File::SetContents(filename, contents, true));
}
void AddSubdir(const string& dirname) {
- GOOGLE_CHECK(File::CreateDir(dirname.c_str(), DEFAULT_FILE_MODE));
+ GOOGLE_CHECK_OK(File::CreateDir(dirname, 0777));
}
void ExpectFileContents(const string& filename,
@@ -371,9 +377,11 @@ class DiskSourceTreeTest : public testing::Test {
EXPECT_EQ(expected_contents, file_contents);
}
- void ExpectFileNotFound(const string& filename) {
+ void ExpectCannotOpenFile(const string& filename,
+ const string& error_message) {
scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename));
EXPECT_TRUE(input == NULL);
+ EXPECT_EQ(error_message, source_tree_.GetLastErrorMessage());
}
DiskSourceTree source_tree_;
@@ -389,7 +397,7 @@ TEST_F(DiskSourceTreeTest, MapRoot) {
source_tree_.MapPath("", dirnames_[0]);
ExpectFileContents("foo", "Hello World!");
- ExpectFileNotFound("bar");
+ ExpectCannotOpenFile("bar", "File not found.");
}
TEST_F(DiskSourceTreeTest, MapDirectory) {
@@ -400,15 +408,21 @@ TEST_F(DiskSourceTreeTest, MapDirectory) {
source_tree_.MapPath("baz", dirnames_[0]);
ExpectFileContents("baz/foo", "Hello World!");
- ExpectFileNotFound("baz/bar");
- ExpectFileNotFound("foo");
- ExpectFileNotFound("bar");
+ ExpectCannotOpenFile("baz/bar", "File not found.");
+ ExpectCannotOpenFile("foo", "File not found.");
+ ExpectCannotOpenFile("bar", "File not found.");
// Non-canonical file names should not work.
- ExpectFileNotFound("baz//foo");
- ExpectFileNotFound("baz/../baz/foo");
- ExpectFileNotFound("baz/./foo");
- ExpectFileNotFound("baz/foo/");
+ ExpectCannotOpenFile("baz//foo",
+ "Backslashes, consecutive slashes, \".\", or \"..\" are "
+ "not allowed in the virtual path");
+ ExpectCannotOpenFile("baz/../baz/foo",
+ "Backslashes, consecutive slashes, \".\", or \"..\" are "
+ "not allowed in the virtual path");
+ ExpectCannotOpenFile("baz/./foo",
+ "Backslashes, consecutive slashes, \".\", or \"..\" are "
+ "not allowed in the virtual path");
+ ExpectCannotOpenFile("baz/foo/", "File not found.");
}
TEST_F(DiskSourceTreeTest, NoParent) {
@@ -420,8 +434,12 @@ TEST_F(DiskSourceTreeTest, NoParent) {
source_tree_.MapPath("", dirnames_[0] + "/bar");
ExpectFileContents("baz", "Blah.");
- ExpectFileNotFound("../foo");
- ExpectFileNotFound("../bar/baz");
+ ExpectCannotOpenFile("../foo",
+ "Backslashes, consecutive slashes, \".\", or \"..\" are "
+ "not allowed in the virtual path");
+ ExpectCannotOpenFile("../bar/baz",
+ "Backslashes, consecutive slashes, \".\", or \"..\" are "
+ "not allowed in the virtual path");
}
TEST_F(DiskSourceTreeTest, MapFile) {
@@ -431,7 +449,7 @@ TEST_F(DiskSourceTreeTest, MapFile) {
source_tree_.MapPath("foo", dirnames_[0] + "/foo");
ExpectFileContents("foo", "Hello World!");
- ExpectFileNotFound("bar");
+ ExpectCannotOpenFile("bar", "File not found.");
}
TEST_F(DiskSourceTreeTest, SearchMultipleDirectories) {
@@ -445,7 +463,7 @@ TEST_F(DiskSourceTreeTest, SearchMultipleDirectories) {
ExpectFileContents("foo", "Hello World!");
ExpectFileContents("bar", "Goodbye World!");
- ExpectFileNotFound("baz");
+ ExpectCannotOpenFile("baz", "File not found.");
}
TEST_F(DiskSourceTreeTest, OrderingTrumpsSpecificity) {
@@ -453,8 +471,7 @@ TEST_F(DiskSourceTreeTest, OrderingTrumpsSpecificity) {
// directory is more-specific than a former one.
// Create the "bar" directory so we can put a file in it.
- ASSERT_TRUE(File::CreateDir((dirnames_[0] + "/bar").c_str(),
- DEFAULT_FILE_MODE));
+ GOOGLE_CHECK_OK(File::CreateDir(dirnames_[0] + "/bar", 0777));
// Add files and map paths.
AddFile(dirnames_[0] + "/bar/foo", "Hello World!");
diff --git a/src/google/protobuf/compiler/java/java_context.cc b/src/google/protobuf/compiler/java/java_context.cc
new file mode 100644
index 0000000..7d21fe6
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_context.cc
@@ -0,0 +1,195 @@
+// 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_context.h>
+
+#include <google/protobuf/compiler/java/java_field.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/map_util.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+Context::Context(const FileDescriptor* file)
+ : name_resolver_(new ClassNameResolver) {
+ InitializeFieldGeneratorInfo(file);
+}
+
+Context::~Context() {
+}
+
+ClassNameResolver* Context::GetNameResolver() {
+ return name_resolver_.get();
+}
+
+namespace {
+// Whether two fields have conflicting accessors (assuming name1 and name2
+// are different). name1 and name2 are field1 and field2's camel-case name
+// respectively.
+bool IsConflicting(const FieldDescriptor* field1, const string& name1,
+ const FieldDescriptor* field2, const string& name2,
+ string* info) {
+ if (field1->is_repeated()) {
+ if (field2->is_repeated()) {
+ // Both fields are repeated.
+ return false;
+ } else {
+ // field1 is repeated, and field2 is not.
+ if (name1 + "Count" == name2) {
+ *info = "both repeated field \"" + field1->name() + "\" and singular " +
+ "field \"" + field2->name() + "\" generates the method \"" +
+ "get" + name1 + "Count()\"";
+ return true;
+ }
+ if (name1 + "List" == name2) {
+ *info = "both repeated field \"" + field1->name() + "\" and singular " +
+ "field \"" + field2->name() + "\" generates the method \"" +
+ "get" + name1 + "List()\"";
+ return true;
+ }
+ // Well, there are obviously many more conflicting cases, but it probably
+ // doesn't worth the effort to exhaust all of them because they rarely
+ // happen and as we are continuing adding new methods/changing existing
+ // methods the number of different conflicting cases will keep growing.
+ // We can just add more cases here when they are found in the real world.
+ return false;
+ }
+ } else {
+ if (field2->is_repeated()) {
+ return IsConflicting(field2, name2, field1, name1, info);
+ } else {
+ // None of the two fields are repeated.
+ return false;
+ }
+ }
+}
+} // namespace
+
+void Context::InitializeFieldGeneratorInfo(const FileDescriptor* file) {
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ InitializeFieldGeneratorInfoForMessage(file->message_type(i));
+ }
+}
+
+void Context::InitializeFieldGeneratorInfoForMessage(
+ const Descriptor* message) {
+ for (int i = 0; i < message->nested_type_count(); ++i) {
+ InitializeFieldGeneratorInfoForMessage(message->nested_type(i));
+ }
+ vector<const FieldDescriptor*> fields;
+ for (int i = 0; i < message->field_count(); ++i) {
+ fields.push_back(message->field(i));
+ }
+ InitializeFieldGeneratorInfoForFields(fields);
+
+ for (int i = 0; i < message->oneof_decl_count(); ++i) {
+ const OneofDescriptor* oneof = message->oneof_decl(i);
+ OneofGeneratorInfo info;
+ info.name = UnderscoresToCamelCase(oneof->name(), false);
+ info.capitalized_name = UnderscoresToCamelCase(oneof->name(), true);
+ oneof_generator_info_map_[oneof] = info;
+ }
+}
+
+void Context::InitializeFieldGeneratorInfoForFields(
+ const vector<const FieldDescriptor*>& fields) {
+ // Find out all fields that conflict with some other field in the same
+ // message.
+ vector<bool> is_conflict(fields.size());
+ vector<string> conflict_reason(fields.size());
+ for (int i = 0; i < fields.size(); ++i) {
+ const FieldDescriptor* field = fields[i];
+ const string& name = UnderscoresToCapitalizedCamelCase(field);
+ for (int j = i + 1; j < fields.size(); ++j) {
+ const FieldDescriptor* other = fields[j];
+ const string& other_name = UnderscoresToCapitalizedCamelCase(other);
+ if (name == other_name) {
+ is_conflict[i] = is_conflict[j] = true;
+ conflict_reason[i] = conflict_reason[j] =
+ "capitalized name of field \"" + field->name() +
+ "\" conflicts with field \"" + other->name() + "\"";
+ } else if (IsConflicting(field, name, other, other_name,
+ &conflict_reason[j])) {
+ is_conflict[i] = is_conflict[j] = true;
+ conflict_reason[i] = conflict_reason[j];
+ }
+ }
+ if (is_conflict[i]) {
+ GOOGLE_LOG(WARNING) << "field \"" << field->full_name() << "\" is conflicting "
+ << "with another field: " << conflict_reason[i];
+ }
+ }
+ for (int i = 0; i < fields.size(); ++i) {
+ const FieldDescriptor* field = fields[i];
+ FieldGeneratorInfo info;
+ info.name = UnderscoresToCamelCase(field);
+ info.capitalized_name = UnderscoresToCapitalizedCamelCase(field);
+ // For fields conflicting with some other fields, we append the field
+ // number to their field names in generated code to avoid conflicts.
+ if (is_conflict[i]) {
+ info.name += SimpleItoa(field->number());
+ info.capitalized_name += SimpleItoa(field->number());
+ info.disambiguated_reason = conflict_reason[i];
+ }
+ field_generator_info_map_[field] = info;
+ }
+}
+
+const FieldGeneratorInfo* Context::GetFieldGeneratorInfo(
+ const FieldDescriptor* field) const {
+ const FieldGeneratorInfo* result =
+ FindOrNull(field_generator_info_map_, field);
+ if (result == NULL) {
+ GOOGLE_LOG(FATAL) << "Can not find FieldGeneratorInfo for field: "
+ << field->full_name();
+ }
+ return result;
+}
+
+const OneofGeneratorInfo* Context::GetOneofGeneratorInfo(
+ const OneofDescriptor* oneof) const {
+ const OneofGeneratorInfo* result =
+ FindOrNull(oneof_generator_info_map_, oneof);
+ if (result == NULL) {
+ GOOGLE_LOG(FATAL) << "Can not find OneofGeneratorInfo for oneof: "
+ << oneof->name();
+ }
+ return result;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/java/java_context.h b/src/google/protobuf/compiler/java/java_context.h
new file mode 100644
index 0000000..5791445
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_context.h
@@ -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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_CONTEXT_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_CONTEXT_H__
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+ class FileDescriptor;
+ class FieldDescriptor;
+ class OneofDescriptor;
+ class Descriptor;
+ namespace compiler {
+ namespace java {
+ class ClassNameResolver; // name_resolver.h
+ }
+ }
+} // namespace protobuf
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+struct FieldGeneratorInfo;
+struct OneofGeneratorInfo;
+// A context object holds the information that is shared among all code
+// generators.
+class Context {
+ public:
+ explicit Context(const FileDescriptor* file);
+ ~Context();
+
+ // Get the name resolver associated with this context. The resolver
+ // can be used to map descriptors to Java class names.
+ ClassNameResolver* GetNameResolver();
+
+ // Get the FieldGeneratorInfo for a given field.
+ const FieldGeneratorInfo* GetFieldGeneratorInfo(
+ const FieldDescriptor* field) const;
+
+ // Get the OneofGeneratorInfo for a given oneof.
+ const OneofGeneratorInfo* GetOneofGeneratorInfo(
+ const OneofDescriptor* oneof) const;
+
+ private:
+ void InitializeFieldGeneratorInfo(const FileDescriptor* file);
+ void InitializeFieldGeneratorInfoForMessage(const Descriptor* message);
+ void InitializeFieldGeneratorInfoForFields(
+ const vector<const FieldDescriptor*>& fields);
+
+ scoped_ptr<ClassNameResolver> name_resolver_;
+ map<const FieldDescriptor*, FieldGeneratorInfo> field_generator_info_map_;
+ map<const OneofDescriptor*, OneofGeneratorInfo> oneof_generator_info_map_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Context);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_CONTEXT_H__
diff --git a/src/google/protobuf/compiler/java/java_doc_comment.cc b/src/google/protobuf/compiler/java/java_doc_comment.cc
new file mode 100644
index 0000000..663f0c9
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_doc_comment.cc
@@ -0,0 +1,233 @@
+// 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: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+
+#include <vector>
+
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+string EscapeJavadoc(const string& input) {
+ string result;
+ result.reserve(input.size() * 2);
+
+ char prev = '*';
+
+ for (string::size_type i = 0; i < input.size(); i++) {
+ char c = input[i];
+ switch (c) {
+ case '*':
+ // Avoid "/*".
+ if (prev == '/') {
+ result.append("&#42;");
+ } else {
+ result.push_back(c);
+ }
+ break;
+ case '/':
+ // Avoid "*/".
+ if (prev == '*') {
+ result.append("&#47;");
+ } else {
+ result.push_back(c);
+ }
+ break;
+ case '@':
+ // '@' starts javadoc tags including the @deprecated tag, which will
+ // cause a compile-time error if inserted before a declaration that
+ // does not have a corresponding @Deprecated annotation.
+ result.append("&#64;");
+ break;
+ case '<':
+ // Avoid interpretation as HTML.
+ result.append("&lt;");
+ break;
+ case '>':
+ // Avoid interpretation as HTML.
+ result.append("&gt;");
+ break;
+ case '&':
+ // Avoid interpretation as HTML.
+ result.append("&amp;");
+ break;
+ case '\\':
+ // Java interprets Unicode escape sequences anywhere!
+ result.append("&#92;");
+ break;
+ default:
+ result.push_back(c);
+ break;
+ }
+
+ prev = c;
+ }
+
+ return result;
+}
+
+static void WriteDocCommentBodyForLocation(
+ io::Printer* printer, const SourceLocation& location) {
+ string comments = location.leading_comments.empty() ?
+ location.trailing_comments : location.leading_comments;
+ if (!comments.empty()) {
+ // TODO(kenton): Ideally we should parse the comment text as Markdown and
+ // write it back as HTML, but this requires a Markdown parser. For now
+ // we just use <pre> to get fixed-width text formatting.
+
+ // If the comment itself contains block comment start or end markers,
+ // HTML-escape them so that they don't accidentally close the doc comment.
+ comments = EscapeJavadoc(comments);
+
+ vector<string> lines = Split(comments, "\n");
+ while (!lines.empty() && lines.back().empty()) {
+ lines.pop_back();
+ }
+
+ printer->Print(
+ " *\n"
+ " * <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
+ // close the comment.
+ if (!lines[i].empty() && lines[i][0] == '/') {
+ printer->Print(" * $line$\n", "line", lines[i]);
+ } else {
+ printer->Print(" *$line$\n", "line", lines[i]);
+ }
+ }
+ printer->Print(" * </pre>\n");
+ }
+}
+
+template <typename DescriptorType>
+static void WriteDocCommentBody(
+ io::Printer* printer, const DescriptorType* descriptor) {
+ SourceLocation location;
+ if (descriptor->GetSourceLocation(&location)) {
+ WriteDocCommentBodyForLocation(printer, location);
+ }
+}
+
+static string FirstLineOf(const string& value) {
+ string result = value;
+
+ string::size_type pos = result.find_first_of('\n');
+ if (pos != string::npos) {
+ result.erase(pos);
+ }
+
+ // If line ends in an opening brace, make it "{ ... }" so it looks nice.
+ if (!result.empty() && result[result.size() - 1] == '{') {
+ result.append(" ... }");
+ }
+
+ return result;
+}
+
+void WriteMessageDocComment(io::Printer* printer, const Descriptor* message) {
+ printer->Print(
+ "/**\n"
+ " * Protobuf type {@code $fullname$}\n",
+ "fullname", EscapeJavadoc(message->full_name()));
+ WriteDocCommentBody(printer, message);
+ printer->Print(" */\n");
+}
+
+void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field) {
+ // In theory we should have slightly different comments for setters, getters,
+ // 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.:
+ // 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"
+ " * <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"
+ " * Protobuf enum {@code $fullname$}\n",
+ "fullname", EscapeJavadoc(enum_->full_name()));
+ WriteDocCommentBody(printer, enum_);
+ printer->Print(" */\n");
+}
+
+void WriteEnumValueDocComment(io::Printer* printer,
+ const EnumValueDescriptor* value) {
+ printer->Print(
+ "/**\n"
+ " * <code>$def$</code>\n",
+ "def", EscapeJavadoc(FirstLineOf(value->DebugString())));
+ WriteDocCommentBody(printer, value);
+ printer->Print(" */\n");
+}
+
+void WriteServiceDocComment(io::Printer* printer,
+ const ServiceDescriptor* service) {
+ printer->Print(
+ "/**\n"
+ " * Protobuf service {@code $fullname$}\n",
+ "fullname", EscapeJavadoc(service->full_name()));
+ WriteDocCommentBody(printer, service);
+ printer->Print(" */\n");
+}
+
+void WriteMethodDocComment(io::Printer* printer,
+ const MethodDescriptor* method) {
+ printer->Print(
+ "/**\n"
+ " * <code>$def$</code>\n",
+ "def", EscapeJavadoc(FirstLineOf(method->DebugString())));
+ WriteDocCommentBody(printer, method);
+ printer->Print(" */\n");
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/java/java_doc_comment.h b/src/google/protobuf/compiler/java/java_doc_comment.h
new file mode 100644
index 0000000..7d9535c
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_doc_comment.h
@@ -0,0 +1,69 @@
+// 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: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__
+
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+void WriteMessageDocComment(io::Printer* printer, const Descriptor* message);
+void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field);
+void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_);
+void WriteEnumValueDocComment(io::Printer* printer,
+ const EnumValueDescriptor* value);
+void WriteServiceDocComment(io::Printer* printer,
+ const ServiceDescriptor* service);
+void WriteMethodDocComment(io::Printer* printer,
+ const MethodDescriptor* method);
+
+// Exposed for testing only.
+LIBPROTOC_EXPORT string EscapeJavadoc(const string& input);
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__
diff --git a/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc b/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc
new file mode 100644
index 0000000..ae582ea
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc
@@ -0,0 +1,67 @@
+// 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: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+namespace {
+
+TEST(JavaDocCommentTest, Escaping) {
+ EXPECT_EQ("foo /&#42; bar *&#47; baz", EscapeJavadoc("foo /* bar */ baz"));
+ EXPECT_EQ("foo /&#42;&#47; baz", EscapeJavadoc("foo /*/ baz"));
+ EXPECT_EQ("{&#64;foo}", EscapeJavadoc("{@foo}"));
+ EXPECT_EQ("&lt;i&gt;&amp;&lt;/i&gt;", EscapeJavadoc("<i>&</i>"));
+ EXPECT_EQ("foo&#92;u1234bar", EscapeJavadoc("foo\\u1234bar"));
+ EXPECT_EQ("&#64;deprecated", EscapeJavadoc("@deprecated"));
+}
+
+// TODO(kenton): It's hard to write a robust test of the doc comments -- we
+// can only really compare the output against a golden value, which is a
+// fairly tedious and fragile testing strategy. If we want to go that route,
+// it probably makes sense to bite the bullet and write a test that compares
+// the whole generated output for unittest.proto against a golden value, with
+// a very simple script that can be run to regenerate it with the latest code.
+// This would mean that updates to the golden file would have to be included
+// in any change to the code generator, which would actually be fairly useful
+// as it allows the reviewer to see clearly how the generated code is
+// changing.
+
+} // namespace
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc
index 85e39f5..668377a 100644
--- a/src/google/protobuf/compiler/java/java_enum.cc
+++ b/src/google/protobuf/compiler/java/java_enum.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,8 +35,11 @@
#include <map>
#include <string>
+#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_enum.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/descriptor.pb.h>
#include <google/protobuf/stubs/strutil.h>
@@ -46,8 +49,22 @@ namespace protobuf {
namespace compiler {
namespace java {
-EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
- : descriptor_(descriptor) {
+namespace {
+bool EnumHasCustomOptions(const EnumDescriptor* descriptor) {
+ if (descriptor->options().unknown_fields().field_count() > 0) return true;
+ for (int i = 0; i < descriptor->value_count(); ++i) {
+ const EnumValueDescriptor* value = descriptor->value(i);
+ if (value->options().unknown_fields().field_count() > 0) return true;
+ }
+ return false;
+}
+} // namespace
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
+ bool immutable_api,
+ Context* context)
+ : descriptor_(descriptor), immutable_api_(immutable_api),
+ name_resolver_(context->GetNameResolver()) {
for (int i = 0; i < descriptor_->value_count(); i++) {
const EnumValueDescriptor* value = descriptor_->value(i);
const EnumValueDescriptor* canonical_value =
@@ -67,6 +84,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
EnumGenerator::~EnumGenerator() {}
void EnumGenerator::Generate(io::Printer* printer) {
+ WriteEnumDocComment(printer, descriptor_);
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
"public enum $classname$\n"
@@ -85,6 +103,10 @@ void EnumGenerator::Generate(io::Printer* printer) {
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");
}
@@ -100,10 +122,21 @@ void EnumGenerator::Generate(io::Printer* printer) {
vars["classname"] = descriptor_->name();
vars["name"] = aliases_[i].value->name();
vars["canonical_name"] = aliases_[i].canonical_value->name();
+ WriteEnumValueDocComment(printer, aliases_[i].value);
printer->Print(vars,
"public static final $classname$ $name$ = $canonical_name$;\n");
}
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ map<string, string> vars;
+ vars["name"] = descriptor_->value(i)->name();
+ vars["number"] = SimpleItoa(descriptor_->value(i)->number());
+ WriteEnumValueDocComment(printer, descriptor_->value(i));
+ printer->Print(vars,
+ "public static final int $name$_VALUE = $number$;\n");
+ }
+ printer->Print("\n");
+
// -----------------------------------------------------------------
printer->Print(
@@ -138,7 +171,7 @@ void EnumGenerator::Generate(io::Printer* printer) {
" internalValueMap =\n"
" new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n"
" public $classname$ findValueByNumber(int number) {\n"
- " return $classname$.valueOf(number)\n;"
+ " return $classname$.valueOf(number);\n"
" }\n"
" };\n"
"\n",
@@ -164,32 +197,87 @@ void EnumGenerator::Generate(io::Printer* printer) {
// at module init time because it wouldn't work with descriptor.proto, but
// we can cache the value the first time getDescriptor() is called.
if (descriptor_->containing_type() == NULL) {
- printer->Print(
- " return $file$.getDescriptor().getEnumTypes().get($index$);\n",
- "file", ClassName(descriptor_->file()),
- "index", SimpleItoa(descriptor_->index()));
+ if (!MultipleJavaFiles(descriptor_->file(), immutable_api_)) {
+ printer->Print(
+ " return $file$.getDescriptor().getEnumTypes().get($index$);\n",
+ "file", name_resolver_->GetClassName(descriptor_->file(),
+ immutable_api_),
+ "index", SimpleItoa(descriptor_->index()));
+ } else {
+ printer->Indent();
+ if (EnumHasCustomOptions(descriptor_)) {
+ // We need to load the immutable classes in order to parse custom
+ // options. However, since file level enums (no outer class) are
+ // shared by immutable code and mutable code, the immutable classes
+ // may not exist. So we try to use Java reflection to retrieve the
+ // descriptor from immutable classes.
+ printer->Print(
+ "try {\n"
+ " java.lang.Class immutableFileClass =\n"
+ " java.lang.Class.forName(\"$immutable_file_class_name$\");\n"
+ " @java.lang.SuppressWarnings(\"unchecked\")\n"
+ " java.lang.reflect.Method m =\n"
+ " immutableFileClass.getMethod(\"getDescriptor\");\n"
+ " com.google.protobuf.Descriptors.FileDescriptor file =\n"
+ " (com.google.protobuf.Descriptors.FileDescriptor)\n"
+ " m.invoke(immutableFileClass);\n"
+ " return file.getEnumTypes().get($index$);\n"
+ "} catch (Exception e) {\n"
+ // Immutable classes cannot be found. Proceed as if custom options
+ // don't exist.
+ "}\n",
+ "immutable_file_class_name",
+ name_resolver_->GetImmutableClassName(descriptor_->file()),
+ "index", SimpleItoa(descriptor_->index()));
+ }
+ printer->Print(
+ "return $immutable_package$.$descriptor_class$.getDescriptor()\n"
+ " .getEnumTypes().get($index$);\n",
+ "immutable_package", FileJavaPackage(descriptor_->file(), true),
+ "descriptor_class",
+ name_resolver_->GetDescriptorClassName(descriptor_->file()),
+ "index", SimpleItoa(descriptor_->index()));
+ printer->Outdent();
+ }
} else {
printer->Print(
- " return $parent$.getDescriptor().getEnumTypes().get($index$);\n",
- "parent", ClassName(descriptor_->containing_type()),
- "index", SimpleItoa(descriptor_->index()));
+ " return $parent$.$descriptor$.getEnumTypes().get($index$);\n",
+ "parent", name_resolver_->GetClassName(descriptor_->containing_type(),
+ immutable_api_),
+ "descriptor", descriptor_->containing_type()->options()
+ .no_standard_descriptor_accessor()
+ ? "getDefaultInstance().getDescriptorForType()"
+ : "getDescriptor()",
+ "index", SimpleItoa(descriptor_->index()));
}
printer->Print(
"}\n"
"\n"
- "private static final $classname$[] VALUES = {\n"
- " ",
+ "private static final $classname$[] VALUES = ",
"classname", descriptor_->name());
- for (int i = 0; i < descriptor_->value_count(); i++) {
- printer->Print("$name$, ",
- "name", descriptor_->value(i)->name());
+ if (CanUseEnumValues()) {
+ // If the constants we are going to output are exactly the ones we
+ // have declared in the Java enum in the same order, then we can use
+ // the values() method that the Java compiler automatically generates
+ // for every enum.
+ printer->Print("values();\n");
+ } else {
+ printer->Print(
+ "{\n"
+ " ");
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ printer->Print("$name$, ",
+ "name", descriptor_->value(i)->name());
+ }
+ printer->Print(
+ "\n"
+ "};\n");
}
printer->Print(
"\n"
- "};\n"
"public static $classname$ valueOf(\n"
" com.google.protobuf.Descriptors.EnumValueDescriptor desc) {\n"
" if (desc.getType() != getDescriptor()) {\n"
@@ -197,31 +285,26 @@ void EnumGenerator::Generate(io::Printer* printer) {
" \"EnumValueDescriptor is not for this type.\");\n"
" }\n"
" return VALUES[desc.getIndex()];\n"
- "}\n",
+ "}\n"
+ "\n",
"classname", descriptor_->name());
+
+ // index is only used for reflection; lite implementation does not need it
+ printer->Print("private final int index;\n");
}
// -----------------------------------------------------------------
printer->Print(
- "private final int index;\n"
- "private final int value;\n"
- "private $classname$(int index, int value) {\n"
- " this.index = index;\n"
- " this.value = value;\n"
- "}\n",
+ "private final int value;\n\n"
+ "private $classname$(int index, int value) {\n",
"classname", descriptor_->name());
-
if (HasDescriptorMethods(descriptor_)) {
- // Force the static initialization code for the file to run, since it may
- // initialize static variables declared in this class.
- printer->Print(
- "\n"
- "static {\n"
- " $file$.getDescriptor();\n"
- "}\n",
- "file", ClassName(descriptor_->file()));
+ printer->Print(" this.index = index;\n");
}
+ printer->Print(
+ " this.value = value;\n"
+ "}\n");
printer->Print(
"\n"
@@ -232,6 +315,18 @@ void EnumGenerator::Generate(io::Printer* printer) {
printer->Print("}\n\n");
}
+bool EnumGenerator::CanUseEnumValues() {
+ if (canonical_values_.size() != descriptor_->value_count()) {
+ return false;
+ }
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ if (descriptor_->value(i)->name() != canonical_values_[i]->name()) {
+ return false;
+ }
+ }
+ return true;
+}
+
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_enum.h b/src/google/protobuf/compiler/java/java_enum.h
index 05ece1f..a0d91f5 100644
--- a/src/google/protobuf/compiler/java/java_enum.h
+++ b/src/google/protobuf/compiler/java/java_enum.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -41,6 +41,12 @@
namespace google {
namespace protobuf {
+ namespace compiler {
+ namespace java {
+ class Context; // context.h
+ class ClassNameResolver; // name_resolver.h
+ }
+ }
namespace io {
class Printer; // printer.h
}
@@ -52,7 +58,9 @@ namespace java {
class EnumGenerator {
public:
- explicit EnumGenerator(const EnumDescriptor* descriptor);
+ explicit EnumGenerator(const EnumDescriptor* descriptor,
+ bool immutable_api,
+ Context* context);
~EnumGenerator();
void Generate(io::Printer* printer);
@@ -73,6 +81,13 @@ class EnumGenerator {
};
vector<Alias> aliases_;
+ bool immutable_api_;
+
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+
+ bool CanUseEnumValues();
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
};
diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc
index af6b1cd..1f0c4af 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,9 +35,12 @@
#include <map>
#include <string>
-#include <google/protobuf/compiler/java/java_enum_field.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_enum_field.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/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
@@ -49,145 +52,456 @@ namespace java {
namespace {
-// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
-// repeat code between this and the other field types.
void SetEnumVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ const FieldGeneratorInfo* info,
+ ClassNameResolver* name_resolver,
map<string, string>* variables) {
- (*variables)["name"] =
- UnderscoresToCamelCase(descriptor);
- (*variables)["capitalized_name"] =
- UnderscoresToCapitalizedCamelCase(descriptor);
- (*variables)["number"] = SimpleItoa(descriptor->number());
- (*variables)["type"] = ClassName(descriptor->enum_type());
- (*variables)["default"] = DefaultValue(descriptor);
+ SetCommonFieldVariables(descriptor, info, variables);
+
+ (*variables)["type"] =
+ name_resolver->GetImmutableClassName(descriptor->enum_type());
+ (*variables)["mutable_type"] =
+ name_resolver->GetMutableClassName(descriptor->enum_type());
+ (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
(*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();" : "";
+
+ if (SupportFieldPresence(descriptor->file())) {
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+
+ // Note that these have a trailing ";".
+ (*variables)["set_has_field_bit_message"] =
+ GenerateSetBit(messageBitIndex) + ";";
+ (*variables)["set_has_field_bit_builder"] =
+ GenerateSetBit(builderBitIndex) + ";";
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex) + ";";
+
+ (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+ } else {
+ (*variables)["set_has_field_bit_message"] = "";
+ (*variables)["set_has_field_bit_builder"] = "";
+ (*variables)["clear_has_field_bit_builder"] = "";
+
+ (*variables)["is_field_present_message"] =
+ (*variables)["name"] + "_ != " + (*variables)["default"];
+ }
+
+ // For repated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ // For repeated fields, one bit is used for whether the array is immutable
+ // in the parsing constructor.
+ (*variables)["get_mutable_bit_parser"] =
+ GenerateGetBitMutableLocal(builderBitIndex);
+ (*variables)["set_mutable_bit_parser"] =
+ GenerateSetBitMutableLocal(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
}
} // namespace
// ===================================================================
-EnumFieldGenerator::
-EnumFieldGenerator(const FieldDescriptor* descriptor)
- : descriptor_(descriptor) {
- SetEnumVariables(descriptor, &variables_);
+ImmutableEnumFieldGenerator::
+ImmutableEnumFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex),
+ name_resolver_(context->GetNameResolver()) {
+ SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {}
+
+int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
+ return 1;
}
-EnumFieldGenerator::~EnumFieldGenerator() {}
+int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
-void EnumFieldGenerator::
+void ImmutableEnumFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n");
+ }
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$$type$ get$capitalized_name$();\n");
+}
+
+void ImmutableEnumFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private boolean has$capitalized_name$;\n"
- "private $type$ $name$_;\n"
- "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
- "public $type$ get$capitalized_name$() { return $name$_; }\n");
+ "private $type$ $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ }
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n");
}
-void EnumFieldGenerator::
+void ImmutableEnumFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
- "public boolean has$capitalized_name$() {\n"
- " return result.has$capitalized_name$();\n"
- "}\n"
- "public $type$ get$capitalized_name$() {\n"
- " return result.get$capitalized_name$();\n"
- "}\n"
- "public Builder set$capitalized_name$($type$ value) {\n"
+ "private $type$ $name$_ = $default$;\n");
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+ }
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
" if (value == null) {\n"
" throw new NullPointerException();\n"
" }\n"
- " result.has$capitalized_name$ = true;\n"
- " result.$name$_ = value;\n"
+ " $set_has_field_bit_builder$\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
" return this;\n"
- "}\n"
- "public Builder clear$capitalized_name$() {\n"
- " result.has$capitalized_name$ = false;\n"
- " result.$name$_ = $default$;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $clear_has_field_bit_builder$\n"
+ " $name$_ = $default$;\n"
+ " $on_changed$\n"
" return this;\n"
"}\n");
}
-void EnumFieldGenerator::
+void ImmutableEnumFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for enums
+}
+
+void ImmutableEnumFieldGenerator::
GenerateInitializationCode(io::Printer* printer) const {
printer->Print(variables_, "$name$_ = $default$;\n");
}
-void EnumFieldGenerator::
+void ImmutableEnumFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $default$;\n"
+ "$clear_has_field_bit_builder$\n");
+}
+
+void ImmutableEnumFieldGenerator::
GenerateMergingCode(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");
+ } else {
+ printer->Print(variables_,
+ "if (other.get$capitalized_name$() != $default$) {\n"
+ " set$capitalized_name$(other.get$capitalized_name$());\n"
+ "}\n");
+ }
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ if (SupportFieldPresence(descriptor_->file())) {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n");
+ }
+ printer->Print(variables_,
+ "result.$name$_ = $name$_;\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "int rawValue = input.readEnum();\n"
+ "$type$ value = $type$.valueOf(rawValue);\n"
+ "if (value == null) {\n");
+ if (UseUnknownFieldSet(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ " unknownFields.mergeVarintField($number$, rawValue);\n");
+ } else {
+ printer->Print(variables_,
+ " unknownFieldsCodedOutput.writeRawVarint32(tag);\n"
+ " unknownFieldsCodedOutput.writeRawVarint32(rawValue);\n");
+ }
+ printer->Print(variables_,
+ "} else {\n"
+ " $set_has_field_bit_message$\n"
+ " $name$_ = value;\n"
+ "}\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+ // noop for enums
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($is_field_present_message$) {\n"
+ " output.writeEnum($number$, $name$_.getNumber());\n"
+ "}\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (other.has$capitalized_name$()) {\n"
- " set$capitalized_name$(other.get$capitalized_name$());\n"
+ "if ($is_field_present_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeEnumSize($number$, $name$_.getNumber());\n"
"}\n");
}
-void EnumFieldGenerator::
+void ImmutableEnumFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result &&\n"
+ " (get$capitalized_name$() == other.get$capitalized_name$());\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n"
+ "hash = (53 * hash) + com.google.protobuf.Internal.hashEnum(\n"
+ " get$capitalized_name$());\n");
+}
+
+string ImmutableEnumFieldGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
+}
+
+// ===================================================================
+
+ImmutableEnumOneofFieldGenerator::
+ImmutableEnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : ImmutableEnumFieldGenerator(
+ descriptor, messageBitIndex, builderBitIndex, context) {
+ const OneofGeneratorInfo* info =
+ context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+ SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutableEnumOneofFieldGenerator::
+~ImmutableEnumOneofFieldGenerator() {}
+
+void ImmutableEnumOneofFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ PrintExtraFieldInfo(variables_, printer);
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ }
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($type$) $oneof_name$_;\n"
+ " }\n"
+ " return $default$;\n"
+ "}\n");
+}
+
+void ImmutableEnumOneofFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ }
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($type$) $oneof_name$_;\n"
+ " }\n"
+ " return $default$;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ " $on_changed$\n"
+ " }\n"
+ " return this;\n"
+ "}\n");
+}
+
+void ImmutableEnumOneofFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const {
- // Nothing to do here for enum types.
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " result.$oneof_name$_ = $oneof_name$_;\n"
+ "}\n");
}
-void EnumFieldGenerator::
+void ImmutableEnumOneofFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "set$capitalized_name$(other.get$capitalized_name$());\n");
+}
+
+void ImmutableEnumOneofFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
"int rawValue = input.readEnum();\n"
- "$type$ value = $type$.valueOf(rawValue);\n");
- if (HasUnknownFields(descriptor_->containing_type())) {
+ "$type$ value = $type$.valueOf(rawValue);\n"
+ "if (value == null) {\n");
+ if (UseUnknownFieldSet(descriptor_->containing_type())) {
printer->Print(variables_,
- "if (value == null) {\n"
- " unknownFields.mergeVarintField($number$, rawValue);\n"
- "} else {\n");
+ " unknownFields.mergeVarintField($number$, rawValue);\n");
} else {
printer->Print(variables_,
- "if (value != null) {\n");
+ " unknownFieldsCodedOutput.writeRawVarint32(tag);\n"
+ " unknownFieldsCodedOutput.writeRawVarint32(rawValue);\n");
}
printer->Print(variables_,
- " set$capitalized_name$(value);\n"
+ "} else {\n"
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = value;\n"
"}\n");
}
-void EnumFieldGenerator::
+void ImmutableEnumOneofFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (has$capitalized_name$()) {\n"
- " output.writeEnum($number$, get$capitalized_name$().getNumber());\n"
+ "if ($has_oneof_case_message$) {\n"
+ " output.writeEnum($number$, (($type$) $oneof_name$_).getNumber());\n"
"}\n");
}
-void EnumFieldGenerator::
+void ImmutableEnumOneofFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (has$capitalized_name$()) {\n"
+ "if ($has_oneof_case_message$) {\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .computeEnumSize($number$, get$capitalized_name$().getNumber());\n"
+ " .computeEnumSize($number$, (($type$) $oneof_name$_).getNumber());\n"
"}\n");
}
-string EnumFieldGenerator::GetBoxedType() const {
- return ClassName(descriptor_->enum_type());
+// ===================================================================
+
+RepeatedImmutableEnumFieldGenerator::
+RepeatedImmutableEnumFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex), context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
}
-// ===================================================================
+RepeatedImmutableEnumFieldGenerator::~RepeatedImmutableEnumFieldGenerator() {}
-RepeatedEnumFieldGenerator::
-RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor)
- : descriptor_(descriptor) {
- SetEnumVariables(descriptor, &variables_);
+int RepeatedImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
}
-RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
+int RepeatedImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
-void RepeatedEnumFieldGenerator::
+void RepeatedImmutableEnumFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$$type$ get$capitalized_name$(int index);\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private java.util.List<$type$> $name$_ =\n"
- " java.util.Collections.emptyList();\n"
- "public java.util.List<$type$> get$capitalized_name$List() {\n"
+ "private java.util.List<$type$> $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
" return $name$_;\n" // note: unmodifiable list
- "}\n"
- "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
- "public $type$ get$capitalized_name$(int index) {\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
" return $name$_.get(index);\n"
"}\n");
@@ -198,99 +512,165 @@ GenerateMembers(io::Printer* printer) const {
}
}
-void RepeatedEnumFieldGenerator::
+void RepeatedImmutableEnumFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
+ // One field is the list and the other field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a refererence to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ "private java.util.List<$type$> $name$_ =\n"
+ " java.util.Collections.emptyList();\n"
+
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
// Note: We return an unmodifiable list because otherwise the caller
// could hold on to the returned list and modify it after the message
// has been built, thus mutating the message which is supposed to be
// immutable.
- "public java.util.List<$type$> get$capitalized_name$List() {\n"
- " return java.util.Collections.unmodifiableList(result.$name$_);\n"
- "}\n"
- "public int get$capitalized_name$Count() {\n"
- " return result.get$capitalized_name$Count();\n"
- "}\n"
- "public $type$ get$capitalized_name$(int index) {\n"
- " return result.get$capitalized_name$(index);\n"
- "}\n"
- "public Builder set$capitalized_name$(int index, $type$ value) {\n"
+ "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
+ " return java.util.Collections.unmodifiableList($name$_);\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$ value) {\n"
" if (value == null) {\n"
" throw new NullPointerException();\n"
" }\n"
- " result.$name$_.set(index, value);\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value);\n"
+ " $on_changed$\n"
" return this;\n"
- "}\n"
- "public Builder add$capitalized_name$($type$ value) {\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
" if (value == null) {\n"
" throw new NullPointerException();\n"
" }\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
- " }\n"
- " result.$name$_.add(value);\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
" return this;\n"
- "}\n"
- "public Builder addAll$capitalized_name$(\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder addAll$capitalized_name$(\n"
" java.lang.Iterable<? extends $type$> values) {\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
- " }\n"
- " super.addAll(values, result.$name$_);\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
+ " values, $name$_);\n"
+ " $on_changed$\n"
" return this;\n"
- "}\n"
- "public Builder clear$capitalized_name$() {\n"
- " result.$name$_ = java.util.Collections.emptyList();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $name$_ = java.util.Collections.emptyList();\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $on_changed$\n"
" return this;\n"
"}\n");
}
-void RepeatedEnumFieldGenerator::
+void RepeatedImmutableEnumFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for enums
+}
+
+void RepeatedImmutableEnumFieldGenerator::
GenerateInitializationCode(io::Printer* printer) const {
- // Initialized inline.
+ printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
}
-void RepeatedEnumFieldGenerator::
+void RepeatedImmutableEnumFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = java.util.Collections.emptyList();\n"
+ "$clear_mutable_bit_builder$;\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
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 (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
" }\n"
- " result.$name$_.addAll(other.$name$_);\n"
+ " $on_changed$\n"
"}\n");
}
-void RepeatedEnumFieldGenerator::
+void RepeatedImmutableEnumFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const {
+ // The code below ensures that the result has an immutable list. If our
+ // list is immutable, we can just reuse it. If not, we make it immutable.
printer->Print(variables_,
- "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n"
- " result.$name$_ =\n"
- " java.util.Collections.unmodifiableList(result.$name$_);\n"
- "}\n");
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
}
-void RepeatedEnumFieldGenerator::
+void RepeatedImmutableEnumFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
// Read and store the enum
printer->Print(variables_,
"int rawValue = input.readEnum();\n"
- "$type$ value = $type$.valueOf(rawValue);\n");
- if (HasUnknownFields(descriptor_->containing_type())) {
+ "$type$ value = $type$.valueOf(rawValue);\n"
+ "if (value == null) {\n");
+ if (UseUnknownFieldSet(descriptor_->containing_type())) {
printer->Print(variables_,
- "if (value == null) {\n"
- " unknownFields.mergeVarintField($number$, rawValue);\n"
- "} else {\n");
+ " unknownFields.mergeVarintField($number$, rawValue);\n");
} else {
printer->Print(variables_,
- "if (value != null) {\n");
+ " unknownFieldsCodedOutput.writeRawVarint32(tag);\n"
+ " unknownFieldsCodedOutput.writeRawVarint32(rawValue);\n");
}
printer->Print(variables_,
- " add$capitalized_name$(value);\n"
+ " } else {\n"
+ " if (!$get_mutable_bit_parser$) {\n"
+ " $name$_ = new java.util.ArrayList<$type$>();\n"
+ " $set_mutable_bit_parser$;\n"
+ " }\n"
+ " $name$_.add(value);\n"
"}\n");
}
-void RepeatedEnumFieldGenerator::
+void RepeatedImmutableEnumFieldGenerator::
GenerateParsingCodeFromPacked(io::Printer* printer) const {
// Wrap GenerateParsingCode's contents with a while loop.
@@ -308,7 +688,15 @@ GenerateParsingCodeFromPacked(io::Printer* printer) const {
"input.popLimit(oldLimit);\n");
}
-void RepeatedEnumFieldGenerator::
+void RepeatedImmutableEnumFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_mutable_bit_parser$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ "}\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
if (descriptor_->options().packed()) {
printer->Print(variables_,
@@ -316,18 +704,18 @@ GenerateSerializationCode(io::Printer* printer) const {
" output.writeRawVarint32($tag$);\n"
" output.writeRawVarint32($name$MemoizedSerializedSize);\n"
"}\n"
- "for ($type$ element : get$capitalized_name$List()) {\n"
- " output.writeEnumNoTag(element.getNumber());\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.writeEnumNoTag($name$_.get(i).getNumber());\n"
"}\n");
} else {
printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
- " output.writeEnum($number$, element.getNumber());\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.writeEnum($number$, $name$_.get(i).getNumber());\n"
"}\n");
}
}
-void RepeatedEnumFieldGenerator::
+void RepeatedImmutableEnumFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
"{\n"
@@ -335,9 +723,9 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Indent();
printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
" dataSize += com.google.protobuf.CodedOutputStream\n"
- " .computeEnumSizeNoTag(element.getNumber());\n"
+ " .computeEnumSizeNoTag($name$_.get(i).getNumber());\n"
"}\n");
printer->Print(
"size += dataSize;\n");
@@ -350,7 +738,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
"}");
} else {
printer->Print(variables_,
- "size += $tag_size$ * get$capitalized_name$List().size();\n");
+ "size += $tag_size$ * $name$_.size();\n");
}
// cache the data size for packed fields.
@@ -363,8 +751,25 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print("}\n");
}
-string RepeatedEnumFieldGenerator::GetBoxedType() const {
- return ClassName(descriptor_->enum_type());
+void RepeatedImmutableEnumFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + com.google.protobuf.Internal.hashEnumList(\n"
+ " get$capitalized_name$List());\n"
+ "}\n");
+}
+
+string RepeatedImmutableEnumFieldGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
}
} // namespace java
diff --git a/src/google/protobuf/compiler/java/java_enum_field.h b/src/google/protobuf/compiler/java/java_enum_field.h
index c54a0fa..6a9535a 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.h
+++ b/src/google/protobuf/compiler/java/java_enum_field.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -41,56 +41,113 @@
namespace google {
namespace protobuf {
+ namespace compiler {
+ namespace java {
+ class Context; // context.h
+ class ClassNameResolver; // name_resolver.h
+ }
+ }
+}
+
+namespace protobuf {
namespace compiler {
namespace java {
-class EnumFieldGenerator : public FieldGenerator {
+class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator {
public:
- explicit EnumFieldGenerator(const FieldDescriptor* descriptor);
- ~EnumFieldGenerator();
-
- // implements FieldGenerator ---------------------------------------
+ explicit ImmutableEnumFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~ImmutableEnumFieldGenerator();
+
+ // implements ImmutableFieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
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 GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
string GetBoxedType() const;
- private:
+ protected:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumFieldGenerator);
};
-class RepeatedEnumFieldGenerator : public FieldGenerator {
+class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator {
public:
- explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor);
- ~RepeatedEnumFieldGenerator();
+ ImmutableEnumOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~ImmutableEnumOneofFieldGenerator();
- // implements FieldGenerator ---------------------------------------
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumOneofFieldGenerator);
+};
+
+class RepeatedImmutableEnumFieldGenerator : public ImmutableFieldGenerator {
+ public:
+ explicit RepeatedImmutableEnumFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~RepeatedImmutableEnumFieldGenerator();
+
+ // implements ImmutableFieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
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 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;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
string GetBoxedType() const;
private:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableEnumFieldGenerator);
};
} // namespace java
diff --git a/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc
index 903b0a9..27cf416 100644
--- a/src/google/protobuf/compiler/java/java_extension.cc
+++ b/src/google/protobuf/compiler/java/java_extension.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,162 +33,168 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/java/java_extension.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/stubs/strutil.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 {
-namespace {
-
-const char* TypeName(FieldDescriptor::Type field_type) {
- switch (field_type) {
- 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_BOOL : return "BOOL";
- case FieldDescriptor::TYPE_STRING : return "STRING";
- case FieldDescriptor::TYPE_BYTES : return "BYTES";
- case FieldDescriptor::TYPE_ENUM : return "ENUM";
- case FieldDescriptor::TYPE_GROUP : return "GROUP";
- case FieldDescriptor::TYPE_MESSAGE : return "MESSAGE";
-
- // No default because we want the compiler to complain if any new
- // types are added.
- }
-
- GOOGLE_LOG(FATAL) << "Can't get here.";
- return NULL;
-}
-
-}
-
-ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor)
- : descriptor_(descriptor) {
+ImmutableExtensionGenerator::ImmutableExtensionGenerator(
+ const FieldDescriptor* descriptor, Context* context)
+ : descriptor_(descriptor), context_(context),
+ name_resolver_(context->GetNameResolver()) {
if (descriptor_->extension_scope() != NULL) {
- scope_ = ClassName(descriptor_->extension_scope());
+ scope_ = name_resolver_->GetImmutableClassName(
+ descriptor_->extension_scope());
} else {
- scope_ = ClassName(descriptor_->file());
+ scope_ = name_resolver_->GetImmutableClassName(descriptor_->file());
}
}
-ExtensionGenerator::~ExtensionGenerator() {}
-
-void ExtensionGenerator::Generate(io::Printer* printer) {
- map<string, string> vars;
- vars["name"] = UnderscoresToCamelCase(descriptor_);
- vars["containing_type"] = ClassName(descriptor_->containing_type());
- vars["number"] = SimpleItoa(descriptor_->number());
- vars["constant_name"] = FieldConstantName(descriptor_);
- vars["lite"] = HasDescriptorMethods(descriptor_->file()) ? "" : "Lite";
+ImmutableExtensionGenerator::~ImmutableExtensionGenerator() {}
+
+// Initializes the vars referenced in the generated code templates.
+void ExtensionGenerator::InitTemplateVars(const FieldDescriptor* descriptor,
+ const string& scope,
+ bool immutable,
+ ClassNameResolver* name_resolver,
+ map<string, string>* vars_pointer) {
+ map<string, string> &vars = *vars_pointer;
+ vars["scope"] = scope;
+ vars["name"] = UnderscoresToCamelCase(descriptor);
+ vars["containing_type"] =
+ name_resolver->GetClassName(descriptor->containing_type(), immutable);
+ vars["number"] = SimpleItoa(descriptor->number());
+ vars["constant_name"] = FieldConstantName(descriptor);
+ vars["index"] = SimpleItoa(descriptor->index());
+ vars["default"] = descriptor->is_repeated() ?
+ "" : DefaultValue(descriptor, immutable, name_resolver);
+ vars["type_constant"] = FieldTypeName(GetType(descriptor));
+ vars["packed"] = descriptor->options().packed() ? "true" : "false";
+ vars["enum_map"] = "null";
+ vars["prototype"] = "null";
- JavaType java_type = GetJavaType(descriptor_);
+ JavaType java_type = GetJavaType(descriptor);
string singular_type;
switch (java_type) {
case JAVATYPE_MESSAGE:
- vars["type"] = ClassName(descriptor_->message_type());
+ singular_type = name_resolver->GetClassName(descriptor->message_type(),
+ immutable);
+ vars["prototype"] = singular_type + ".getDefaultInstance()";
break;
case JAVATYPE_ENUM:
- vars["type"] = ClassName(descriptor_->enum_type());
+ singular_type = name_resolver->GetClassName(descriptor->enum_type(),
+ immutable);
+ vars["enum_map"] = singular_type + ".internalGetValueMap()";
+ break;
+ case JAVATYPE_STRING:
+ singular_type = "java.lang.String";
+ break;
+ case JAVATYPE_BYTES:
+ singular_type = immutable ? "com.google.protobuf.ByteString" : "byte[]";
break;
default:
- vars["type"] = BoxedPrimitiveTypeName(java_type);
+ singular_type = BoxedPrimitiveTypeName(java_type);
break;
}
-
- printer->Print(vars,
- "public static final int $constant_name$ = $number$;\n");
- if (descriptor_->is_repeated()) {
- printer->Print(vars,
- "public static final\n"
- " com.google.protobuf.GeneratedMessage$lite$.GeneratedExtension<\n"
- " $containing_type$,\n"
- " java.util.List<$type$>> $name$ =\n"
- " com.google.protobuf.GeneratedMessage$lite$\n"
- " .newGeneratedExtension();\n");
- } else {
- printer->Print(vars,
- "public static final\n"
- " com.google.protobuf.GeneratedMessage$lite$.GeneratedExtension<\n"
- " $containing_type$,\n"
- " $type$> $name$ =\n"
- " com.google.protobuf.GeneratedMessage$lite$\n"
- " .newGeneratedExtension();\n");
- }
+ vars["type"] = descriptor->is_repeated() ?
+ "java.util.List<" + singular_type + ">" : singular_type;
+ vars["singular_type"] = singular_type;
}
-void ExtensionGenerator::GenerateInitializationCode(io::Printer* printer) {
+void ImmutableExtensionGenerator::Generate(io::Printer* printer) {
map<string, string> vars;
- vars["name"] = UnderscoresToCamelCase(descriptor_);
- vars["scope"] = scope_;
- vars["index"] = SimpleItoa(descriptor_->index());
- vars["extendee"] = ClassName(descriptor_->containing_type());
- vars["default"] = descriptor_->is_repeated() ? "" : DefaultValue(descriptor_);
- vars["number"] = SimpleItoa(descriptor_->number());
- vars["type_constant"] = TypeName(GetType(descriptor_));
- vars["packed"] = descriptor_->options().packed() ? "true" : "false";
- vars["enum_map"] = "null";
- vars["prototype"] = "null";
-
- JavaType java_type = GetJavaType(descriptor_);
- string singular_type;
- switch (java_type) {
- case JAVATYPE_MESSAGE:
- vars["type"] = ClassName(descriptor_->message_type());
- vars["prototype"] = ClassName(descriptor_->message_type()) +
- ".getDefaultInstance()";
- break;
- case JAVATYPE_ENUM:
- vars["type"] = ClassName(descriptor_->enum_type());
- vars["enum_map"] = ClassName(descriptor_->enum_type()) +
- ".internalGetValueMap()";
- break;
- default:
- vars["type"] = BoxedPrimitiveTypeName(java_type);
- break;
- }
+ 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 (HasDescriptorMethods(descriptor_->file())) {
- printer->Print(vars,
- "$scope$.$name$.internalInit(\n"
- " $scope$.getDescriptor().getExtensions().get($index$),\n"
- " $type$.class);\n");
+ // 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");
+ }
} else {
+ // Lite extensions
if (descriptor_->is_repeated()) {
- printer->Print(vars,
- "$scope$.$name$.internalInitRepeated(\n"
- " $extendee$.getDefaultInstance(),\n"
- " $prototype$,\n"
- " $enum_map$,\n"
- " $number$,\n"
- " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
- " $packed$);\n");
+ 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,
- "$scope$.$name$.internalInitSingular(\n"
- " $extendee$.getDefaultInstance(),\n"
- " $default$,\n"
- " $prototype$,\n"
- " $enum_map$,\n"
- " $number$,\n"
- " com.google.protobuf.WireFormat.FieldType.$type_constant$);\n");
+ 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");
}
}
}
-void ExtensionGenerator::GenerateRegistrationCode(io::Printer* printer) {
+void ImmutableExtensionGenerator::GenerateNonNestedInitializationCode(
+ io::Printer* printer) {
+ if (descriptor_->extension_scope() == NULL &&
+ HasDescriptorMethods(descriptor_->file())) {
+ // Only applies to non-nested, non-lite extensions.
+ printer->Print(
+ "$name$.internalInit(descriptor.getExtensions().get($index$));\n",
+ "name", UnderscoresToCamelCase(descriptor_),
+ "index", SimpleItoa(descriptor_->index()));
+ }
+}
+
+void ImmutableExtensionGenerator::GenerateRegistrationCode(
+ io::Printer* printer) {
printer->Print(
"registry.add($scope$.$name$);\n",
"scope", scope_,
diff --git a/src/google/protobuf/compiler/java/java_extension.h b/src/google/protobuf/compiler/java/java_extension.h
index 1e42304..f1701fb 100644
--- a/src/google/protobuf/compiler/java/java_extension.h
+++ b/src/google/protobuf/compiler/java/java_extension.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,6 +35,7 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__
#define GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__
+#include <map>
#include <string>
#include <google/protobuf/stubs/common.h>
@@ -42,6 +43,12 @@
namespace google {
namespace protobuf {
class FieldDescriptor; // descriptor.h
+ namespace compiler {
+ namespace java {
+ class Context; // context.h
+ class ClassNameResolver; // name_resolver.h
+ }
+ }
namespace io {
class Printer; // printer.h
}
@@ -56,17 +63,42 @@ namespace java {
// since extensions are just simple identifiers with interesting types.
class ExtensionGenerator {
public:
- explicit ExtensionGenerator(const FieldDescriptor* descriptor);
- ~ExtensionGenerator();
+ explicit ExtensionGenerator() {}
+ virtual ~ExtensionGenerator() {}
+
+ virtual void Generate(io::Printer* printer) = 0;
+ virtual void GenerateNonNestedInitializationCode(io::Printer* printer) = 0;
+ virtual void GenerateRegistrationCode(io::Printer* printer) = 0;
- void Generate(io::Printer* printer);
- void GenerateInitializationCode(io::Printer* printer);
- void GenerateRegistrationCode(io::Printer* printer);
+ protected:
+ static void InitTemplateVars(const FieldDescriptor* descriptor,
+ const string& scope,
+ bool immutable,
+ ClassNameResolver* name_resolver,
+ map<string, string>* vars_pointer);
private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
+};
+
+class ImmutableExtensionGenerator : public ExtensionGenerator {
+ public:
+ explicit ImmutableExtensionGenerator(const FieldDescriptor* descriptor,
+ Context* context);
+ virtual ~ImmutableExtensionGenerator();
+
+ virtual void Generate(io::Printer* printer);
+ virtual void GenerateNonNestedInitializationCode(io::Printer* printer);
+ virtual void GenerateRegistrationCode(io::Printer* printer);
+
+ protected:
const FieldDescriptor* descriptor_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
string scope_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableExtensionGenerator);
};
} // namespace java
@@ -74,4 +106,4 @@ class ExtensionGenerator {
} // namespace protobuf
} // namespace google
-#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__
diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc
index 978c8f3..d7b0f3f 100644
--- a/src/google/protobuf/compiler/java/java_field.cc
+++ b/src/google/protobuf/compiler/java/java_field.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,77 +33,178 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/java/java_field.h>
-#include <google/protobuf/compiler/java/java_helpers.h>
-#include <google/protobuf/compiler/java/java_primitive_field.h>
+
+#include <memory>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_enum_field.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_lazy_message_field.h>
#include <google/protobuf/compiler/java/java_message_field.h>
-#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_primitive_field.h>
+#include <google/protobuf/compiler/java/java_string_field.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace java {
-FieldGenerator::~FieldGenerator() {}
-
-void FieldGenerator::GenerateParsingCodeFromPacked(io::Printer* printer) const {
- // Reaching here indicates a bug. Cases are:
- // - This FieldGenerator should support packing, but this method should be
- // overridden.
- // - This FieldGenerator doesn't support packing, and this method should
- // never have been called.
- GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() "
- << "called on field generator that does not support packing.";
-}
-
-FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
- : descriptor_(descriptor),
- field_generators_(
- new scoped_ptr<FieldGenerator>[descriptor->field_count()]),
- extension_generators_(
- new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) {
+namespace {
- // Construct all the FieldGenerators.
- for (int i = 0; i < descriptor->field_count(); i++) {
- field_generators_[i].reset(MakeGenerator(descriptor->field(i)));
- }
- for (int i = 0; i < descriptor->extension_count(); i++) {
- extension_generators_[i].reset(MakeGenerator(descriptor->extension(i)));
- }
-}
-
-FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) {
+ImmutableFieldGenerator* MakeImmutableGenerator(
+ const FieldDescriptor* field, int messageBitIndex, int builderBitIndex,
+ Context* context) {
if (field->is_repeated()) {
switch (GetJavaType(field)) {
case JAVATYPE_MESSAGE:
- return new RepeatedMessageFieldGenerator(field);
+ if (IsLazy(field)) {
+ return new RepeatedImmutableLazyMessageFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ } else {
+ return new RepeatedImmutableMessageFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ }
case JAVATYPE_ENUM:
- return new RepeatedEnumFieldGenerator(field);
+ return new RepeatedImmutableEnumFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ case JAVATYPE_STRING:
+ return new RepeatedImmutableStringFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
default:
- return new RepeatedPrimitiveFieldGenerator(field);
+ return new RepeatedImmutablePrimitiveFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
}
} else {
- switch (GetJavaType(field)) {
- case JAVATYPE_MESSAGE:
- return new MessageFieldGenerator(field);
- case JAVATYPE_ENUM:
- return new EnumFieldGenerator(field);
- default:
- return new PrimitiveFieldGenerator(field);
+ if (field->containing_oneof()) {
+ switch (GetJavaType(field)) {
+ case JAVATYPE_MESSAGE:
+ if (IsLazy(field)) {
+ return new ImmutableLazyMessageOneofFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ } else {
+ return new ImmutableMessageOneofFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ }
+ case JAVATYPE_ENUM:
+ return new ImmutableEnumOneofFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ case JAVATYPE_STRING:
+ return new ImmutableStringOneofFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ default:
+ return new ImmutablePrimitiveOneofFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ }
+ } else {
+ switch (GetJavaType(field)) {
+ case JAVATYPE_MESSAGE:
+ if (IsLazy(field)) {
+ return new ImmutableLazyMessageFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ } else {
+ return new ImmutableMessageFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ }
+ case JAVATYPE_ENUM:
+ return new ImmutableEnumFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ case JAVATYPE_STRING:
+ return new ImmutableStringFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ default:
+ return new ImmutablePrimitiveFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ }
}
}
}
-FieldGeneratorMap::~FieldGeneratorMap() {}
-const FieldGenerator& FieldGeneratorMap::get(
- const FieldDescriptor* field) const {
- GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
- return *field_generators_[field->index()];
+static inline void ReportUnexpectedPackedFieldsCall(io::Printer* printer) {
+ // Reaching here indicates a bug. Cases are:
+ // - This FieldGenerator should support packing,
+ // but this method should be overridden.
+ // - This FieldGenerator doesn't support packing, and this method
+ // should never have been called.
+ GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() "
+ << "called on field generator that does not support packing.";
}
-const FieldGenerator& FieldGeneratorMap::get_extension(int index) const {
- return *extension_generators_[index];
+} // namespace
+
+ImmutableFieldGenerator::~ImmutableFieldGenerator() {}
+
+void ImmutableFieldGenerator::
+GenerateParsingCodeFromPacked(io::Printer* printer) const {
+ ReportUnexpectedPackedFieldsCall(printer);
+}
+
+// ===================================================================
+
+template <>
+FieldGeneratorMap<ImmutableFieldGenerator>::FieldGeneratorMap(
+ const Descriptor* descriptor, Context* context)
+ : descriptor_(descriptor),
+ field_generators_(new scoped_ptr<
+ ImmutableFieldGenerator>[descriptor->field_count()]) {
+
+ // Construct all the FieldGenerators and assign them bit indices for their
+ // bit fields.
+ int messageBitIndex = 0;
+ int builderBitIndex = 0;
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ ImmutableFieldGenerator* generator = MakeImmutableGenerator(
+ descriptor->field(i), messageBitIndex, builderBitIndex, context);
+ field_generators_[i].reset(generator);
+ messageBitIndex += generator->GetNumBitsForMessage();
+ builderBitIndex += generator->GetNumBitsForBuilder();
+ }
+}
+
+template<>
+FieldGeneratorMap<ImmutableFieldGenerator>::~FieldGeneratorMap() {}
+
+
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ const FieldGeneratorInfo* info,
+ map<string, string>* variables) {
+ (*variables)["field_name"] = descriptor->name();
+ (*variables)["name"] = info->name;
+ (*variables)["capitalized_name"] = info->capitalized_name;
+ (*variables)["disambiguated_reason"] = info->disambiguated_reason;
+ (*variables)["constant_name"] = FieldConstantName(descriptor);
+ (*variables)["number"] = SimpleItoa(descriptor->number());
+}
+
+void SetCommonOneofVariables(const FieldDescriptor* descriptor,
+ const OneofGeneratorInfo* info,
+ map<string, string>* variables) {
+ (*variables)["oneof_name"] = info->name;
+ (*variables)["oneof_capitalized_name"] = info->capitalized_name;
+ (*variables)["oneof_index"] =
+ SimpleItoa(descriptor->containing_oneof()->index());
+ (*variables)["set_oneof_case_message"] = info->name +
+ "Case_ = " + SimpleItoa(descriptor->number());
+ (*variables)["clear_oneof_case_message"] = info->name +
+ "Case_ = 0";
+ (*variables)["has_oneof_case_message"] = info->name +
+ "Case_ == " + SimpleItoa(descriptor->number());
+}
+
+void PrintExtraFieldInfo(const map<string, string>& variables,
+ io::Printer* printer) {
+ const map<string, string>::const_iterator it =
+ variables.find("disambiguated_reason");
+ if (it != variables.end() && !it->second.empty()) {
+ printer->Print(
+ variables,
+ "// An alternative name is used for field \"$field_name$\" because:\n"
+ "// $disambiguated_reason$\n");
+ }
}
} // namespace java
diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h
index f5bef7a..db339d5 100644
--- a/src/google/protobuf/compiler/java/java_field.h
+++ b/src/google/protobuf/compiler/java/java_field.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,14 +35,23 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
+#include <map>
+#include <memory>
#include <string>
+
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
namespace google {
namespace protobuf {
+ namespace compiler {
+ namespace java {
+ class Context; // context.h
+ class ClassNameResolver; // name_resolver.h
+ }
+ }
namespace io {
- class Printer; // printer.h
+ class Printer; // printer.h
}
}
@@ -50,46 +59,101 @@ namespace protobuf {
namespace compiler {
namespace java {
-class FieldGenerator {
+class ImmutableFieldGenerator {
public:
- FieldGenerator() {}
- virtual ~FieldGenerator();
+ ImmutableFieldGenerator() {}
+ virtual ~ImmutableFieldGenerator();
+ virtual int GetNumBitsForMessage() const = 0;
+ virtual int GetNumBitsForBuilder() const = 0;
+ virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0;
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 GenerateBuilderClearCode(io::Printer* printer) const = 0;
virtual void GenerateMergingCode(io::Printer* printer) const = 0;
virtual void GenerateBuildingCode(io::Printer* printer) const = 0;
virtual void GenerateParsingCode(io::Printer* printer) const = 0;
virtual void GenerateParsingCodeFromPacked(io::Printer* printer) const;
+ virtual void GenerateParsingDoneCode(io::Printer* printer) const = 0;
virtual void GenerateSerializationCode(io::Printer* printer) const = 0;
virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0;
+ virtual void GenerateFieldBuilderInitializationCode(io::Printer* printer)
+ const = 0;
+
+ virtual void GenerateEqualsCode(io::Printer* printer) const = 0;
+ virtual void GenerateHashCode(io::Printer* printer) const = 0;
virtual string GetBoxedType() const = 0;
private:
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableFieldGenerator);
};
+
// Convenience class which constructs FieldGenerators for a Descriptor.
+template<typename FieldGeneratorType>
class FieldGeneratorMap {
public:
- explicit FieldGeneratorMap(const Descriptor* descriptor);
+ explicit FieldGeneratorMap(const Descriptor* descriptor,
+ Context* context);
~FieldGeneratorMap();
- const FieldGenerator& get(const FieldDescriptor* field) const;
- const FieldGenerator& get_extension(int index) const;
+ const FieldGeneratorType& get(const FieldDescriptor* field) const;
private:
const Descriptor* descriptor_;
- scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
- scoped_array<scoped_ptr<FieldGenerator> > extension_generators_;
-
- static FieldGenerator* MakeGenerator(const FieldDescriptor* field);
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+ scoped_array<scoped_ptr<FieldGeneratorType> > field_generators_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
};
+template<typename FieldGeneratorType>
+inline const FieldGeneratorType&
+FieldGeneratorMap<FieldGeneratorType>::get(const FieldDescriptor* field) const {
+ GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
+ return *field_generators_[field->index()];
+}
+
+// Instantiate template for mutable and immutable maps.
+template<>
+FieldGeneratorMap<ImmutableFieldGenerator>::
+FieldGeneratorMap(const Descriptor* descriptor,
+ Context* context);
+
+template<>
+FieldGeneratorMap<ImmutableFieldGenerator>::~FieldGeneratorMap();
+
+
+// Field information used in FieldGeneartors.
+struct FieldGeneratorInfo {
+ string name;
+ string capitalized_name;
+ string disambiguated_reason;
+};
+
+// Oneof information used in OneofFieldGeneartors.
+struct OneofGeneratorInfo {
+ string name;
+ string capitalized_name;
+};
+
+// Set some common variables used in variable FieldGenerators.
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ const FieldGeneratorInfo* info,
+ map<string, string>* variables);
+
+// Set some common oneof variables used in OneofFieldGenerators.
+void SetCommonOneofVariables(const FieldDescriptor* descriptor,
+ const OneofGeneratorInfo* info,
+ map<string, string>* variables);
+
+// Print useful comments before a field's accessors.
+void PrintExtraFieldInfo(const map<string, string>& variables,
+ io::Printer* printer);
+
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc
index 7ea127c..231b144 100644
--- a/src/google/protobuf/compiler/java/java_file.cc
+++ b/src/google/protobuf/compiler/java/java_file.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,15 +33,23 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/java/java_file.h>
+
+#include <memory>
+
+#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_enum.h>
-#include <google/protobuf/compiler/java/java_service.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>
#include <google/protobuf/compiler/java/java_message.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+#include <google/protobuf/compiler/java/java_service.h>
+#include <google/protobuf/compiler/java/java_shared_code_generator.h>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
@@ -51,18 +59,24 @@ namespace java {
namespace {
-// Recursively searches the given message to see if it contains any extensions.
-bool UsesExtensions(const Message& message) {
+
+// Recursively searches the given message to collect extensions.
+// Returns true if all the extensions can be recognized. The extensions will be
+// appended in to the extensions parameter.
+// Returns false when there are unknown fields, in which case the data in the
+// extensions output parameter is not reliable and should be discarded.
+bool CollectExtensions(const Message& message,
+ vector<const FieldDescriptor*>* extensions) {
const Reflection* reflection = message.GetReflection();
- // We conservatively assume that unknown fields are extensions.
- if (reflection->GetUnknownFields(message).field_count() > 0) return true;
+ // There are unknown fields that could be extensions, thus this call fails.
+ if (reflection->GetUnknownFields(message).field_count() > 0) return false;
vector<const FieldDescriptor*> fields;
reflection->ListFields(message, &fields);
for (int i = 0; i < fields.size(); i++) {
- if (fields[i]->is_extension()) return true;
+ if (fields[i]->is_extension()) extensions->push_back(fields[i]);
if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) {
if (fields[i]->is_repeated()) {
@@ -70,25 +84,83 @@ bool UsesExtensions(const Message& message) {
for (int j = 0; j < size; j++) {
const Message& sub_message =
reflection->GetRepeatedMessage(message, fields[i], j);
- if (UsesExtensions(sub_message)) return true;
+ if (!CollectExtensions(sub_message, extensions)) return false;
}
} else {
const Message& sub_message = reflection->GetMessage(message, fields[i]);
- if (UsesExtensions(sub_message)) return true;
+ if (!CollectExtensions(sub_message, extensions)) return false;
}
}
}
- return false;
+ return true;
+}
+
+// Finds all extensions in the given message and its sub-messages. If the
+// message contains unknown fields (which could be extensions), then those
+// extensions are defined in alternate_pool.
+// The message will be converted to a DynamicMessage backed by alternate_pool
+// in order to handle this case.
+void CollectExtensions(const FileDescriptorProto& file_proto,
+ const DescriptorPool& alternate_pool,
+ vector<const FieldDescriptor*>* extensions,
+ const string& file_data) {
+ if (!CollectExtensions(file_proto, extensions)) {
+ // There are unknown fields in the file_proto, which are probably
+ // extensions. We need to parse the data into a dynamic message based on the
+ // builder-pool to find out all extensions.
+ const Descriptor* file_proto_desc = alternate_pool.FindMessageTypeByName(
+ file_proto.GetDescriptor()->full_name());
+ GOOGLE_CHECK(file_proto_desc)
+ << "Find unknown fields in FileDescriptorProto when building "
+ << file_proto.name()
+ << ". It's likely that those fields are custom options, however, "
+ "descriptor.proto is not in the transitive dependencies. "
+ "This normally should not happen. Please report a bug.";
+ DynamicMessageFactory factory;
+ scoped_ptr<Message> dynamic_file_proto(
+ factory.GetPrototype(file_proto_desc)->New());
+ GOOGLE_CHECK(dynamic_file_proto.get() != NULL);
+ GOOGLE_CHECK(dynamic_file_proto->ParseFromString(file_data));
+
+ // Collect the extensions again from the dynamic message. There should be no
+ // more unknown fields this time, i.e. all the custom options should be
+ // parsed as extensions now.
+ extensions->clear();
+ GOOGLE_CHECK(CollectExtensions(*dynamic_file_proto, extensions))
+ << "Find unknown fields in FileDescriptorProto when building "
+ << file_proto.name()
+ << ". It's likely that those fields are custom options, however, "
+ "those options cannot be recognized in the builder pool. "
+ "This normally should not happen. Please report a bug.";
+ }
}
} // namespace
-FileGenerator::FileGenerator(const FileDescriptor* file)
- : file_(file),
- java_package_(FileJavaPackage(file)),
- classname_(FileClassName(file)) {}
+FileGenerator::FileGenerator(const FileDescriptor* file, bool immutable_api)
+ : file_(file),
+ java_package_(FileJavaPackage(file, immutable_api)),
+ message_generators_(
+ new scoped_ptr<MessageGenerator>[file->message_type_count()]),
+ extension_generators_(
+ new scoped_ptr<ExtensionGenerator>[file->extension_count()]),
+ context_(new Context(file)),
+ name_resolver_(context_->GetNameResolver()),
+ immutable_api_(immutable_api) {
+ classname_ = name_resolver_->GetFileClassName(file, immutable_api);
+ generator_factory_.reset(
+ new ImmutableGeneratorFactory(context_.get()));
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ message_generators_[i].reset(
+ generator_factory_->NewMessageGenerator(file_->message_type(i)));
+ }
+ for (int i = 0; i < file_->extension_count(); ++i) {
+ extension_generators_[i].reset(
+ generator_factory_->NewExtensionGenerator(file_->extension(i)));
+ }
+}
FileGenerator::~FileGenerator() {}
@@ -97,25 +169,7 @@ bool FileGenerator::Validate(string* error) {
// problem that leads to Java compile errors that can be hard to understand.
// It's especially bad when using the java_multiple_files, since we would
// end up overwriting the outer class with one of the inner ones.
-
- bool found_conflict = false;
- for (int i = 0; i < file_->enum_type_count() && !found_conflict; i++) {
- if (file_->enum_type(i)->name() == classname_) {
- found_conflict = true;
- }
- }
- for (int i = 0; i < file_->message_type_count() && !found_conflict; i++) {
- if (file_->message_type(i)->name() == classname_) {
- found_conflict = true;
- }
- }
- for (int i = 0; i < file_->service_count() && !found_conflict; i++) {
- if (file_->service(i)->name() == classname_) {
- found_conflict = true;
- }
- }
-
- if (found_conflict) {
+ if (name_resolver_->HasConflictingClassName(file_, classname_)) {
error->assign(file_->name());
error->append(
": Cannot generate Java output because the file's outer class name, \"");
@@ -126,7 +180,29 @@ bool FileGenerator::Validate(string* error) {
"option to specify a different outer class name for the .proto file.");
return false;
}
-
+ // If java_outer_classname option is not set and the default outer class name
+ // conflicts with a type defined in the message, we will append a suffix to
+ // avoid the conflict. This allows proto1 API protos to be dual-compiled into
+ // proto2 API without code change. When this happens we'd like to issue an
+ // warning to let the user know that the outer class name has been changed.
+ // Although we only do this automatic naming fix for immutable API, mutable
+ // outer class name will also be affected as it's contructed from immutable
+ // outer class name with an additional "Mutable" prefix. Since the naming
+ // change in mutable API is not caused by a naming conflict, we generate the
+ // warning for immutable API only.
+ if (immutable_api_ && !file_->options().has_java_outer_classname()) {
+ string default_classname =
+ name_resolver_->GetFileDefaultImmutableClassName(file_);
+ if (default_classname != classname_) {
+ GOOGLE_LOG(WARNING) << file_->name() << ": The default outer class name, \""
+ << default_classname << "\", conflicts with a type "
+ << "declared in the proto file and an alternative outer "
+ << "class name is used: \"" << classname_ << "\". To avoid "
+ << "this warning, please use the java_outer_classname "
+ << "option to specify a different outer class name for "
+ << "the .proto file.";
+ }
+ }
return true;
}
@@ -160,12 +236,11 @@ void FileGenerator::Generate(io::Printer* printer) {
printer->Indent();
for (int i = 0; i < file_->extension_count(); i++) {
- ExtensionGenerator(file_->extension(i)).GenerateRegistrationCode(printer);
+ extension_generators_[i]->GenerateRegistrationCode(printer);
}
for (int i = 0; i < file_->message_type_count(); i++) {
- MessageGenerator(file_->message_type(i))
- .GenerateExtensionRegistrationCode(printer);
+ message_generators_[i]->GenerateExtensionRegistrationCode(printer);
}
printer->Outdent();
@@ -174,16 +249,20 @@ void FileGenerator::Generate(io::Printer* printer) {
// -----------------------------------------------------------------
- if (!file_->options().java_multiple_files()) {
+ if (!MultipleJavaFiles(file_, immutable_api_)) {
for (int i = 0; i < file_->enum_type_count(); i++) {
- EnumGenerator(file_->enum_type(i)).Generate(printer);
+ EnumGenerator(file_->enum_type(i), immutable_api_, context_.get())
+ .Generate(printer);
}
for (int i = 0; i < file_->message_type_count(); i++) {
- MessageGenerator(file_->message_type(i)).Generate(printer);
+ message_generators_[i]->GenerateInterface(printer);
+ message_generators_[i]->Generate(printer);
}
if (HasGenericServices(file_)) {
for (int i = 0; i < file_->service_count(); i++) {
- ServiceGenerator(file_->service(i)).Generate(printer);
+ scoped_ptr<ServiceGenerator> generator(
+ generator_factory_->NewServiceGenerator(file_->service(i)));
+ generator->Generate(printer);
}
}
}
@@ -191,34 +270,29 @@ void FileGenerator::Generate(io::Printer* printer) {
// Extensions must be generated in the outer class since they are values,
// not classes.
for (int i = 0; i < file_->extension_count(); i++) {
- ExtensionGenerator(file_->extension(i)).Generate(printer);
+ extension_generators_[i]->Generate(printer);
}
// Static variables.
for (int i = 0; i < file_->message_type_count(); i++) {
- // TODO(kenton): Reuse MessageGenerator objects?
- MessageGenerator(file_->message_type(i)).GenerateStaticVariables(printer);
+ message_generators_[i]->GenerateStaticVariables(printer);
}
printer->Print("\n");
if (HasDescriptorMethods(file_)) {
- GenerateEmbeddedDescriptor(printer);
+ if (immutable_api_) {
+ GenerateDescriptorInitializationCodeForImmutable(printer);
+ } else {
+ GenerateDescriptorInitializationCodeForMutable(printer);
+ }
} else {
printer->Print(
"static {\n");
printer->Indent();
for (int i = 0; i < file_->message_type_count(); i++) {
- // TODO(kenton): Reuse MessageGenerator objects?
- MessageGenerator(file_->message_type(i))
- .GenerateStaticVariableInitializers(printer);
- }
-
- for (int i = 0; i < file_->extension_count(); i++) {
- // TODO(kenton): Reuse ExtensionGenerator objects?
- ExtensionGenerator(file_->extension(i))
- .GenerateInitializationCode(printer);
+ message_generators_[i]->GenerateStaticVariableInitializers(printer);
}
printer->Outdent();
@@ -226,13 +300,6 @@ void FileGenerator::Generate(io::Printer* printer) {
"}\n");
}
- // Dummy function we can use to force the static initialization block to
- // run. Needed by inner classes. Cannot be private due to
- // java_multiple_files option.
- printer->Print(
- "\n"
- "public static void internalForceInit() {}\n");
-
printer->Print(
"\n"
"// @@protoc_insertion_point(outer_class_scope)\n");
@@ -241,23 +308,8 @@ void FileGenerator::Generate(io::Printer* printer) {
printer->Print("}\n");
}
-void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) {
- // 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. We unfortunately have to put it in
- // a string literal, not a byte array, because apparently using a literal
- // byte array causes the Java compiler to generate *instructions* to
- // initialize each and every byte of the array, e.g. as if you typed:
- // b[0] = 123; b[1] = 456; b[2] = 789;
- // This makes huge bytecode files and can easily hit the compiler's internal
- // code size limits (error "code to large"). String literals are apparently
- // embedded raw, which is what we want.
- FileDescriptorProto file_proto;
- file_->CopyTo(&file_proto);
-
- string file_data;
- file_proto.SerializeToString(&file_data);
-
+void FileGenerator::GenerateDescriptorInitializationCodeForImmutable(
+ io::Printer* printer) {
printer->Print(
"public static com.google.protobuf.Descriptors.FileDescriptor\n"
" getDescriptor() {\n"
@@ -265,104 +317,135 @@ void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) {
"}\n"
"private static com.google.protobuf.Descriptors.FileDescriptor\n"
" descriptor;\n"
- "static {\n"
- " java.lang.String[] descriptorData = {\n");
- printer->Indent();
+ "static {\n");
printer->Indent();
- // Only write 40 bytes per line.
- static const int kBytesPerLine = 40;
- for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
- if (i > 0) {
- // Every 400 lines, start a new string literal, in order to avoid the
- // 64k length limit.
- if (i % 400 == 0) {
- printer->Print(",\n");
- } else {
- printer->Print(" +\n");
- }
- }
- printer->Print("\"$data$\"",
- "data", CEscape(file_data.substr(i, kBytesPerLine)));
- }
-
- printer->Outdent();
- printer->Print("\n};\n");
-
- // -----------------------------------------------------------------
- // Create the InternalDescriptorAssigner.
-
- printer->Print(
- "com.google.protobuf.Descriptors.FileDescriptor."
- "InternalDescriptorAssigner assigner =\n"
- " new com.google.protobuf.Descriptors.FileDescriptor."
- "InternalDescriptorAssigner() {\n"
- " public com.google.protobuf.ExtensionRegistry assignDescriptors(\n"
- " com.google.protobuf.Descriptors.FileDescriptor root) {\n"
- " descriptor = root;\n");
-
- printer->Indent();
- printer->Indent();
- printer->Indent();
+ SharedCodeGenerator shared_code_generator(file_);
+ shared_code_generator.GenerateDescriptors(printer);
for (int i = 0; i < file_->message_type_count(); i++) {
- // TODO(kenton): Reuse MessageGenerator objects?
- MessageGenerator(file_->message_type(i))
- .GenerateStaticVariableInitializers(printer);
+ message_generators_[i]->GenerateStaticVariableInitializers(printer);
}
-
for (int i = 0; i < file_->extension_count(); i++) {
- // TODO(kenton): Reuse ExtensionGenerator objects?
- ExtensionGenerator(file_->extension(i))
- .GenerateInitializationCode(printer);
+ extension_generators_[i]->GenerateNonNestedInitializationCode(printer);
}
- if (UsesExtensions(file_proto)) {
- // Must construct an ExtensionRegistry containing all possible extensions
- // and return it.
+ // Proto compiler builds a DescriptorPool, which holds all the descriptors to
+ // generate, when processing the ".proto" files. We call this DescriptorPool
+ // the parsed pool (a.k.a. file_->pool()).
+ //
+ // Note that when users try to extend the (.*)DescriptorProto in their
+ // ".proto" files, it does not affect the pre-built FileDescriptorProto class
+ // in proto compiler. When we put the descriptor data in the file_proto, those
+ // extensions become unknown fields.
+ //
+ // Now we need to find out all the extension value to the (.*)DescriptorProto
+ // in the file_proto message, and prepare an ExtensionRegistry to return.
+ //
+ // To find those extensions, we need to parse the data into a dynamic message
+ // of the FileDescriptor based on the builder-pool, then we can use
+ // reflections to find all extension fields
+ FileDescriptorProto file_proto;
+ file_->CopyTo(&file_proto);
+ string file_data;
+ file_proto.SerializeToString(&file_data);
+ vector<const FieldDescriptor*> extensions;
+ CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
+
+ if (extensions.size() > 0) {
+ // Must construct an ExtensionRegistry containing all existing extensions
+ // and use it to parse the descriptor data again to recognize extensions.
printer->Print(
"com.google.protobuf.ExtensionRegistry registry =\n"
- " com.google.protobuf.ExtensionRegistry.newInstance();\n"
- "registerAllExtensions(registry);\n");
- for (int i = 0; i < file_->dependency_count(); i++) {
- printer->Print(
- "$dependency$.registerAllExtensions(registry);\n",
- "dependency", ClassName(file_->dependency(i)));
+ " com.google.protobuf.ExtensionRegistry.newInstance();\n");
+ for (int i = 0; i < extensions.size(); i++) {
+ scoped_ptr<ExtensionGenerator> generator(
+ generator_factory_->NewExtensionGenerator(extensions[i]));
+ generator->GenerateRegistrationCode(printer);
}
printer->Print(
- "return registry;\n");
- } else {
- printer->Print(
- "return null;\n");
+ "com.google.protobuf.Descriptors.FileDescriptor\n"
+ " .internalUpdateFileDescriptor(descriptor, registry);\n");
}
- printer->Outdent();
- printer->Outdent();
- printer->Outdent();
+ // Force descriptor initialization of all dependencies.
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ if (ShouldIncludeDependency(file_->dependency(i), true)) {
+ string dependency =
+ name_resolver_->GetImmutableClassName(file_->dependency(i));
+ printer->Print(
+ "$dependency$.getDescriptor();\n",
+ "dependency", dependency);
+ }
+ }
+ printer->Outdent();
printer->Print(
- " }\n"
- " };\n");
+ "}\n");
+}
- // -----------------------------------------------------------------
- // Invoke internalBuildGeneratedFileFrom() to build the file.
+void FileGenerator::GenerateDescriptorInitializationCodeForMutable(io::Printer* printer) {
+ printer->Print(
+ "public static com.google.protobuf.Descriptors.FileDescriptor\n"
+ " getDescriptor() {\n"
+ " return descriptor;\n"
+ "}\n"
+ "private static com.google.protobuf.Descriptors.FileDescriptor\n"
+ " descriptor;\n"
+ "static {\n");
+ printer->Indent();
printer->Print(
- "com.google.protobuf.Descriptors.FileDescriptor\n"
- " .internalBuildGeneratedFileFrom(descriptorData,\n"
- " new com.google.protobuf.Descriptors.FileDescriptor[] {\n");
+ "descriptor = $immutable_package$.$descriptor_classname$.descriptor;\n",
+ "immutable_package", FileJavaPackage(file_, true),
+ "descriptor_classname", name_resolver_->GetDescriptorClassName(file_));
+
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateStaticVariableInitializers(printer);
+ }
+ for (int i = 0; i < file_->extension_count(); i++) {
+ extension_generators_[i]->GenerateNonNestedInitializationCode(printer);
+ }
+
+ // Check if custom options exist. If any, try to load immutable classes since
+ // custom options are only represented with immutable messages.
+ FileDescriptorProto file_proto;
+ file_->CopyTo(&file_proto);
+ string file_data;
+ file_proto.SerializeToString(&file_data);
+ vector<const FieldDescriptor*> extensions;
+ CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
+
+ if (extensions.size() > 0) {
+ // Try to load immutable messages' outer class. Its initialization code
+ // will take care of interpreting custom options.
+ printer->Print(
+ "try {\n"
+ // Note that we have to load the immutable class dynamically here as
+ // we want the mutable code to be independent from the immutable code
+ // at compile time. It is required to implement dual-compile for
+ // mutable and immutable API in blaze.
+ " java.lang.Class immutableClass = java.lang.Class.forName(\n"
+ " \"$immutable_classname$\");\n"
+ "} catch (java.lang.ClassNotFoundException e) {\n"
+ // The immutable class can not be found. Custom options are left
+ // as unknown fields.
+ // TODO(xiaofeng): inform the user with a warning?
+ "}\n",
+ "immutable_classname", name_resolver_->GetImmutableClassName(file_));
+ }
+ // Force descriptor initialization of all dependencies.
for (int i = 0; i < file_->dependency_count(); i++) {
- if (ShouldIncludeDependency(file_->dependency(i))) {
+ if (ShouldIncludeDependency(file_->dependency(i), false)) {
+ string dependency = name_resolver_->GetMutableClassName(
+ file_->dependency(i));
printer->Print(
- " $dependency$.getDescriptor(),\n",
- "dependency", ClassName(file_->dependency(i)));
+ "$dependency$.getDescriptor();\n",
+ "dependency", dependency);
}
}
- printer->Print(
- " }, assigner);\n");
-
printer->Outdent();
printer->Print(
"}\n");
@@ -372,18 +455,22 @@ template<typename GeneratorClass, typename DescriptorClass>
static void GenerateSibling(const string& package_dir,
const string& java_package,
const DescriptorClass* descriptor,
- OutputDirectory* output_directory,
- vector<string>* file_list) {
- string filename = package_dir + descriptor->name() + ".java";
+ GeneratorContext* context,
+ vector<string>* file_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);
- scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(filename));
+ scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
io::Printer printer(output.get(), '$');
printer.Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
- "\n");
+ "// source: $filename$\n"
+ "\n",
+ "filename", descriptor->file()->name());
if (!java_package.empty()) {
printer.Print(
"package $package$;\n"
@@ -391,34 +478,53 @@ static void GenerateSibling(const string& package_dir,
"package", java_package);
}
- GeneratorClass(descriptor).Generate(&printer);
+ (generator->*pfn)(&printer);
}
void FileGenerator::GenerateSiblings(const string& package_dir,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
vector<string>* file_list) {
- if (file_->options().java_multiple_files()) {
+ 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),
- output_directory, file_list);
+ context, file_list, "",
+ &generator,
+ &EnumGenerator::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),
- output_directory, file_list);
+ context, file_list, "",
+ message_generators_[i].get(),
+ &MessageGenerator::Generate);
}
if (HasGenericServices(file_)) {
for (int i = 0; i < file_->service_count(); i++) {
+ scoped_ptr<ServiceGenerator> generator(
+ generator_factory_->NewServiceGenerator(file_->service(i)));
GenerateSibling<ServiceGenerator>(package_dir, java_package_,
file_->service(i),
- output_directory, file_list);
+ context, file_list, "",
+ generator.get(),
+ &ServiceGenerator::Generate);
}
}
}
}
-bool FileGenerator::ShouldIncludeDependency(const FileDescriptor* descriptor) {
+bool FileGenerator::ShouldIncludeDependency(
+ const FileDescriptor* descriptor, bool immutable_api) {
return true;
}
diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h
index 9e35d33..c805b9a 100644
--- a/src/google/protobuf/compiler/java/java_file.h
+++ b/src/google/protobuf/compiler/java/java_file.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,18 +35,26 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
#define GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
+#include <memory>
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
- class FileDescriptor; // descriptor.h
+ class FileDescriptor; // descriptor.h
namespace io {
- class Printer; // printer.h
+ class Printer; // printer.h
}
namespace compiler {
- class OutputDirectory; // code_generator.h
+ class GeneratorContext; // code_generator.h
+ namespace java {
+ class Context; // context.h
+ class MessageGenerator; // message.h
+ class GeneratorFactory; // generator_factory.h
+ class ExtensionGenerator; // extension.h
+ class ClassNameResolver; // name_resolver.h
+ }
}
}
@@ -56,7 +64,7 @@ namespace java {
class FileGenerator {
public:
- explicit FileGenerator(const FileDescriptor* file);
+ FileGenerator(const FileDescriptor* file, bool immutable_api = true);
~FileGenerator();
// Checks for problems that would otherwise lead to cryptic compile errors.
@@ -70,23 +78,31 @@ class FileGenerator {
// files other than the outer file (i.e. one for each message, enum, and
// service type).
void GenerateSiblings(const string& package_dir,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
vector<string>* file_list);
const string& java_package() { return java_package_; }
const string& classname() { return classname_; }
+
private:
- // Returns whether the dependency should be included in the output file.
- // Always returns true for opensource, but used internally at Google to help
- // improve compatibility with version 1 of protocol buffers.
- bool ShouldIncludeDependency(const FileDescriptor* descriptor);
+ void GenerateDescriptorInitializationCodeForImmutable(io::Printer* printer);
+ void GenerateDescriptorInitializationCodeForMutable(io::Printer* printer);
+
+ bool ShouldIncludeDependency(const FileDescriptor* descriptor,
+ bool immutable_api_);
const FileDescriptor* file_;
string java_package_;
string classname_;
- void GenerateEmbeddedDescriptor(io::Printer* printer);
+ scoped_array<scoped_ptr<MessageGenerator> > message_generators_;
+ scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_;
+ scoped_ptr<GeneratorFactory> generator_factory_;
+ scoped_ptr<Context> context_;
+ ClassNameResolver* name_resolver_;
+ 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 745b55a..c3a47e3 100644
--- a/src/google/protobuf/compiler/java/java_generator.cc
+++ b/src/google/protobuf/compiler/java/java_generator.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,8 +33,13 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/java/java_generator.h>
+
+#include <memory>
+
#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_shared_code_generator.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor.pb.h>
@@ -51,11 +56,8 @@ JavaGenerator::~JavaGenerator() {}
bool JavaGenerator::Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
- vector<pair<string, string> > options;
- ParseGeneratorParameter(parameter, &options);
-
// -----------------------------------------------------------------
// parse generator options
@@ -63,50 +65,84 @@ bool JavaGenerator::Generate(const FileDescriptor* file,
// per line.
string output_list_file;
+
+ vector<pair<string, string> > options;
+ ParseGeneratorParameter(parameter, &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;
+ } else if (options[i].first == "immutable") {
+ generate_immutable_code = true;
+ } else if (options[i].first == "mutable") {
+ generate_mutable_code = true;
+ } else if (options[i].first == "shared") {
+ generate_shared_code = true;
} else {
*error = "Unknown generator option: " + options[i].first;
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;
+ }
// -----------------------------------------------------------------
- FileGenerator file_generator(file);
- if (!file_generator.Validate(error)) {
- return false;
+ vector<string> all_files;
+
+ vector<FileGenerator*> file_generators;
+ if (generate_immutable_code) {
+ file_generators.push_back(new FileGenerator(file, /* immutable = */ true));
+ }
+ for (int i = 0; i < file_generators.size(); ++i) {
+ if (!file_generators[i]->Validate(error)) {
+ for (int j = 0; j < file_generators.size(); ++j) {
+ delete file_generators[j];
+ }
+ return false;
+ }
}
- string package_dir =
- StringReplace(file_generator.java_package(), ".", "/", true);
- if (!package_dir.empty()) package_dir += "/";
+ for (int i = 0; i < file_generators.size(); ++i) {
+ FileGenerator* file_generator = file_generators[i];
- vector<string> all_files;
+ string package_dir = JavaPackageToDir(file_generator->java_package());
+
+ string java_filename = package_dir;
+ java_filename += file_generator->classname();
+ java_filename += ".java";
+ all_files.push_back(java_filename);
- string java_filename = package_dir;
- java_filename += file_generator.classname();
- java_filename += ".java";
- all_files.push_back(java_filename);
+ // Generate main java file.
+ scoped_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(java_filename));
+ io::Printer printer(output.get(), '$');
+ file_generator->Generate(&printer);
- // Generate main java file.
- scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(java_filename));
- io::Printer printer(output.get(), '$');
- file_generator.Generate(&printer);
+ // Generate sibling files.
+ file_generator->GenerateSiblings(package_dir, context, &all_files);
+ }
- // Generate sibling files.
- file_generator.GenerateSiblings(package_dir, output_directory, &all_files);
+ for (int i = 0; i < file_generators.size(); ++i) {
+ delete file_generators[i];
+ }
+ file_generators.clear();
// Generate output list if requested.
if (!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.
scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output(
- output_directory->Open(output_list_file));
+ context->Open(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]);
diff --git a/src/google/protobuf/compiler/java/java_generator.h b/src/google/protobuf/compiler/java/java_generator.h
index c91c905..47f76be 100644
--- a/src/google/protobuf/compiler/java/java_generator.h
+++ b/src/google/protobuf/compiler/java/java_generator.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -57,7 +57,7 @@ class LIBPROTOC_EXPORT JavaGenerator : public CodeGenerator {
// implements CodeGenerator ----------------------------------------
bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const;
private:
diff --git a/src/google/protobuf/compiler/java/java_generator_factory.cc b/src/google/protobuf/compiler/java/java_generator_factory.cc
new file mode 100644
index 0000000..2d1437f
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_generator_factory.cc
@@ -0,0 +1,77 @@
+// 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: liujisi@google.com (Pherl Liu)
+
+#include <google/protobuf/compiler/java/java_generator_factory.h>
+
+#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_field.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_message.h>
+#include <google/protobuf/compiler/java/java_service.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+GeneratorFactory::GeneratorFactory() {}
+GeneratorFactory::~GeneratorFactory() {}
+
+// ===================================================================
+
+ImmutableGeneratorFactory::ImmutableGeneratorFactory(
+ Context* context) : context_(context) {
+}
+ImmutableGeneratorFactory::~ImmutableGeneratorFactory() {}
+
+MessageGenerator* ImmutableGeneratorFactory::NewMessageGenerator(
+ const Descriptor* descriptor) const {
+ return new ImmutableMessageGenerator(descriptor, context_);
+}
+
+ExtensionGenerator* ImmutableGeneratorFactory::NewExtensionGenerator(
+ const FieldDescriptor* descriptor) const {
+ return new ImmutableExtensionGenerator(descriptor, context_);
+}
+
+ServiceGenerator* ImmutableGeneratorFactory::NewServiceGenerator(
+ const ServiceDescriptor* descriptor) const {
+ return new ImmutableServiceGenerator(descriptor, context_);
+}
+
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/java/java_generator_factory.h b/src/google/protobuf/compiler/java/java_generator_factory.h
new file mode 100644
index 0000000..55365a9
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_generator_factory.h
@@ -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.
+
+// Author: liujisi@google.com (Pherl Liu)
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_FACTORY_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_FACTORY_H__
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+ class FieldDescriptor; // descriptor.h
+ class Descriptor; // descriptor.h
+ class ServiceDescriptor; // descriptor.h
+ namespace compiler {
+ namespace java {
+ class MessageGenerator; // message.h
+ class ExtensionGenerator; // extension.h
+ class ServiceGenerator; // service.h
+ class Context; // context.h
+ }
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class GeneratorFactory {
+ public:
+ GeneratorFactory();
+ virtual ~GeneratorFactory();
+
+ virtual MessageGenerator* NewMessageGenerator(
+ const Descriptor* descriptor) const = 0;
+
+ virtual ExtensionGenerator* NewExtensionGenerator(
+ const FieldDescriptor* descriptor) const = 0;
+
+ virtual ServiceGenerator* NewServiceGenerator(
+ const ServiceDescriptor* descriptor) const = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorFactory);
+};
+
+// Factory that creates generators for immutable-default messages.
+class ImmutableGeneratorFactory : public GeneratorFactory {
+ public:
+ ImmutableGeneratorFactory(Context* context);
+ virtual ~ImmutableGeneratorFactory();
+
+ virtual MessageGenerator* NewMessageGenerator(
+ const Descriptor* descriptor) const;
+
+ virtual ExtensionGenerator* NewExtensionGenerator(
+ const FieldDescriptor* descriptor) const;
+
+ virtual ServiceGenerator* NewServiceGenerator(
+ const ServiceDescriptor* descriptor) const;
+
+ private:
+ Context* context_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableGeneratorFactory);
+};
+
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_FACTORY_H__
diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc
index 7ed0c3c..3efd7ed 100644
--- a/src/google/protobuf/compiler/java/java_helpers.cc
+++ b/src/google/protobuf/compiler/java/java_helpers.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,11 +32,15 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#include <algorithm>
+#include <google/protobuf/stubs/hash.h>
#include <limits>
#include <vector>
#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
@@ -45,6 +49,9 @@ namespace protobuf {
namespace compiler {
namespace java {
+using internal::WireFormat;
+using internal::WireFormatLite;
+
const char kThickSeparator[] =
"// ===================================================================\n";
const char kThinSeparator[] =
@@ -54,18 +61,47 @@ namespace {
const char* kDefaultPackage = "";
-const string& FieldName(const FieldDescriptor* field) {
+// Names that should be avoided as field names.
+// Using them will cause the compiler to generate accessors whose names are
+// colliding with methods defined in base classes.
+const char* kForbiddenWordList[] = {
+ // message base class:
+ "cached_size", "serialized_size",
+ // java.lang.Object:
+ "class",
+};
+
+bool IsForbidden(const string& field_name) {
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) {
+ if (field_name == kForbiddenWordList[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+string FieldName(const FieldDescriptor* field) {
+ string field_name;
// Groups are hacky: The name of the field is just the lower-cased name
// of the group type. In Java, though, we would like to retain the original
// capitalization of the type name.
if (GetType(field) == FieldDescriptor::TYPE_GROUP) {
- return field->message_type()->name();
+ field_name = field->message_type()->name();
} else {
- return field->name();
+ field_name = field->name();
}
+ if (IsForbidden(field_name)) {
+ // Append a trailing "#" to indicate that the name should be decorated to
+ // avoid collision with other names.
+ field_name += "#";
+ }
+ return field_name;
}
-string UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) {
+
+} // namespace
+
+string UnderscoresToCamelCase(const string& input, bool cap_next_letter) {
string result;
// Note: I distrust ctype.h due to locales.
for (int i = 0; i < input.size(); i++) {
@@ -93,21 +129,27 @@ string UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) {
cap_next_letter = true;
}
}
+ // Add a trailing "_" if the name should be altered.
+ if (input[input.size() - 1] == '#') {
+ result += '_';
+ }
return result;
}
-} // namespace
-
string UnderscoresToCamelCase(const FieldDescriptor* field) {
- return UnderscoresToCamelCaseImpl(FieldName(field), false);
+ return UnderscoresToCamelCase(FieldName(field), false);
}
string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
- return UnderscoresToCamelCaseImpl(FieldName(field), true);
+ return UnderscoresToCamelCase(FieldName(field), true);
}
string UnderscoresToCamelCase(const MethodDescriptor* method) {
- return UnderscoresToCamelCaseImpl(method->name(), false);
+ return UnderscoresToCamelCase(method->name(), false);
+}
+
+string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
+ return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
}
string StripProto(const string& filename) {
@@ -118,35 +160,38 @@ string StripProto(const string& filename) {
}
}
-string FileClassName(const FileDescriptor* file) {
- if (file->options().has_java_outer_classname()) {
- return file->options().java_outer_classname();
- } else {
- string basename;
- string::size_type last_slash = file->name().find_last_of('/');
- if (last_slash == string::npos) {
- basename = file->name();
- } else {
- basename = file->name().substr(last_slash + 1);
- }
- return UnderscoresToCamelCaseImpl(StripProto(basename), true);
- }
+string FileClassName(const FileDescriptor* file, bool immutable) {
+ ClassNameResolver name_resolver;
+ return name_resolver.GetFileClassName(file, immutable);
}
-string FileJavaPackage(const FileDescriptor* file) {
+string FileJavaPackage(const FileDescriptor* file, bool immutable) {
+ string result;
+
if (file->options().has_java_package()) {
- return file->options().java_package();
+ result = file->options().java_package();
} else {
- string result = kDefaultPackage;
+ result = kDefaultPackage;
if (!file->package().empty()) {
if (!result.empty()) result += '.';
result += file->package();
}
- return result;
}
+
+ return result;
+}
+
+string JavaPackageToDir(string package_name) {
+ string package_dir =
+ StringReplace(package_name, ".", "/", true);
+ if (!package_dir.empty()) package_dir += "/";
+ return package_dir;
}
-string ToJavaName(const string& full_name, const FileDescriptor* file) {
+// TODO(xiaofeng): This function is only kept for it's publicly referenced.
+// It should be removed after mutable API up-integration.
+string ToJavaName(const string& full_name,
+ const FileDescriptor* file) {
string result;
if (file->options().java_multiple_files()) {
result = FileJavaPackage(file);
@@ -166,11 +211,43 @@ string ToJavaName(const string& full_name, const FileDescriptor* file) {
return result;
}
+string ClassName(const Descriptor* descriptor) {
+ ClassNameResolver name_resolver;
+ return name_resolver.GetClassName(descriptor, true);
+}
+
+string ClassName(const EnumDescriptor* descriptor) {
+ ClassNameResolver name_resolver;
+ return name_resolver.GetClassName(descriptor, true);
+}
+
+string ClassName(const ServiceDescriptor* descriptor) {
+ ClassNameResolver name_resolver;
+ return name_resolver.GetClassName(descriptor, true);
+}
+
string ClassName(const FileDescriptor* descriptor) {
- string result = FileJavaPackage(descriptor);
- if (!result.empty()) result += '.';
- result += FileClassName(descriptor);
- return result;
+ ClassNameResolver name_resolver;
+ return name_resolver.GetClassName(descriptor, true);
+}
+
+string ExtraMessageInterfaces(const Descriptor* descriptor) {
+ string interfaces = "// @@protoc_insertion_point(message_implements:"
+ + descriptor->full_name() + ")";
+ return interfaces;
+}
+
+
+string ExtraBuilderInterfaces(const Descriptor* descriptor) {
+ string interfaces = "// @@protoc_insertion_point(builder_implements:"
+ + descriptor->full_name() + ")";
+ return interfaces;
+}
+
+string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor) {
+ string interfaces = "// @@protoc_insertion_point(interface_extends:"
+ + descriptor->full_name() + ")";
+ return interfaces;
}
string FieldConstantName(const FieldDescriptor *field) {
@@ -249,6 +326,35 @@ const char* BoxedPrimitiveTypeName(JavaType type) {
return NULL;
}
+const char* FieldTypeName(FieldDescriptor::Type field_type) {
+ switch (field_type) {
+ 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_BOOL : return "BOOL";
+ case FieldDescriptor::TYPE_STRING : return "STRING";
+ case FieldDescriptor::TYPE_BYTES : return "BYTES";
+ case FieldDescriptor::TYPE_ENUM : return "ENUM";
+ case FieldDescriptor::TYPE_GROUP : return "GROUP";
+ case FieldDescriptor::TYPE_MESSAGE : return "MESSAGE";
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
bool AllAscii(const string& text) {
for (int i = 0; i < text.size(); i++) {
if ((text[i] & 0x80) != 0) {
@@ -258,7 +364,8 @@ bool AllAscii(const string& text) {
return true;
}
-string DefaultValue(const FieldDescriptor* field) {
+string DefaultValue(const FieldDescriptor* field, bool immutable,
+ ClassNameResolver* name_resolver) {
// Switch on CppType since we need to know which default_value_* method
// of FieldDescriptor to call.
switch (field->cpp_type()) {
@@ -315,17 +422,18 @@ string DefaultValue(const FieldDescriptor* field) {
} else {
// See comments in Internal.java for gory details.
return strings::Substitute(
- "com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
- CEscape(field->default_value_string()));
+ "com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
+ CEscape(field->default_value_string()));
}
}
case FieldDescriptor::CPPTYPE_ENUM:
- return ClassName(field->enum_type()) + "." +
- field->default_value_enum()->name();
+ return name_resolver->GetClassName(field->enum_type(), immutable) + "." +
+ field->default_value_enum()->name();
case FieldDescriptor::CPPTYPE_MESSAGE:
- return ClassName(field->message_type()) + ".getDefaultInstance()";
+ return name_resolver->GetClassName(field->message_type(), immutable) +
+ ".getDefaultInstance()";
// No default because we want the compiler to complain if any new
// types are added.
@@ -335,6 +443,294 @@ string DefaultValue(const FieldDescriptor* field) {
return "";
}
+bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
+ // Switch on CppType since we need to know which default_value_* method
+ // of FieldDescriptor to call.
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return field->default_value_int32() == 0;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return field->default_value_uint32() == 0;
+ case FieldDescriptor::CPPTYPE_INT64:
+ return field->default_value_int64() == 0L;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return field->default_value_uint64() == 0L;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return field->default_value_double() == 0.0;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ 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:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return false;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
+const char* bit_masks[] = {
+ "0x00000001",
+ "0x00000002",
+ "0x00000004",
+ "0x00000008",
+ "0x00000010",
+ "0x00000020",
+ "0x00000040",
+ "0x00000080",
+
+ "0x00000100",
+ "0x00000200",
+ "0x00000400",
+ "0x00000800",
+ "0x00001000",
+ "0x00002000",
+ "0x00004000",
+ "0x00008000",
+
+ "0x00010000",
+ "0x00020000",
+ "0x00040000",
+ "0x00080000",
+ "0x00100000",
+ "0x00200000",
+ "0x00400000",
+ "0x00800000",
+
+ "0x01000000",
+ "0x02000000",
+ "0x04000000",
+ "0x08000000",
+ "0x10000000",
+ "0x20000000",
+ "0x40000000",
+ "0x80000000",
+};
+
+string GetBitFieldName(int index) {
+ string varName = "bitField";
+ varName += SimpleItoa(index);
+ varName += "_";
+ return varName;
+}
+
+string GetBitFieldNameForBit(int bitIndex) {
+ return GetBitFieldName(bitIndex / 32);
+}
+
+namespace {
+
+string GenerateGetBitInternal(const string& prefix, int bitIndex) {
+ string varName = prefix + GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ string mask = bit_masks[bitInVarIndex];
+ string result = "((" + varName + " & " + mask + ") == " + mask + ")";
+ return result;
+}
+
+string GenerateSetBitInternal(const string& prefix, int bitIndex) {
+ string varName = prefix + GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ string mask = bit_masks[bitInVarIndex];
+ string result = varName + " |= " + mask;
+ return result;
+}
+
+} // namespace
+
+string GenerateGetBit(int bitIndex) {
+ return GenerateGetBitInternal("", bitIndex);
+}
+
+string GenerateSetBit(int bitIndex) {
+ return GenerateSetBitInternal("", bitIndex);
+}
+
+string GenerateClearBit(int bitIndex) {
+ string varName = GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ string mask = bit_masks[bitInVarIndex];
+ string result = varName + " = (" + varName + " & ~" + mask + ")";
+ return result;
+}
+
+string GenerateGetBitFromLocal(int bitIndex) {
+ return GenerateGetBitInternal("from_", bitIndex);
+}
+
+string GenerateSetBitToLocal(int bitIndex) {
+ return GenerateSetBitInternal("to_", bitIndex);
+}
+
+string GenerateGetBitMutableLocal(int bitIndex) {
+ return GenerateGetBitInternal("mutable_", bitIndex);
+}
+
+string GenerateSetBitMutableLocal(int bitIndex) {
+ return GenerateSetBitInternal("mutable_", bitIndex);
+}
+
+bool IsReferenceType(JavaType type) {
+ switch (type) {
+ case JAVATYPE_INT : return false;
+ case JAVATYPE_LONG : return false;
+ case JAVATYPE_FLOAT : return false;
+ case JAVATYPE_DOUBLE : return false;
+ case JAVATYPE_BOOLEAN: return false;
+ case JAVATYPE_STRING : return true;
+ case JAVATYPE_BYTES : return true;
+ case JAVATYPE_ENUM : return true;
+ case JAVATYPE_MESSAGE: return true;
+
+ // No default because we want the compiler to complain if any new
+ // JavaTypes are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
+const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable) {
+ switch (GetType(field)) {
+ 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_BOOL : return "Bool";
+ case FieldDescriptor::TYPE_STRING : return "String";
+ case FieldDescriptor::TYPE_BYTES : {
+ return "Bytes";
+ }
+ case FieldDescriptor::TYPE_ENUM : return "Enum";
+ case FieldDescriptor::TYPE_GROUP : return "Group";
+ case FieldDescriptor::TYPE_MESSAGE : return "Message";
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+// For encodings with fixed sizes, returns that size in bytes. Otherwise
+// returns -1.
+int FixedSize(FieldDescriptor::Type type) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32 : return -1;
+ case FieldDescriptor::TYPE_INT64 : return -1;
+ case FieldDescriptor::TYPE_UINT32 : return -1;
+ case FieldDescriptor::TYPE_UINT64 : return -1;
+ case FieldDescriptor::TYPE_SINT32 : return -1;
+ case FieldDescriptor::TYPE_SINT64 : return -1;
+ case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
+ case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
+ case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
+ case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
+ case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize;
+ case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize;
+
+ case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize;
+ case FieldDescriptor::TYPE_ENUM : return -1;
+
+ case FieldDescriptor::TYPE_STRING : return -1;
+ case FieldDescriptor::TYPE_BYTES : return -1;
+ case FieldDescriptor::TYPE_GROUP : return -1;
+ case FieldDescriptor::TYPE_MESSAGE : return -1;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return -1;
+}
+
+// Sort the fields of the given Descriptor by number into a new[]'d array
+// and return it. The caller should delete the returned array.
+const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
+ const FieldDescriptor** fields =
+ new const FieldDescriptor*[descriptor->field_count()];
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ fields[i] = descriptor->field(i);
+ }
+ sort(fields, fields + descriptor->field_count(),
+ FieldOrderingByNumber());
+ return fields;
+}
+
+// Returns true if the message type has any required fields. If it doesn't,
+// we can optimize out calls to its isInitialized() method.
+//
+// already_seen is used to avoid checking the same type multiple times
+// (and also to protect against recursion).
+bool HasRequiredFields(
+ const Descriptor* type,
+ hash_set<const Descriptor*>* already_seen) {
+ if (already_seen->count(type) > 0) {
+ // The type is already in cache. This means that either:
+ // a. The type has no required fields.
+ // b. We are in the midst of checking if the type has required fields,
+ // somewhere up the stack. In this case, we know that if the type
+ // has any required fields, they'll be found when we return to it,
+ // and the whole call to HasRequiredFields() will return true.
+ // Therefore, we don't have to check if this type has required fields
+ // here.
+ return false;
+ }
+ already_seen->insert(type);
+
+ // If the type has extensions, an extension with message type could contain
+ // required fields, so we have to be conservative and assume such an
+ // extension exists.
+ if (type->extension_range_count() > 0) return true;
+
+ for (int i = 0; i < type->field_count(); i++) {
+ const FieldDescriptor* field = type->field(i);
+ if (field->is_required()) {
+ return true;
+ }
+ if (GetJavaType(field) == JAVATYPE_MESSAGE) {
+ if (HasRequiredFields(field->message_type(), already_seen)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool HasRequiredFields(const Descriptor* type) {
+ hash_set<const Descriptor*> already_seen;
+ return HasRequiredFields(type, &already_seen);
+}
+
+bool HasRepeatedFields(const Descriptor* descriptor) {
+ for (int i = 0; i < descriptor->field_count(); ++i) {
+ const FieldDescriptor* field = descriptor->field(i);
+ if (field->is_repeated()) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h
index 3c8974c..93f23a9 100644
--- a/src/google/protobuf/compiler/java/java_helpers.h
+++ b/src/google/protobuf/compiler/java/java_helpers.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -49,6 +49,9 @@ namespace java {
extern const char kThickSeparator[];
extern const char kThinSeparator[];
+// 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);
// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes
// "fooBarBaz" or "FooBarBaz", respectively.
string UnderscoresToCamelCase(const FieldDescriptor* field);
@@ -58,36 +61,70 @@ string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field);
// of lower-casing the first letter of the name.)
string UnderscoresToCamelCase(const MethodDescriptor* method);
+// Get an identifier that uniquely identifies this type within the file.
+// This is used to declare static variables related to this type at the
+// outermost file scope.
+string UniqueFileScopeIdentifier(const Descriptor* descriptor);
+
// Strips ".proto" or ".protodevel" from the end of a filename.
string StripProto(const string& filename);
-// Gets the unqualified class name for the file. Each .proto file becomes a
-// single Java class, with all its contents nested in that class.
-string FileClassName(const FileDescriptor* file);
+// Gets the unqualified class name for the file. For each .proto file, there
+// will be one Java class containing all the immutable messages and another
+// Java class containing all the mutable messages.
+// TODO(xiaofeng): remove the default value after updating client code.
+string FileClassName(const FileDescriptor* file, bool immutable = true);
// Returns the file's Java package name.
-string FileJavaPackage(const FileDescriptor* file);
+string FileJavaPackage(const FileDescriptor* file, bool immutable = true);
+
+// Returns output directory for the given package name.
+string JavaPackageToDir(string package_name);
// Converts the given fully-qualified name in the proto namespace to its
// fully-qualified name in the Java namespace, given that it is in the given
// file.
-string ToJavaName(const string& full_name, const FileDescriptor* file);
+// TODO(xiaofeng): this method is deprecated and should be removed in the
+// future.
+string ToJavaName(const string& full_name,
+ const FileDescriptor* file);
-// These return the fully-qualified class name corresponding to the given
-// descriptor.
-inline string ClassName(const Descriptor* descriptor) {
- return ToJavaName(descriptor->full_name(), descriptor->file());
-}
-inline string ClassName(const EnumDescriptor* descriptor) {
- return ToJavaName(descriptor->full_name(), descriptor->file());
-}
-inline string ClassName(const ServiceDescriptor* descriptor) {
- return ToJavaName(descriptor->full_name(), descriptor->file());
+// TODO(xiaofeng): the following methods are kept for they are exposed
+// publicly in //google/protobuf/compiler/java/names.h. They return
+// immutable names only and should be removed after mutable API is
+// integrated into google3.
+string ClassName(const Descriptor* descriptor);
+string ClassName(const EnumDescriptor* descriptor);
+string ClassName(const ServiceDescriptor* descriptor);
+string ClassName(const FileDescriptor* descriptor);
+
+// Comma-separate list of option-specified interfaces implemented by the
+// Message, to follow the "implements" declaration of the Message definition.
+string ExtraMessageInterfaces(const Descriptor* descriptor);
+// Comma-separate list of option-specified interfaces implemented by the
+// MutableMessage, to follow the "implements" declaration of the MutableMessage
+// definition.
+string ExtraMutableMessageInterfaces(const Descriptor* descriptor);
+// Comma-separate list of option-specified interfaces implemented by the
+// Builder, to follow the "implements" declaration of the Builder definition.
+string ExtraBuilderInterfaces(const Descriptor* descriptor);
+// Comma-separate list of option-specified interfaces extended by the
+// MessageOrBuilder, to follow the "extends" declaration of the
+// MessageOrBuilder definition.
+string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor);
+
+// Get the unqualified Java class name for mutable messages. i.e. without
+// package or outer classnames.
+inline string ShortMutableJavaClassName(const Descriptor* descriptor) {
+ return descriptor->name();
}
-inline string ExtensionIdentifierName(const FieldDescriptor* descriptor) {
- return ToJavaName(descriptor->full_name(), descriptor->file());
+
+
+// Whether we should generate multiple java files for messages.
+inline bool MultipleJavaFiles(
+ const FileDescriptor* descriptor, bool immutable) {
+ return descriptor->options().java_multiple_files();
}
-string ClassName(const FileDescriptor* descriptor);
// Get the unqualified name that should be used for a field's field
// number constant.
@@ -117,10 +154,23 @@ JavaType GetJavaType(const FieldDescriptor* field);
// types.
const char* BoxedPrimitiveTypeName(JavaType type);
-string DefaultValue(const FieldDescriptor* field);
+// Get the name of the java enum constant representing this type. E.g.,
+// "INT32" for FieldDescriptor::TYPE_INT32. The enum constant's full
+// name is "com.google.protobuf.WireFormat.FieldType.INT32".
+const char* FieldTypeName(const FieldDescriptor::Type field_type);
-// Does this message class keep track of unknown fields?
-inline bool HasUnknownFields(const Descriptor* descriptor) {
+class ClassNameResolver;
+string DefaultValue(const FieldDescriptor* field, bool immutable,
+ ClassNameResolver* name_resolver);
+inline string ImmutableDefaultValue(const FieldDescriptor* field,
+ ClassNameResolver* name_resolver) {
+ return DefaultValue(field, true, name_resolver);
+}
+bool IsDefaultValueJavaDefault(const FieldDescriptor* field);
+
+// Does this message class use UnknownFieldSet?
+// Otherwise, unknown fields will be stored in a ByteString object
+inline bool UseUnknownFieldSet(const Descriptor* descriptor) {
return descriptor->file()->options().optimize_for() !=
FileOptions::LITE_RUNTIME;
}
@@ -132,6 +182,11 @@ inline bool HasGeneratedMethods(const Descriptor* descriptor) {
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();
+}
+
// Does this message class have descriptor and reflection methods?
inline bool HasDescriptorMethods(const Descriptor* descriptor) {
return descriptor->file()->options().optimize_for() !=
@@ -146,6 +201,12 @@ inline bool HasDescriptorMethods(const FileDescriptor* descriptor) {
FileOptions::LITE_RUNTIME;
}
+inline bool HasNestedBuilders(const Descriptor* descriptor) {
+ // The proto-lite version doesn't support nested builders.
+ return descriptor->file()->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME;
+}
+
// Should we generate generic services for this file?
inline bool HasGenericServices(const FileDescriptor *file) {
return file->service_count() > 0 &&
@@ -153,6 +214,106 @@ inline bool HasGenericServices(const FileDescriptor *file) {
file->options().java_generic_services();
}
+inline bool IsLazy(const FieldDescriptor* descriptor) {
+ // Currently, the proto-lite version suports lazy field.
+ // TODO(niwasaki): Support lazy fields also for other proto runtimes.
+ if (descriptor->file()->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME) {
+ return false;
+ }
+ return descriptor->options().lazy();
+}
+
+// Methods for shared bitfields.
+
+// Gets the name of the shared bitfield for the given index.
+string GetBitFieldName(int index);
+
+// Gets the name of the shared bitfield for the given bit index.
+// Effectively, GetBitFieldName(bitIndex / 32)
+string GetBitFieldNameForBit(int bitIndex);
+
+// Generates the java code for the expression that returns the boolean value
+// of the bit of the shared bitfields for the given bit index.
+// Example: "((bitField1_ & 0x04) == 0x04)"
+string GenerateGetBit(int bitIndex);
+
+// Generates the java code for the expression that sets the bit of the shared
+// bitfields for the given bit index.
+// Example: "bitField1_ = (bitField1_ | 0x04)"
+string GenerateSetBit(int bitIndex);
+
+// Generates the java code for the expression that clears the bit of the shared
+// bitfields for the given bit index.
+// Example: "bitField1_ = (bitField1_ & ~0x04)"
+string GenerateClearBit(int bitIndex);
+
+// Does the same as GenerateGetBit but operates on the bit field on a local
+// variable. This is used by the builder to copy the value in the builder to
+// the message.
+// Example: "((from_bitField1_ & 0x04) == 0x04)"
+string GenerateGetBitFromLocal(int bitIndex);
+
+// Does the same as GenerateSetBit but operates on the bit field on a local
+// variable. This is used by the builder to copy the value in the builder to
+// the message.
+// Example: "to_bitField1_ = (to_bitField1_ | 0x04)"
+string GenerateSetBitToLocal(int bitIndex);
+
+// Does the same as GenerateGetBit but operates on the bit field on a local
+// variable. This is used by the parsing constructor to record if a repeated
+// field is mutable.
+// Example: "((mutable_bitField1_ & 0x04) == 0x04)"
+string GenerateGetBitMutableLocal(int bitIndex);
+
+// Does the same as GenerateSetBit but operates on the bit field on a local
+// variable. This is used by the parsing constructor to record if a repeated
+// field is mutable.
+// Example: "mutable_bitField1_ = (mutable_bitField1_ | 0x04)"
+string GenerateSetBitMutableLocal(int bitIndex);
+
+// Returns whether the JavaType is a reference type.
+bool IsReferenceType(JavaType type);
+
+// Returns the capitalized name for calling relative functions in
+// CodedInputStream
+const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable);
+
+// For encodings with fixed sizes, returns that size in bytes. Otherwise
+// returns -1.
+int FixedSize(FieldDescriptor::Type type);
+
+// Comparators used to sort fields in MessageGenerator
+struct FieldOrderingByNumber {
+ inline bool operator()(const FieldDescriptor* a,
+ const FieldDescriptor* b) const {
+ return a->number() < b->number();
+ }
+};
+
+struct ExtensionRangeOrdering {
+ bool operator()(const Descriptor::ExtensionRange* a,
+ const Descriptor::ExtensionRange* b) const {
+ return a->start < b->start;
+ }
+};
+
+// Sort the fields of the given Descriptor by number into a new[]'d array
+// and return it. The caller should delete the returned array.
+const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor);
+
+// Check a message type and its sub-message types recursively to see if any of
+// them has a required field. Return true if a required field is found.
+bool HasRequiredFields(const Descriptor* descriptor);
+
+// Whether a .proto file supports field presence test for non-message types.
+inline bool SupportFieldPresence(const FileDescriptor* descriptor) {
+ return true;
+}
+
+// Check whether a mesasge has repeated fields.
+bool HasRepeatedFields(const Descriptor* descriptor);
+
} // 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
new file mode 100644
index 0000000..21cab7d
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_lazy_message_field.cc
@@ -0,0 +1,826 @@
+// 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: niwasaki@google.com (Naoki Iwasaki)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_lazy_message_field.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+ImmutableLazyMessageFieldGenerator::
+ImmutableLazyMessageFieldGenerator(
+ const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : ImmutableMessageFieldGenerator(
+ descriptor, messageBitIndex, builderBitIndex, context) {
+}
+
+ImmutableLazyMessageFieldGenerator::~ImmutableLazyMessageFieldGenerator() {}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private com.google.protobuf.LazyFieldLite $name$_ =\n"
+ " new com.google.protobuf.LazyFieldLite();\n");
+
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return ($type$) $name$_.getValue($type$.getDefaultInstance());\n"
+ "}\n");
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+ " return $name$_;\n"
+ "}\n");
+ }
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ // When using nested-builders, the code initially works just like the
+ // non-nested builder case. It only creates a nested builder lazily on
+ // demand and then forever delegates to it after creation.
+
+ printer->Print(variables_,
+ "private com.google.protobuf.LazyFieldLite $name$_ =\n"
+ " new com.google.protobuf.LazyFieldLite();\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ // If this builder is non-null, it is used and the other fields are
+ // ignored.
+ "private com.google.protobuf.SingleFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
+ "\n");
+ }
+
+ // The comments above the methods below are based on a hypothetical
+ // field of type "Field" called "Field".
+
+ // boolean hasField()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return ($type$) $name$_.getValue($type$.getDefaultInstance());\n"
+ "}\n");
+
+ // Field.Builder setField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$($type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "$name$_.setValue(value);\n"
+ "$on_changed$\n",
+
+ NULL, // Lazy fields are supported only for lite-runtime.
+
+ "$set_has_field_bit_builder$;\n"
+ "return this;\n");
+
+ // Field.Builder setField(Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " $type$.Builder builderForValue)",
+
+ "$name$_.setValue(builderForValue.build());\n"
+ "$on_changed$\n",
+
+ NULL,
+
+ "$set_has_field_bit_builder$;\n"
+ "return this;\n");
+
+ // Field.Builder mergeField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder merge$capitalized_name$($type$ value)",
+
+ "if ($get_has_field_bit_builder$ &&\n"
+ " !$name$_.containsDefaultInstance()) {\n"
+ " $name$_.setValue(\n"
+ " $type$.newBuilder(\n"
+ " get$capitalized_name$()).mergeFrom(value).buildPartial());\n"
+ "} else {\n"
+ " $name$_.setValue(value);\n"
+ "}\n"
+ "$on_changed$\n",
+
+ NULL,
+
+ "$set_has_field_bit_builder$;\n"
+ "return this;\n");
+
+ // Field.Builder clearField()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder clear$capitalized_name$()",
+
+ "$name$_.clear();\n"
+ "$on_changed$\n",
+
+ NULL,
+
+ "$clear_has_field_bit_builder$;\n"
+ "return this;\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n"
+ " $set_has_field_bit_builder$;\n"
+ " $on_changed$\n"
+ " return get$capitalized_name$FieldBuilder().getBuilder();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+ " if ($name$Builder_ != null) {\n"
+ " return $name$Builder_.getMessageOrBuilder();\n"
+ " } else {\n"
+ " return $name$_;\n"
+ " }\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private com.google.protobuf.SingleFieldBuilder<\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"
+ " $type$, $type$.Builder, $type$OrBuilder>(\n"
+ " $name$_,\n"
+ " getParentForChildren(),\n"
+ " isClean());\n"
+ " $name$_ = null;\n"
+ " }\n"
+ " return $name$Builder_;\n"
+ "}\n");
+ }
+}
+
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.clear();\n");
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.clear();\n");
+ printer->Print(variables_, "$clear_has_field_bit_builder$;\n");
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (other.has$capitalized_name$()) {\n"
+ " $name$_.merge(other.$name$_);\n"
+ " $set_has_field_bit_builder$;\n"
+ "}\n");
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "result.$name$_.setByteString(\n"
+ " $name$_.toByteString(),\n"
+ " $name$_.getExtensionRegistry());\n");
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_.setByteString(input.readBytes(), extensionRegistry);\n");
+ printer->Print(variables_,
+ "$set_has_field_bit_message$;\n");
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ // Do not de-serialize lazy fields.
+ printer->Print(variables_,
+ "if ($get_has_field_bit_message$) {\n"
+ " output.writeBytes($number$, $name$_.toByteString());\n"
+ "}\n");
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeLazyFieldSize($number$, $name$_);\n"
+ "}\n");
+}
+
+// ===================================================================
+
+ImmutableLazyMessageOneofFieldGenerator::
+ImmutableLazyMessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : ImmutableLazyMessageFieldGenerator(
+ descriptor, messageBitIndex, builderBitIndex, context) {
+ const OneofGeneratorInfo* info =
+ context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+ SetCommonOneofVariables(descriptor, info, &variables_);
+ variables_["lazy_type"] = "com.google.protobuf.LazyFieldLite";
+}
+
+ImmutableLazyMessageOneofFieldGenerator::
+~ImmutableLazyMessageOneofFieldGenerator() {}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldDocComment(printer, descriptor_);
+
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($type$) (($lazy_type$) $oneof_name$_).getValue(\n"
+ " $type$.getDefaultInstance());\n"
+ " }\n"
+ " return $type$.getDefaultInstance();\n"
+ "}\n");
+}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ // boolean hasField()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($type$) (($lazy_type$) $oneof_name$_).getValue(\n"
+ " $type$.getDefaultInstance());\n"
+ " }\n"
+ " return $type$.getDefaultInstance();\n"
+ "}\n");
+
+ // Field.Builder setField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$($type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "if (!($has_oneof_case_message$)) {\n"
+ " $oneof_name$_ = new $lazy_type$();\n"
+ " $set_oneof_case_message$;\n"
+ "}\n"
+ "(($lazy_type$) $oneof_name$_).setValue(value);\n"
+ "$on_changed$\n",
+
+ NULL, // Lazy fields are supported only for lite-runtime.
+
+ "return this;\n");
+
+ // Field.Builder setField(Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " $type$.Builder builderForValue)",
+
+ "if (!($has_oneof_case_message$)) {\n"
+ " $oneof_name$_ = new $lazy_type$();\n"
+ " $set_oneof_case_message$;\n"
+ "}\n"
+ "(($lazy_type$) $oneof_name$_).setValue(builderForValue.build());\n"
+ "$on_changed$\n",
+
+ NULL,
+
+ "return this;\n");
+
+ // Field.Builder mergeField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder merge$capitalized_name$($type$ value)",
+
+ "if ($has_oneof_case_message$ &&\n"
+ " !(($lazy_type$) $oneof_name$_).containsDefaultInstance()) {\n"
+ " (($lazy_type$) $oneof_name$_).setValue(\n"
+ " $type$.newBuilder(\n"
+ " get$capitalized_name$()).mergeFrom(value).buildPartial());\n"
+ "} else {\n"
+ " if (!($has_oneof_case_message$)) {\n"
+ " $oneof_name$_ = new $lazy_type$();\n"
+ " $set_oneof_case_message$;\n"
+ " }\n"
+ " (($lazy_type$) $oneof_name$_).setValue(value);\n"
+ "}\n"
+ "$on_changed$\n",
+
+ NULL,
+
+ "return this;\n");
+
+ // Field.Builder clearField()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder clear$capitalized_name$()",
+
+ "if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ " $on_changed$\n"
+ "}\n",
+
+ NULL,
+
+ "return this;\n");
+}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateMergingCode(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");
+}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n");
+ printer->Indent();
+
+ printer->Print(variables_,
+ "result.$oneof_name$_ = new $lazy_type$();\n"
+ "(($lazy_type$) result.$oneof_name$_).setByteString(\n"
+ " (($lazy_type$) $oneof_name$_).toByteString(),\n"
+ " (($lazy_type$) $oneof_name$_).getExtensionRegistry());\n");
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (!($has_oneof_case_message$)) {\n"
+ " $oneof_name$_ = new $lazy_type$();\n"
+ "}\n"
+ "(($lazy_type$) $oneof_name$_).setByteString(\n"
+ " input.readBytes(), extensionRegistry);\n"
+ "$set_oneof_case_message$;\n");
+}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ // Do not de-serialize lazy fields.
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " output.writeBytes(\n"
+ " $number$, (($lazy_type$) $oneof_name$_).toByteString());\n"
+ "}\n");
+}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeLazyFieldSize($number$, ($lazy_type$) $oneof_name$_);\n"
+ "}\n");
+}
+
+// ===================================================================
+
+RepeatedImmutableLazyMessageFieldGenerator::
+RepeatedImmutableLazyMessageFieldGenerator(
+ const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : RepeatedImmutableMessageFieldGenerator(
+ descriptor, messageBitIndex, builderBitIndex, context) {
+}
+
+
+RepeatedImmutableLazyMessageFieldGenerator::
+~RepeatedImmutableLazyMessageFieldGenerator() {}
+
+void RepeatedImmutableLazyMessageFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private java.util.List<com.google.protobuf.LazyFieldLite> $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<$type$>\n"
+ " get$capitalized_name$List() {\n"
+ " java.util.List<$type$> list =\n"
+ " new java.util.ArrayList<$type$>($name$_.size());\n"
+ " for (com.google.protobuf.LazyFieldLite lf : $name$_) {\n"
+ " list.add(($type$) lf.getValue($type$.getDefaultInstance()));\n"
+ " }\n"
+ " return list;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<? extends $type$OrBuilder>\n"
+ " get$capitalized_name$OrBuilderList() {\n"
+ " return get$capitalized_name$List();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+ " return ($type$)\n"
+ " $name$_.get(index).getValue($type$.getDefaultInstance());\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
+ " int index) {\n"
+ " return ($type$OrBuilder)\n"
+ " $name$_.get(index).getValue($type$.getDefaultInstance());\n"
+ "}\n");
+}
+
+void RepeatedImmutableLazyMessageFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ // When using nested-builders, the code initially works just like the
+ // non-nested builder case. It only creates a nested builder lazily on
+ // demand and then forever delegates to it after creation.
+
+ printer->Print(variables_,
+ "private java.util.List<com.google.protobuf.LazyFieldLite> $name$_ =\n"
+ " java.util.Collections.emptyList();\n"
+
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ =\n"
+ " new java.util.ArrayList<com.google.protobuf.LazyFieldLite>(\n"
+ " $name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n"
+ "\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ // If this builder is non-null, it is used and the other fields are
+ // ignored.
+ "private com.google.protobuf.RepeatedFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
+ "\n");
+ }
+
+ // The comments above the methods below are based on a hypothetical
+ // repeated field of type "Field" called "RepeatedField".
+
+ // List<Field> getRepeatedFieldList()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public java.util.List<$type$> get$capitalized_name$List()",
+
+ "java.util.List<$type$> list =\n"
+ " new java.util.ArrayList<$type$>($name$_.size());\n"
+ "for (com.google.protobuf.LazyFieldLite lf : $name$_) {\n"
+ " list.add(($type$) lf.getValue($type$.getDefaultInstance()));\n"
+ "}\n"
+ "return java.util.Collections.unmodifiableList(list);\n",
+
+ "return $name$Builder_.getMessageList();\n",
+
+ NULL);
+
+ // int getRepeatedFieldCount()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public int get$capitalized_name$Count()",
+
+ "return $name$_.size();\n",
+ "return $name$Builder_.getCount();\n",
+
+ NULL);
+
+ // Field getRepeatedField(int index)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public $type$ get$capitalized_name$(int index)",
+
+ "return ($type$) $name$_.get(index).getValue(\n"
+ " $type$.getDefaultInstance());\n",
+
+ "return $name$Builder_.getMessage(index);\n",
+
+ NULL);
+
+ // Builder setRepeatedField(int index, Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$ value)",
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.set(index, com.google.protobuf.LazyFieldLite.fromValue(value));\n"
+ "$on_changed$\n",
+ "$name$Builder_.setMessage(index, value);\n",
+ "return this;\n");
+
+ // Builder setRepeatedField(int index, Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.set(index, com.google.protobuf.LazyFieldLite.fromValue(\n"
+ " builderForValue.build()));\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(index, builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$($type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(com.google.protobuf.LazyFieldLite.fromValue(value));\n"
+
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(value);\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(int index, Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " int index, $type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(index, com.google.protobuf.LazyFieldLite.fromValue(value));\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(index, value);\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(com.google.protobuf.LazyFieldLite.fromValue(\n"
+ " builderForValue.build()));\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(int index, Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " int index, $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(index, com.google.protobuf.LazyFieldLite.fromValue(\n"
+ " builderForValue.build()));\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(index, builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addAllRepeatedField(Iterable<Field> values)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder addAll$capitalized_name$(\n"
+ " java.lang.Iterable<? extends $type$> values)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "for (com.google.protobuf.MessageLite v : values) {\n"
+ " $name$_.add(com.google.protobuf.LazyFieldLite.fromValue(v));\n"
+ "}\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addAllMessages(values);\n",
+
+ "return this;\n");
+
+ // Builder clearAllRepeatedField()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder clear$capitalized_name$()",
+
+ "$name$_ = java.util.Collections.emptyList();\n"
+ "$clear_mutable_bit_builder$;\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.clear();\n",
+
+ "return this;\n");
+
+ // Builder removeRepeatedField(int index)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder remove$capitalized_name$(int index)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.remove(index);\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.remove(index);\n",
+
+ "return this;\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder get$capitalized_name$Builder(\n"
+ " int index) {\n"
+ " return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
+ " int index) {\n"
+ " if ($name$Builder_ == null) {\n"
+ " return $name$_.get(index);"
+ " } else {\n"
+ " return $name$Builder_.getMessageOrBuilder(index);\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
+ " get$capitalized_name$OrBuilderList() {\n"
+ " if ($name$Builder_ != null) {\n"
+ " return $name$Builder_.getMessageOrBuilderList();\n"
+ " } else {\n"
+ " return java.util.Collections.unmodifiableList($name$_);\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n"
+ " return get$capitalized_name$FieldBuilder().addBuilder(\n"
+ " $type$.getDefaultInstance());\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder add$capitalized_name$Builder(\n"
+ " int index) {\n"
+ " return get$capitalized_name$FieldBuilder().addBuilder(\n"
+ " index, $type$.getDefaultInstance());\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<$type$.Builder> \n"
+ " get$capitalized_name$BuilderList() {\n"
+ " return get$capitalized_name$FieldBuilder().getBuilderList();\n"
+ "}\n"
+ "private com.google.protobuf.RepeatedFieldBuilder<\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"
+ " $type$, $type$.Builder, $type$OrBuilder>(\n"
+ " $name$_,\n"
+ " $get_mutable_bit_builder$,\n"
+ " getParentForChildren(),\n"
+ " isClean());\n"
+ " $name$_ = null;\n"
+ " }\n"
+ " return $name$Builder_;\n"
+ "}\n");
+ }
+}
+
+void RepeatedImmutableLazyMessageFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (!$get_mutable_bit_parser$) {\n"
+ " $name$_ =\n"
+ " new java.util.ArrayList<com.google.protobuf.LazyFieldLite>();\n"
+ " $set_mutable_bit_parser$;\n"
+ "}\n"
+ "$name$_.add(new com.google.protobuf.LazyFieldLite(\n"
+ " extensionRegistry, input.readBytes()));\n");
+}
+
+void RepeatedImmutableLazyMessageFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.writeBytes($number$, $name$_.get(i).toByteString());\n"
+ "}\n");
+}
+
+void RepeatedImmutableLazyMessageFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeLazyFieldSize($number$, $name$_.get(i));\n"
+ "}\n");
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field.h b/src/google/protobuf/compiler/java/java_lazy_message_field.h
new file mode 100644
index 0000000..b1b7f28
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_lazy_message_field.h
@@ -0,0 +1,121 @@
+// 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: niwasaki@google.com (Naoki Iwasaki)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_H__
+
+#include <google/protobuf/compiler/java/java_field.h>
+#include <google/protobuf/compiler/java/java_message_field.h>
+
+namespace google {
+namespace protobuf {
+ namespace compiler {
+ namespace java {
+ class Context; // context.h
+ }
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableLazyMessageFieldGenerator
+ : public ImmutableMessageFieldGenerator {
+ public:
+ explicit ImmutableLazyMessageFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~ImmutableLazyMessageFieldGenerator();
+
+ // overroads ImmutableMessageFieldGenerator ---------------------------------
+ void GenerateMembers(io::Printer* printer) const;
+ 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 GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageFieldGenerator);
+};
+
+class ImmutableLazyMessageOneofFieldGenerator
+ : public ImmutableLazyMessageFieldGenerator {
+ public:
+ ImmutableLazyMessageOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~ImmutableLazyMessageOneofFieldGenerator();
+
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageOneofFieldGenerator);
+};
+
+class RepeatedImmutableLazyMessageFieldGenerator
+ : public RepeatedImmutableMessageFieldGenerator {
+ public:
+ explicit RepeatedImmutableLazyMessageFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~RepeatedImmutableLazyMessageFieldGenerator();
+
+ // overroads RepeatedImmutableMessageFieldGenerator -------------------------
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableLazyMessageFieldGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_H__
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index a326057..8aa89ac 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,17 +32,27 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#include <google/protobuf/compiler/java/java_message.h>
+
#include <algorithm>
#include <google/protobuf/stubs/hash.h>
-#include <google/protobuf/compiler/java/java_message.h>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
#include <google/protobuf/compiler/java/java_enum.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>
-#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/io/printer.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/wire_format.h>
+#include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
namespace google {
namespace protobuf {
@@ -53,107 +63,31 @@ using internal::WireFormat;
using internal::WireFormatLite;
namespace {
-
-void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
- // Print the field's proto-syntax definition as a comment. We don't want to
- // print group bodies so we cut off after the first line.
- string def = field->DebugString();
- printer->Print("// $def$\n",
- "def", def.substr(0, def.find_first_of('\n')));
-}
-
-struct FieldOrderingByNumber {
- inline bool operator()(const FieldDescriptor* a,
- const FieldDescriptor* b) const {
- return a->number() < b->number();
- }
-};
-
-struct ExtensionRangeOrdering {
- bool operator()(const Descriptor::ExtensionRange* a,
- const Descriptor::ExtensionRange* b) const {
- return a->start < b->start;
- }
-};
-
-// Sort the fields of the given Descriptor by number into a new[]'d array
-// and return it.
-const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
- const FieldDescriptor** fields =
- new const FieldDescriptor*[descriptor->field_count()];
- for (int i = 0; i < descriptor->field_count(); i++) {
- fields[i] = descriptor->field(i);
- }
- sort(fields, fields + descriptor->field_count(),
- FieldOrderingByNumber());
- return fields;
-}
-
-// Get an identifier that uniquely identifies this type within the file.
-// This is used to declare static variables related to this type at the
-// outermost file scope.
-string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
- return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
-}
-
-// Returns true if the message type has any required fields. If it doesn't,
-// we can optimize out calls to its isInitialized() method.
-//
-// 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) {
- if (already_seen->count(type) > 0) {
- // The type is already in cache. This means that either:
- // a. The type has no required fields.
- // b. We are in the midst of checking if the type has required fields,
- // somewhere up the stack. In this case, we know that if the type
- // has any required fields, they'll be found when we return to it,
- // and the whole call to HasRequiredFields() will return true.
- // Therefore, we don't have to check if this type has required fields
- // here.
- return false;
- }
- already_seen->insert(type);
-
- // If the type has extensions, an extension with message type could contain
- // required fields, so we have to be conservative and assume such an
- // extension exists.
- if (type->extension_range_count() > 0) return true;
-
- for (int i = 0; i < type->field_count(); i++) {
- const FieldDescriptor* field = type->field(i);
- if (field->is_required()) {
- return true;
- }
- if (GetJavaType(field) == JAVATYPE_MESSAGE) {
- if (HasRequiredFields(field->message_type(), already_seen)) {
- return true;
- }
- }
- }
-
- return false;
-}
-
-static bool HasRequiredFields(const Descriptor* type) {
- hash_set<const Descriptor*> already_seen;
- return HasRequiredFields(type, &already_seen);
+bool GenerateHasBits(const Descriptor* descriptor) {
+ return SupportFieldPresence(descriptor->file()) ||
+ HasRepeatedFields(descriptor);
}
-
} // namespace
// ===================================================================
MessageGenerator::MessageGenerator(const Descriptor* descriptor)
- : descriptor_(descriptor),
- field_generators_(descriptor) {
-}
+ : descriptor_(descriptor) {}
MessageGenerator::~MessageGenerator() {}
-void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
+// ===================================================================
+// 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_) {
+}
+
+ImmutableMessageGenerator::~ImmutableMessageGenerator() {}
+
+void ImmutableMessageGenerator::GenerateStaticVariables(io::Printer* printer) {
if (HasDescriptorMethods(descriptor_)) {
// Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
// used in the construction of descriptors, we have a tricky bootstrapping
@@ -165,12 +99,12 @@ void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
map<string, string> vars;
vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
vars["index"] = SimpleItoa(descriptor_->index());
- vars["classname"] = ClassName(descriptor_);
+ vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
if (descriptor_->containing_type() != NULL) {
vars["parent"] = UniqueFileScopeIdentifier(
descriptor_->containing_type());
}
- if (descriptor_->file()->options().java_multiple_files()) {
+ if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
// We can only make these package-private since the classes that use them
// are in separate files.
vars["private"] = "";
@@ -180,31 +114,28 @@ void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
// The descriptor for this type.
printer->Print(vars,
- "$private$static com.google.protobuf.Descriptors.Descriptor\n"
+ "$private$static final com.google.protobuf.Descriptors.Descriptor\n"
" internal_$identifier$_descriptor;\n");
// And the FieldAccessorTable.
- printer->Print(vars,
- "$private$static\n"
- " com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
- " internal_$identifier$_fieldAccessorTable;\n");
+ GenerateFieldAccessorTable(printer);
}
// Generate static members for all nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// TODO(kenton): Reuse MessageGenerator objects?
- MessageGenerator(descriptor_->nested_type(i))
+ ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
.GenerateStaticVariables(printer);
}
}
-void MessageGenerator::GenerateStaticVariableInitializers(
+void ImmutableMessageGenerator::GenerateStaticVariableInitializers(
io::Printer* printer) {
if (HasDescriptorMethods(descriptor_)) {
map<string, string> vars;
vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
vars["index"] = SimpleItoa(descriptor_->index());
- vars["classname"] = ClassName(descriptor_);
+ vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
if (descriptor_->containing_type() != NULL) {
vars["parent"] = UniqueFileScopeIdentifier(
descriptor_->containing_type());
@@ -222,82 +153,191 @@ void MessageGenerator::GenerateStaticVariableInitializers(
}
// And the FieldAccessorTable.
- printer->Print(vars,
- "internal_$identifier$_fieldAccessorTable = new\n"
- " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n"
- " internal_$identifier$_descriptor,\n"
- " new java.lang.String[] { ");
- for (int i = 0; i < descriptor_->field_count(); i++) {
- printer->Print(
- "\"$field_name$\", ",
- "field_name",
- UnderscoresToCapitalizedCamelCase(descriptor_->field(i)));
- }
- printer->Print("},\n"
- " $classname$.class,\n"
- " $classname$.Builder.class);\n",
- "classname", ClassName(descriptor_));
+ GenerateFieldAccessorTableInitializer(printer);
}
// Generate static member initializers for all nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// TODO(kenton): Reuse MessageGenerator objects?
- MessageGenerator(descriptor_->nested_type(i))
+ ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
.GenerateStaticVariableInitializers(printer);
}
+}
- for (int i = 0; i < descriptor_->extension_count(); i++) {
- // TODO(kenton): Reuse ExtensionGenerator objects?
- ExtensionGenerator(descriptor_->extension(i))
- .GenerateInitializationCode(printer);
+void ImmutableMessageGenerator::
+GenerateFieldAccessorTable(io::Printer* printer) {
+ map<string, string> vars;
+ vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
+ if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
+ // We can only make these package-private since the classes that use them
+ // are in separate files.
+ vars["private"] = "";
+ } else {
+ vars["private"] = "private ";
}
+ printer->Print(vars,
+ "$private$static\n"
+ " com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+ " internal_$identifier$_fieldAccessorTable;\n");
}
-void MessageGenerator::Generate(io::Printer* printer) {
- bool is_own_file =
- descriptor_->containing_type() == NULL &&
- descriptor_->file()->options().java_multiple_files();
+void ImmutableMessageGenerator::
+GenerateFieldAccessorTableInitializer(io::Printer* printer) {
+ printer->Print(
+ "internal_$identifier$_fieldAccessorTable = new\n"
+ " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n"
+ " internal_$identifier$_descriptor,\n"
+ " new java.lang.String[] { ",
+ "identifier",
+ UniqueFileScopeIdentifier(descriptor_));
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ printer->Print(
+ "\"$field_name$\", ",
+ "field_name", info->capitalized_name);
+ }
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
+ const OneofGeneratorInfo* info = context_->GetOneofGeneratorInfo(oneof);
+ printer->Print(
+ "\"$oneof_name$\", ",
+ "oneof_name", info->capitalized_name);
+ }
+ printer->Print("});\n");
+}
+// ===================================================================
+
+void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
- "public $static$ final class $classname$ extends\n"
- " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n"
- " $classname$> {\n",
- "static", is_own_file ? "" : "static",
+ "public interface $classname$OrBuilder extends\n"
+ " $extra_interfaces$\n"
+ " com.google.protobuf.GeneratedMessage.\n"
+ " ExtendableMessageOrBuilder<$classname$> {\n",
+ "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
"classname", descriptor_->name());
} else {
printer->Print(
- "public $static$ final class $classname$ extends\n"
- " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
- " $classname$> {\n",
- "static", is_own_file ? "" : "static",
+ "public interface $classname$OrBuilder extends \n"
+ " $extra_interfaces$\n"
+ " com.google.protobuf.GeneratedMessageLite.\n"
+ " ExtendableMessageOrBuilder<$classname$> {\n",
+ "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
"classname", descriptor_->name());
}
} else {
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
- "public $static$ final class $classname$ extends\n"
- " com.google.protobuf.GeneratedMessage {\n",
- "static", is_own_file ? "" : "static",
+ "public interface $classname$OrBuilder extends\n"
+ " $extra_interfaces$\n"
+ " com.google.protobuf.MessageOrBuilder {\n",
+ "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
"classname", descriptor_->name());
} else {
printer->Print(
- "public $static$ final class $classname$ extends\n"
- " com.google.protobuf.GeneratedMessageLite {\n",
- "static", is_own_file ? "" : "static",
+ "public interface $classname$OrBuilder extends\n"
+ " $extra_interfaces$\n"
+ " com.google.protobuf.MessageLiteOrBuilder {\n",
+ "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
"classname", descriptor_->name());
}
}
+
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print("\n");
+ field_generators_.get(descriptor_->field(i))
+ .GenerateInterfaceMembers(printer);
+ }
+ printer->Outdent();
+
+ printer->Print("}\n");
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::Generate(io::Printer* printer) {
+ bool is_own_file =
+ descriptor_->containing_type() == NULL &&
+ MultipleJavaFiles(descriptor_->file(), /* immutable = */ true);
+
+ WriteMessageDocComment(printer, descriptor_);
+
+ // The builder_type stores the super type name of the nested Builder class.
+ string builder_type;
+ if (descriptor_->extension_range_count() > 0) {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public$static$final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n"
+ " $classname$> implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n",
+ "static", is_own_file ? " " : " static ",
+ "classname", descriptor_->name(),
+ "extra_interfaces", ExtraMessageInterfaces(descriptor_));
+ builder_type = strings::Substitute(
+ "com.google.protobuf.GeneratedMessage.ExtendableBuilder<$0, ?>",
+ name_resolver_->GetImmutableClassName(descriptor_));
+ } else {
+ printer->Print(
+ "public$static$final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
+ " $classname$> implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n",
+ "static", is_own_file ? " " : " static ",
+ "classname", descriptor_->name(),
+ "extra_interfaces", ExtraMessageInterfaces(descriptor_));
+ builder_type = strings::Substitute(
+ "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>",
+ name_resolver_->GetImmutableClassName(descriptor_));
+ }
+ } else {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public$static$final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessage implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n",
+ "static", is_own_file ? " " : " static ",
+ "classname", descriptor_->name(),
+ "extra_interfaces", ExtraMessageInterfaces(descriptor_));
+ builder_type = "com.google.protobuf.GeneratedMessage.Builder<?>";
+ } else {
+ printer->Print(
+ "public$static$final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessageLite implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n",
+ "static", is_own_file ? " " : " static ",
+ "classname", descriptor_->name(),
+ "extra_interfaces", ExtraMessageInterfaces(descriptor_));
+ builder_type = "com.google.protobuf.GeneratedMessageLite.Builder";
+ }
+ }
printer->Indent();
+ // Using builder_type, instead of Builder, prevents the Builder class from
+ // being loaded into PermGen space when the default instance is created.
+ // This optimizes the PermGen space usage for clients that do not modify
+ // messages.
printer->Print(
"// Use $classname$.newBuilder() to construct.\n"
- "private $classname$() {\n"
- " initFields();\n"
- "}\n"
+ "private $classname$($buildertype$ builder) {\n"
+ " super(builder);\n"
+ "$set_unknown_fields$\n"
+ "}\n",
+ "classname", descriptor_->name(),
+ "buildertype", builder_type,
+ "set_unknown_fields",
+ " this.unknownFields = builder.getUnknownFields();");
+ printer->Print(
// Used when constructing the default instance, which cannot be initialized
// immediately because it may cyclically refer to other default instances.
- "private $classname$(boolean noInit) {}\n"
+ "private $classname$(boolean noInit) {$set_default_unknown_fields$}\n"
"\n"
"private static final $classname$ defaultInstance;\n"
"public static $classname$ getDefaultInstance() {\n"
@@ -308,40 +348,131 @@ void MessageGenerator::Generate(io::Printer* printer) {
" return defaultInstance;\n"
"}\n"
"\n",
- "classname", descriptor_->name());
+ "classname", descriptor_->name(),
+ "set_default_unknown_fields", UseUnknownFieldSet(descriptor_)
+ ? " this.unknownFields ="
+ " com.google.protobuf.UnknownFieldSet.getDefaultInstance(); "
+ : " this.unknownFields = com.google.protobuf.ByteString.EMPTY;");
- if (HasDescriptorMethods(descriptor_)) {
+ if (UseUnknownFieldSet(descriptor_)) {
printer->Print(
- "public static final com.google.protobuf.Descriptors.Descriptor\n"
- " getDescriptor() {\n"
- " return $fileclass$.internal_$identifier$_descriptor;\n"
- "}\n"
- "\n"
- "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
- " internalGetFieldAccessorTable() {\n"
- " return $fileclass$.internal_$identifier$_fieldAccessorTable;\n"
- "}\n"
- "\n",
- "fileclass", ClassName(descriptor_->file()),
- "identifier", UniqueFileScopeIdentifier(descriptor_));
+ "private final com.google.protobuf.UnknownFieldSet unknownFields;\n"
+ ""
+ "@java.lang.Override\n"
+ "public final com.google.protobuf.UnknownFieldSet\n"
+ " getUnknownFields() {\n"
+ " return this.unknownFields;\n"
+ "}\n");
+ } else {
+ printer->Print(
+ "private final com.google.protobuf.ByteString unknownFields;\n");
}
- // Nested types and extensions
+ if (HasGeneratedMethods(descriptor_)) {
+ GenerateParsingConstructor(printer);
+ }
+
+ GenerateDescriptorMethods(printer);
+ GenerateParser(printer);
+
+ // Nested types
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
- EnumGenerator(descriptor_->enum_type(i)).Generate(printer);
+ EnumGenerator(descriptor_->enum_type(i), true, context_)
+ .Generate(printer);
}
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
- MessageGenerator(descriptor_->nested_type(i)).Generate(printer);
+ ImmutableMessageGenerator messageGenerator(
+ descriptor_->nested_type(i), context_);
+ messageGenerator.GenerateInterface(printer);
+ messageGenerator.Generate(printer);
}
- for (int i = 0; i < descriptor_->extension_count(); i++) {
- ExtensionGenerator(descriptor_->extension(i)).Generate(printer);
+ 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 < totalInts; i++) {
+ printer->Print("private int $bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+ }
+
+ // oneof
+ map<string, string> vars;
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ vars["oneof_name"] = context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->name;
+ vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->capitalized_name;
+ vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
+ // oneofCase_ and oneof_
+ printer->Print(vars,
+ "private int $oneof_name$Case_ = 0;\n"
+ "private java.lang.Object $oneof_name$_;\n");
+ // OneofCase enum
+ printer->Print(vars,
+ "public enum $oneof_capitalized_name$Case\n"
+ " implements com.google.protobuf.Internal.EnumLite {\n");
+ 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(
+ "$field_name$($field_number$),\n",
+ "field_name",
+ ToUpper(field->name()),
+ "field_number",
+ SimpleItoa(field->number()));
+ }
+ printer->Print(
+ "$cap_oneof_name$_NOT_SET(0);\n",
+ "cap_oneof_name",
+ ToUpper(vars["oneof_name"]));
+ printer->Print(vars,
+ "private int value = 0;\n"
+ "private $oneof_capitalized_name$Case(int value) {\n"
+ " this.value = value;\n"
+ "}\n");
+ printer->Print(vars,
+ "public static $oneof_capitalized_name$Case valueOf(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);
+ printer->Print(
+ " case $field_number$: return $field_name$;\n",
+ "field_number",
+ SimpleItoa(field->number()),
+ "field_name",
+ ToUpper(field->name()));
+ }
+ 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"
+ " }\n"
+ "}\n"
+ "public int getNumber() {\n"
+ " return this.value;\n"
+ "}\n",
+ "cap_oneof_name", ToUpper(vars["oneof_name"]));
+ printer->Outdent();
+ printer->Print("};\n\n");
+ // oneofCase()
+ printer->Print(vars,
+ "public $oneof_capitalized_name$Case\n"
+ "get$oneof_capitalized_name$Case() {\n"
+ " return $oneof_capitalized_name$Case.valueOf(\n"
+ " $oneof_name$Case_);\n"
+ "}\n"
+ "\n");
}
// Fields
for (int i = 0; i < descriptor_->field_count(); i++) {
- PrintFieldComment(printer, descriptor_->field(i));
printer->Print("public static final int $constant_name$ = $number$;\n",
"constant_name", FieldConstantName(descriptor_->field(i)),
"number", SimpleItoa(descriptor_->field(i)->number()));
@@ -354,48 +485,60 @@ void MessageGenerator::Generate(io::Printer* printer) {
printer->Print("private void initFields() {\n");
printer->Indent();
for (int i = 0; i < descriptor_->field_count(); i++) {
- field_generators_.get(descriptor_->field(i))
- .GenerateInitializationCode(printer);
+ if (!descriptor_->field(i)->containing_oneof()) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateInitializationCode(printer);
+ }
}
+
printer->Outdent();
printer->Print("}\n");
if (HasGeneratedMethods(descriptor_)) {
- GenerateIsInitialized(printer);
+ GenerateIsInitialized(printer, MEMOIZE);
GenerateMessageSerializationMethods(printer);
}
+ if (HasEqualsAndHashCode(descriptor_)) {
+ GenerateEqualsAndHashCode(printer);
+ }
+
+
GenerateParseFromMethods(printer);
GenerateBuilder(printer);
- // Force initialization of outer class. Otherwise, nested extensions may
- // not be initialized. Also carefully initialize the default instance in
- // such a way that it doesn't conflict with other initialization.
+ // Carefully initialize the default instance in such a way that it doesn't
+ // conflict with other initialization.
printer->Print(
"\n"
"static {\n"
" defaultInstance = new $classname$(true);\n"
- " $file$.internalForceInit();\n"
" defaultInstance.initFields();\n"
- "}\n",
- "file", ClassName(descriptor_->file()),
- "classname", descriptor_->name());
-
- printer->Print(
+ "}\n"
"\n"
"// @@protoc_insertion_point(class_scope:$full_name$)\n",
+ "classname", descriptor_->name(),
"full_name", descriptor_->full_name());
+ // Extensions must be declared after the defaultInstance is initialized
+ // because the defaultInstance 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_)
+ .Generate(printer);
+ }
+
printer->Outdent();
printer->Print("}\n\n");
}
+
// ===================================================================
-void MessageGenerator::
+void ImmutableMessageGenerator::
GenerateMessageSerializationMethods(io::Printer* printer) {
scoped_array<const FieldDescriptor*> sorted_fields(
- SortFieldsByNumber(descriptor_));
+ SortFieldsByNumber(descriptor_));
vector<const Descriptor::ExtensionRange*> sorted_extensions;
for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
@@ -420,15 +563,18 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
if (descriptor_->options().message_set_wire_format()) {
printer->Print(
- "com.google.protobuf.GeneratedMessage$lite$.ExtendableMessage\n"
- " .ExtensionWriter extensionWriter =\n"
+ "com.google.protobuf.GeneratedMessage$lite$\n"
+ " .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n"
" newMessageSetExtensionWriter();\n",
- "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite");
+ "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
} else {
printer->Print(
- "com.google.protobuf.GeneratedMessage$lite$.ExtendableMessage\n"
- " .ExtensionWriter extensionWriter = newExtensionWriter();\n",
- "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite");
+ "com.google.protobuf.GeneratedMessage$lite$\n"
+ " .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n"
+ " newExtensionWriter();\n",
+ "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
}
}
@@ -447,7 +593,7 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
}
}
- if (HasUnknownFields(descriptor_)) {
+ if (UseUnknownFieldSet(descriptor_)) {
if (descriptor_->options().message_set_wire_format()) {
printer->Print(
"getUnknownFields().writeAsMessageSetTo(output);\n");
@@ -455,6 +601,9 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
printer->Print(
"getUnknownFields().writeTo(output);\n");
}
+ } else {
+ printer->Print(
+ "output.writeRawBytes(unknownFields);\n");
}
printer->Outdent();
@@ -483,7 +632,7 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
}
}
- if (HasUnknownFields(descriptor_)) {
+ if (UseUnknownFieldSet(descriptor_)) {
if (descriptor_->options().message_set_wire_format()) {
printer->Print(
"size += getUnknownFields().getSerializedSizeAsMessageSet();\n");
@@ -491,6 +640,9 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
printer->Print(
"size += getUnknownFields().getSerializedSize();\n");
}
+ } else {
+ printer->Print(
+ "size += unknownFields.size();\n");
}
printer->Outdent();
@@ -499,9 +651,18 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
" return size;\n"
"}\n"
"\n");
+
+ printer->Print(
+ "private static final long serialVersionUID = 0L;\n"
+ "@java.lang.Override\n"
+ "protected java.lang.Object writeReplace()\n"
+ " throws java.io.ObjectStreamException {\n"
+ " return super.writeReplace();\n"
+ "}\n"
+ "\n");
}
-void MessageGenerator::
+void ImmutableMessageGenerator::
GenerateParseFromMethods(io::Printer* printer) {
// Note: These are separate from GenerateMessageSerializationMethods()
// because they need to be generated even for messages that are optimized
@@ -510,79 +671,65 @@ GenerateParseFromMethods(io::Printer* printer) {
"public static $classname$ parseFrom(\n"
" com.google.protobuf.ByteString data)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return newBuilder().mergeFrom(data).buildParsed();\n"
+ " return PARSER.parseFrom(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 newBuilder().mergeFrom(data, extensionRegistry)\n"
- " .buildParsed();\n"
+ " return PARSER.parseFrom(data, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(byte[] data)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return newBuilder().mergeFrom(data).buildParsed();\n"
+ " return PARSER.parseFrom(data);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" byte[] data,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return newBuilder().mergeFrom(data, extensionRegistry)\n"
- " .buildParsed();\n"
+ " return PARSER.parseFrom(data, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
- " return newBuilder().mergeFrom(input).buildParsed();\n"
+ " return PARSER.parseFrom(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 newBuilder().mergeFrom(input, extensionRegistry)\n"
- " .buildParsed();\n"
+ " return PARSER.parseFrom(input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
- " Builder builder = newBuilder();\n"
- " if (builder.mergeDelimitedFrom(input)) {\n"
- " return builder.buildParsed();\n"
- " } else {\n"
- " return null;\n"
- " }\n"
+ " return PARSER.parseDelimitedFrom(input);\n"
"}\n"
"public static $classname$ parseDelimitedFrom(\n"
" java.io.InputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
- " Builder builder = newBuilder();\n"
- " if (builder.mergeDelimitedFrom(input, extensionRegistry)) {\n"
- " return builder.buildParsed();\n"
- " } else {\n"
- " return null;\n"
- " }\n"
+ " return PARSER.parseDelimitedFrom(input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.CodedInputStream input)\n"
" throws java.io.IOException {\n"
- " return newBuilder().mergeFrom(input).buildParsed();\n"
+ " return PARSER.parseFrom(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 newBuilder().mergeFrom(input, extensionRegistry)\n"
- " .buildParsed();\n"
+ " return PARSER.parseFrom(input, extensionRegistry);\n"
"}\n"
"\n",
- "classname", ClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
}
-void MessageGenerator::GenerateSerializeOneField(
+void ImmutableMessageGenerator::GenerateSerializeOneField(
io::Printer* printer, const FieldDescriptor* field) {
field_generators_.get(field).GenerateSerializationCode(printer);
}
-void MessageGenerator::GenerateSerializeOneExtensionRange(
+void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange(
io::Printer* printer, const Descriptor::ExtensionRange* range) {
printer->Print(
"extensionWriter.writeUntil($end$, output);\n",
@@ -591,7 +738,7 @@ void MessageGenerator::GenerateSerializeOneExtensionRange(
// ===================================================================
-void MessageGenerator::GenerateBuilder(io::Printer* printer) {
+void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) {
printer->Print(
"public static Builder newBuilder() { return Builder.create(); }\n"
"public Builder newBuilderForType() { return newBuilder(); }\n"
@@ -600,47 +747,119 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) {
"}\n"
"public Builder toBuilder() { return newBuilder(this); }\n"
"\n",
- "classname", ClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ if (HasNestedBuilders(descriptor_)) {
+ printer->Print(
+ "@java.lang.Override\n"
+ "protected Builder newBuilderForType(\n"
+ " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
+ " Builder builder = new Builder(parent);\n"
+ " return builder;\n"
+ "}\n");
+ }
+
+ WriteMessageDocComment(printer, descriptor_);
if (descriptor_->extension_range_count() > 0) {
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
"public static final class Builder extends\n"
" com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n"
- " $classname$, Builder> {\n",
- "classname", ClassName(descriptor_));
+ " $classname$, Builder> implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
} else {
printer->Print(
"public static final class Builder extends\n"
" com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<\n"
- " $classname$, Builder> {\n",
- "classname", ClassName(descriptor_));
+ " $classname$, Builder> implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
}
} else {
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
"public static final class Builder extends\n"
- " com.google.protobuf.GeneratedMessage.Builder<Builder> {\n",
- "classname", ClassName(descriptor_));
+ " com.google.protobuf.GeneratedMessage.Builder<Builder> implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
} else {
printer->Print(
"public static final class Builder extends\n"
" com.google.protobuf.GeneratedMessageLite.Builder<\n"
- " $classname$, Builder> {\n",
- "classname", ClassName(descriptor_));
+ " $classname$, Builder>\n"
+ " implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
}
}
printer->Indent();
+ GenerateDescriptorMethods(printer);
GenerateCommonBuilderMethods(printer);
if (HasGeneratedMethods(descriptor_)) {
+ GenerateIsInitialized(printer, DONT_MEMOIZE);
GenerateBuilderParsingMethods(printer);
}
+ // oneof
+ map<string, string> vars;
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ vars["oneof_name"] = context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->name;
+ vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->capitalized_name;
+ vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
+ // oneofCase_ and oneof_
+ printer->Print(vars,
+ "private int $oneof_name$Case_ = 0;\n"
+ "private java.lang.Object $oneof_name$_;\n");
+ // oneofCase() and clearOneof()
+ printer->Print(vars,
+ "public $oneof_capitalized_name$Case\n"
+ " get$oneof_capitalized_name$Case() {\n"
+ " return $oneof_capitalized_name$Case.valueOf(\n"
+ " $oneof_name$Case_);\n"
+ "}\n"
+ "\n"
+ "public Builder clear$oneof_capitalized_name$() {\n"
+ " $oneof_name$Case_ = 0;\n"
+ " $oneof_name$_ = null;\n");
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(" onChanged();\n");
+ }
+ printer->Print(
+ " return this;\n"
+ "}\n"
+ "\n");
+ }
+
+ 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))
+ .GetNumBitsForBuilder();
+ }
+ int totalInts = (totalBits + 31) / 32;
+ for (int i = 0; i < totalInts; i++) {
+ printer->Print("private int $bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+ }
+
for (int i = 0; i < descriptor_->field_count(); i++) {
printer->Print("\n");
- PrintFieldComment(printer, descriptor_->field(i));
field_generators_.get(descriptor_->field(i))
.GenerateBuilderMembers(printer);
}
@@ -654,98 +873,209 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) {
printer->Print("}\n");
}
+void ImmutableMessageGenerator::
+GenerateDescriptorMethods(io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_)) {
+ if (!descriptor_->options().no_standard_descriptor_accessor()) {
+ printer->Print(
+ "public static final com.google.protobuf.Descriptors.Descriptor\n"
+ " getDescriptor() {\n"
+ " return $fileclass$.internal_$identifier$_descriptor;\n"
+ "}\n"
+ "\n",
+ "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
+ "identifier", UniqueFileScopeIdentifier(descriptor_));
+ }
+ printer->Print(
+ "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+ " internalGetFieldAccessorTable() {\n"
+ " return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
+ " .ensureFieldAccessorsInitialized(\n"
+ " $classname$.class, $classname$.Builder.class);\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
+ "identifier", UniqueFileScopeIdentifier(descriptor_));
+ }
+}
+
// ===================================================================
-void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
+void ImmutableMessageGenerator::
+GenerateCommonBuilderMethods(io::Printer* printer) {
printer->Print(
- "private $classname$ result;\n"
- "\n"
"// Construct using $classname$.newBuilder()\n"
- "private Builder() {}\n"
- "\n"
- "private static Builder create() {\n"
- " Builder builder = new Builder();\n"
- " builder.result = new $classname$();\n"
- " return builder;\n"
+ "private Builder() {\n"
+ " maybeForceBuilderInitialization();\n"
"}\n"
- "\n"
- "protected $classname$ internalGetResult() {\n"
- " return result;\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "private Builder(\n"
+ " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
+ " super(parent);\n"
+ " maybeForceBuilderInitialization();\n"
+ "}\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ }
+
+
+ if (HasNestedBuilders(descriptor_)) {
+ printer->Print(
+ "private void maybeForceBuilderInitialization() {\n"
+ " if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {\n");
+
+ printer->Indent();
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!descriptor_->field(i)->containing_oneof()) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateFieldBuilderInitializationCode(printer);
+ }
+ }
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
+ " }\n"
+ "}\n");
+ } else {
+ printer->Print(
+ "private void maybeForceBuilderInitialization() {\n"
+ "}\n");
+ }
+
+ printer->Print(
+ "private static Builder create() {\n"
+ " return new Builder();\n"
"}\n"
"\n"
"public Builder clear() {\n"
- " if (result == null) {\n"
- " throw new IllegalStateException(\n"
- " \"Cannot call clear() after build().\");\n"
- " }\n"
- " result = new $classname$();\n"
+ " super.clear();\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!descriptor_->field(i)->containing_oneof()) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateBuilderClearCode(printer);
+ }
+ }
+
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "$oneof_name$Case_ = 0;\n"
+ "$oneof_name$_ = null;\n",
+ "oneof_name", context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->name);
+ }
+
+ printer->Outdent();
+
+ printer->Print(
" return this;\n"
"}\n"
"\n"
"public Builder clone() {\n"
- " return create().mergeFrom(result);\n"
+ " return create().mergeFrom(buildPartial());\n"
"}\n"
"\n",
- "classname", ClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
"public com.google.protobuf.Descriptors.Descriptor\n"
" getDescriptorForType() {\n"
- " return $classname$.getDescriptor();\n"
+ " return $fileclass$.internal_$identifier$_descriptor;\n"
"}\n"
"\n",
- "classname", ClassName(descriptor_));
+ "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
+ "identifier", UniqueFileScopeIdentifier(descriptor_));
}
printer->Print(
"public $classname$ getDefaultInstanceForType() {\n"
" return $classname$.getDefaultInstance();\n"
"}\n"
- "\n"
- "public boolean isInitialized() {\n"
- " return result.isInitialized();\n"
- "}\n",
- "classname", ClassName(descriptor_));
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
// -----------------------------------------------------------------
printer->Print(
"public $classname$ build() {\n"
- // If result == null, we'll throw an appropriate exception later.
- " if (result != null && !isInitialized()) {\n"
+ " $classname$ result = buildPartial();\n"
+ " if (!result.isInitialized()) {\n"
" throw newUninitializedMessageException(result);\n"
" }\n"
- " return buildPartial();\n"
- "}\n"
- "\n"
- "private $classname$ buildParsed()\n"
- " throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " if (!isInitialized()) {\n"
- " throw newUninitializedMessageException(\n"
- " result).asInvalidProtocolBufferException();\n"
- " }\n"
- " return buildPartial();\n"
+ " return result;\n"
"}\n"
"\n"
"public $classname$ buildPartial() {\n"
- " if (result == null) {\n"
- " throw new IllegalStateException(\n"
- " \"build() has already been called on this Builder.\");\n"
- " }\n",
- "classname", ClassName(descriptor_));
+ " $classname$ result = new $classname$(this);\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
printer->Indent();
+ int totalBuilderBits = 0;
+ int totalMessageBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const ImmutableFieldGenerator& field =
+ field_generators_.get(descriptor_->field(i));
+ totalBuilderBits += field.GetNumBitsForBuilder();
+ totalMessageBits += field.GetNumBitsForMessage();
+ }
+ int totalBuilderInts = (totalBuilderBits + 31) / 32;
+ int totalMessageInts = (totalMessageBits + 31) / 32;
+
+ if (GenerateHasBits(descriptor_)) {
+ // Local vars for from and to bit fields to avoid accessing the builder and
+ // message over and over for these fields. Seems to provide a slight
+ // perforamance improvement in micro benchmark and this is also what proto1
+ // code does.
+ for (int i = 0; i < totalBuilderInts; i++) {
+ printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+ for (int i = 0; i < totalMessageInts; i++) {
+ printer->Print("int to_$bit_field_name$ = 0;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+ }
+
+ // Output generation code for each field.
for (int i = 0; i < descriptor_->field_count(); i++) {
field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
}
+ if (GenerateHasBits(descriptor_)) {
+ // Copy the bit field results to the generated message
+ for (int i = 0; i < totalMessageInts; i++) {
+ printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+ }
+
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n",
+ "oneof_name", context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->name);
+ }
+
printer->Outdent();
+
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ " onBuilt();\n");
+ }
+
printer->Print(
- " $classname$ returnMe = result;\n"
- " result = null;\n"
- " return returnMe;\n"
+ " return result;\n"
"}\n"
"\n",
- "classname", ClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
// -----------------------------------------------------------------
@@ -763,7 +1093,7 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
" }\n"
"}\n"
"\n",
- "classname", ClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
}
printer->Print(
@@ -771,11 +1101,48 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
// Optimization: If other is the default instance, we know none of its
// fields are set so we can skip the merge.
" if (other == $classname$.getDefaultInstance()) return this;\n",
- "classname", ClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
printer->Indent();
for (int i = 0; i < descriptor_->field_count(); i++) {
- field_generators_.get(descriptor_->field(i)).GenerateMergingCode(printer);
+ if (!descriptor_->field(i)->containing_oneof()) {
+ field_generators_.get(
+ descriptor_->field(i)).GenerateMergingCode(printer);
+ }
+ }
+
+ // Merge oneof fields.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
+ printer->Print(
+ "switch (other.get$oneof_capitalized_name$Case()) {\n",
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->capitalized_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(
+ "case $field_name$: {\n",
+ "field_name",
+ ToUpper(field->name()));
+ printer->Indent();
+ field_generators_.get(field).GenerateMergingCode(printer);
+ printer->Print(
+ "break;\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+ printer->Print(
+ "case $cap_oneof_name$_NOT_SET: {\n"
+ " break;\n"
+ "}\n",
+ "cap_oneof_name",
+ ToUpper(context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->name));
+ printer->Outdent();
+ printer->Print(
+ "}\n");
}
printer->Outdent();
@@ -786,9 +1153,13 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
" this.mergeExtensionFields(other);\n");
}
- if (HasUnknownFields(descriptor_)) {
+ if (UseUnknownFieldSet(descriptor_)) {
printer->Print(
" this.mergeUnknownFields(other.getUnknownFields());\n");
+ } else {
+ printer->Print(
+ " setUnknownFields(\n"
+ " getUnknownFields().concat(other.unknownFields));\n");
}
printer->Print(
@@ -800,57 +1171,358 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
// ===================================================================
-void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
- scoped_array<const FieldDescriptor*> sorted_fields(
- SortFieldsByNumber(descriptor_));
-
+void ImmutableMessageGenerator::
+GenerateBuilderParsingMethods(io::Printer* printer) {
printer->Print(
"public Builder mergeFrom(\n"
" com.google.protobuf.CodedInputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
- " throws java.io.IOException {\n");
+ " throws java.io.IOException {\n"
+ " $classname$ parsedMessage = null;\n"
+ " try {\n"
+ " parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);\n"
+ " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
+ " parsedMessage = ($classname$) e.getUnfinishedMessage();\n"
+ " throw e;\n"
+ " } finally {\n"
+ " if (parsedMessage != null) {\n"
+ " mergeFrom(parsedMessage);\n"
+ " }\n"
+ " }\n"
+ " return this;\n"
+ "}\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::GenerateIsInitialized(
+ io::Printer* printer, UseMemoization useMemoization) {
+ bool memoization = useMemoization == MEMOIZE;
+ if (memoization) {
+ // Memoizes whether the protocol buffer is fully initialized (has all
+ // required fields). -1 means not yet computed. 0 means false and 1 means
+ // true.
+ printer->Print(
+ "private byte memoizedIsInitialized = -1;\n");
+ }
+ printer->Print(
+ "public final boolean isInitialized() {\n");
printer->Indent();
- if (HasUnknownFields(descriptor_)) {
+ if (memoization) {
+ // Don't directly compare to -1 to avoid an Android x86 JIT bug.
printer->Print(
- "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
- " com.google.protobuf.UnknownFieldSet.newBuilder(\n"
- " this.getUnknownFields());\n");
+ "byte isInitialized = memoizedIsInitialized;\n"
+ "if (isInitialized == 1) return true;\n"
+ "if (isInitialized == 0) return false;\n"
+ "\n");
+ }
+
+ // Check that all required fields in this message are set.
+ // TODO(kenton): We can optimize this when we switch to putting all the
+ // "has" fields into a single bitfield.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+
+ if (field->is_required()) {
+ printer->Print(
+ "if (!has$name$()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ "}\n",
+ "name", info->capitalized_name,
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+ }
+ }
+
+ // Now check that all embedded messages are initialized.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ if (GetJavaType(field) == JAVATYPE_MESSAGE &&
+ HasRequiredFields(field->message_type())) {
+ switch (field->label()) {
+ case FieldDescriptor::LABEL_REQUIRED:
+ printer->Print(
+ "if (!get$name$().isInitialized()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ "}\n",
+ "type", name_resolver_->GetImmutableClassName(
+ field->message_type()),
+ "name", info->capitalized_name,
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+ break;
+ case FieldDescriptor::LABEL_OPTIONAL:
+ printer->Print(
+ "if (has$name$()) {\n"
+ " if (!get$name$().isInitialized()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ " }\n"
+ "}\n",
+ "type", name_resolver_->GetImmutableClassName(
+ field->message_type()),
+ "name", info->capitalized_name,
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+ break;
+ case FieldDescriptor::LABEL_REPEATED:
+ printer->Print(
+ "for (int i = 0; i < get$name$Count(); i++) {\n"
+ " if (!get$name$(i).isInitialized()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ " }\n"
+ "}\n",
+ "type", name_resolver_->GetImmutableClassName(
+ field->message_type()),
+ "name", info->capitalized_name,
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+ break;
+ }
+ }
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "if (!extensionsAreInitialized()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ "}\n",
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+ }
+
+ printer->Outdent();
+
+ if (memoization) {
+ printer->Print(
+ " memoizedIsInitialized = 1;\n");
}
printer->Print(
- "while (true) {\n");
+ " return true;\n"
+ "}\n"
+ "\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 ImmutableMessageGenerator::
+GenerateEqualsAndHashCode(io::Printer* printer) {
+ printer->Print(
+ "@java.lang.Override\n"
+ "public boolean equals(final java.lang.Object obj) {\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 (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "result = result &&\n"
+ " getUnknownFields().equals(other.getUnknownFields());\n");
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "result = result &&\n"
+ " getExtensionFields().equals(other.getExtensionFields());\n");
+ }
+ }
+ printer->Print(
+ "return result;\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
printer->Print(
- "int tag = input.readTag();\n"
- "switch (tag) {\n");
+ "@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");
- if (HasUnknownFields(descriptor_)) {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print("hash = (19 * hash) + getDescriptorForType().hashCode();\n");
+ } else {
+ // 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_));
+ }
+
+ 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(
+ "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");
+ }
+ }
+ if (HasDescriptorMethods(descriptor_)) {
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "hash = hashFields(hash, getExtensionFields());\n");
+ }
+ }
+
+ if (UseUnknownFieldSet(descriptor_)) {
printer->Print(
- "case 0:\n" // zero signals EOF / limit reached
- " this.setUnknownFields(unknownFields.build());\n"
- " return this;\n"
- "default: {\n"
- " if (!parseUnknownField(input, unknownFields,\n"
- " extensionRegistry, tag)) {\n"
- " this.setUnknownFields(unknownFields.build());\n"
- " return this;\n" // it's an endgroup tag
- " }\n"
- " break;\n"
- "}\n");
+ "hash = (29 * hash) + getUnknownFields().hashCode();\n");
} else {
printer->Print(
- "case 0:\n" // zero signals EOF / limit reached
- " return this;\n"
- "default: {\n"
- " if (!parseUnknownField(input, extensionRegistry, tag)) {\n"
- " return this;\n" // it's an endgroup tag
- " }\n"
- " break;\n"
- "}\n");
+ "hash = (29 * hash) + unknownFields.hashCode();\n");
+ }
+ printer->Print(
+ "memoizedHashCode = hash;\n"
+ "return hash;\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::
+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++) {
+ ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
+ .GenerateExtensionRegistrationCode(printer);
+ }
+}
+
+// ===================================================================
+void ImmutableMessageGenerator::
+GenerateParsingConstructor(io::Printer* printer) {
+ 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"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+
+ // Initialize all fields to default.
+ printer->Print(
+ "initFields();\n");
+
+ // Use builder bits to track mutable repeated fields.
+ int totalBuilderBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const ImmutableFieldGenerator& 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));
+ }
+
+ if (UseUnknownFieldSet(descriptor_)) {
+ printer->Print(
+ "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
+ " com.google.protobuf.UnknownFieldSet.newBuilder();\n");
+ } else {
+ printer->Print(
+ "com.google.protobuf.ByteString.Output unknownFieldsOutput =\n"
+ " com.google.protobuf.ByteString.newOutput();\n"
+ "com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput =\n"
+ " com.google.protobuf.CodedOutputStream.newInstance(\n"
+ " unknownFieldsOutput);\n");
+ }
+
+ printer->Print(
+ "try {\n");
+ printer->Indent();
+
+ printer->Print(
+ "boolean done = false;\n"
+ "while (!done) {\n");
+ printer->Indent();
+
+ printer->Print(
+ "int tag = input.readTag();\n"
+ "switch (tag) {\n");
+ printer->Indent();
+
+ printer->Print(
+ "case 0:\n" // zero signals EOF / limit reached
+ " done = true;\n"
+ " break;\n"
+ "default: {\n"
+ " if (!parseUnknownField(input,$unknown_fields$\n"
+ " extensionRegistry, tag)) {\n"
+ " done = true;\n" // it's an endgroup tag
+ " }\n"
+ " break;\n"
+ "}\n",
+ "unknown_fields", UseUnknownFieldSet(descriptor_)
+ ? " unknownFields," : " unknownFieldsCodedOutput,");
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = sorted_fields[i];
@@ -890,92 +1562,104 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
printer->Outdent();
printer->Outdent();
- printer->Outdent();
printer->Print(
- " }\n" // switch (tag)
- " }\n" // while (true)
- "}\n"
- "\n");
-}
-
-// ===================================================================
+ " }\n" // switch (tag)
+ "}\n"); // while (!done)
-void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
+ printer->Outdent();
printer->Print(
- "public final boolean isInitialized() {\n");
+ "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
+ " throw e.setUnfinishedMessage(this);\n"
+ "} catch (java.io.IOException e) {\n"
+ " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
+ " e.getMessage()).setUnfinishedMessage(this);\n"
+ "} finally {\n");
printer->Indent();
- // Check that all required fields in this message are set.
- // TODO(kenton): We can optimize this when we switch to putting all the
- // "has" fields into a single bitfield.
+ // Make repeated field list immutable.
for (int i = 0; i < descriptor_->field_count(); i++) {
- const FieldDescriptor* field = descriptor_->field(i);
-
- if (field->is_required()) {
- printer->Print(
- "if (!has$name$) return false;\n",
- "name", UnderscoresToCapitalizedCamelCase(field));
- }
- }
-
- // Now check that all embedded messages are initialized.
- for (int i = 0; i < descriptor_->field_count(); i++) {
- const FieldDescriptor* field = descriptor_->field(i);
- if (GetJavaType(field) == JAVATYPE_MESSAGE &&
- HasRequiredFields(field->message_type())) {
- switch (field->label()) {
- case FieldDescriptor::LABEL_REQUIRED:
- printer->Print(
- "if (!get$name$().isInitialized()) return false;\n",
- "type", ClassName(field->message_type()),
- "name", UnderscoresToCapitalizedCamelCase(field));
- break;
- case FieldDescriptor::LABEL_OPTIONAL:
- printer->Print(
- "if (has$name$()) {\n"
- " if (!get$name$().isInitialized()) return false;\n"
- "}\n",
- "type", ClassName(field->message_type()),
- "name", UnderscoresToCapitalizedCamelCase(field));
- break;
- case FieldDescriptor::LABEL_REPEATED:
- printer->Print(
- "for ($type$ element : get$name$List()) {\n"
- " if (!element.isInitialized()) return false;\n"
- "}\n",
- "type", ClassName(field->message_type()),
- "name", UnderscoresToCapitalizedCamelCase(field));
- break;
- }
- }
+ const FieldDescriptor* field = sorted_fields[i];
+ field_generators_.get(field).GenerateParsingDoneCode(printer);
}
- if (descriptor_->extension_range_count() > 0) {
+ // Make unknown fields immutable.
+ if (UseUnknownFieldSet(descriptor_)) {
+ printer->Print(
+ "this.unknownFields = unknownFields.build();\n");
+ } else {
printer->Print(
- "if (!extensionsAreInitialized()) return false;\n");
+ "try {\n"
+ " unknownFieldsCodedOutput.flush();\n"
+ "} catch (java.io.IOException e) {\n"
+ "// Should not happen\n"
+ "} finally {\n"
+ " unknownFields = unknownFieldsOutput.toByteString();\n"
+ "}\n");
}
+ // Make extensions immutable.
+ printer->Print(
+ "makeExtensionsImmutable();\n");
+
+ printer->Outdent();
printer->Outdent();
printer->Print(
- " return true;\n"
- "}\n"
- "\n");
+ " }\n" // finally
+ "}\n");
}
// ===================================================================
-
-void MessageGenerator::GenerateExtensionRegistrationCode(io::Printer* printer) {
- for (int i = 0; i < descriptor_->extension_count(); i++) {
- ExtensionGenerator(descriptor_->extension(i))
- .GenerateRegistrationCode(printer);
+void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
+ printer->Print(
+ "public static com.google.protobuf.Parser<$classname$> PARSER =\n"
+ " new com.google.protobuf.AbstractParser<$classname$>() {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+ printer->Print(
+ "public $classname$ parsePartialFrom(\n"
+ " com.google.protobuf.CodedInputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n",
+ "classname", descriptor_->name());
+ if (HasGeneratedMethods(descriptor_)) {
+ printer->Print(
+ " return new $classname$(input, extensionRegistry);\n",
+ "classname", descriptor_->name());
+ } else {
+ // When parsing constructor isn't generated, use builder to parse messages.
+ // Note, will fallback to use reflection based mergeFieldFrom() in
+ // AbstractMessage.Builder.
+ printer->Indent();
+ printer->Print(
+ "Builder builder = newBuilder();\n"
+ "try {\n"
+ " builder.mergeFrom(input, extensionRegistry);\n"
+ "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
+ " throw e.setUnfinishedMessage(builder.buildPartial());\n"
+ "} catch (java.io.IOException e) {\n"
+ " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
+ " e.getMessage()).setUnfinishedMessage(builder.buildPartial());\n"
+ "}\n"
+ "return builder.buildPartial();\n");
+ printer->Outdent();
}
+ printer->Print(
+ "}\n");
+ printer->Outdent();
+ printer->Print(
+ "};\n"
+ "\n");
- for (int i = 0; i < descriptor_->nested_type_count(); i++) {
- MessageGenerator(descriptor_->nested_type(i))
- .GenerateExtensionRegistrationCode(printer);
- }
+ printer->Print(
+ "@java.lang.Override\n"
+ "public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
+ " return PARSER;\n"
+ "}\n"
+ "\n",
+ "classname", descriptor_->name());
}
+
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h
index 50ffae0..fece1c2 100644
--- a/src/google/protobuf/compiler/java/java_message.h
+++ b/src/google/protobuf/compiler/java/java_message.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -36,11 +36,17 @@
#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
#include <string>
-#include <google/protobuf/stubs/common.h>
+#include <map>
#include <google/protobuf/compiler/java/java_field.h>
namespace google {
namespace protobuf {
+ namespace compiler {
+ namespace java {
+ class Context; // context.h
+ class ClassNameResolver; // name_resolver.h
+ }
+ }
namespace io {
class Printer; // printer.h
}
@@ -53,25 +59,55 @@ namespace java {
class MessageGenerator {
public:
explicit MessageGenerator(const Descriptor* descriptor);
- ~MessageGenerator();
+ virtual ~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.
- void GenerateStaticVariables(io::Printer* printer);
+ virtual void GenerateStaticVariables(io::Printer* printer) = 0;
// Output code which initializes the static variables generated by
// GenerateStaticVariables().
- void GenerateStaticVariableInitializers(io::Printer* printer);
+ virtual void GenerateStaticVariableInitializers(io::Printer* printer) = 0;
// Generate the class itself.
- void Generate(io::Printer* printer);
+ virtual void Generate(io::Printer* printer) = 0;
+
+ // Generates the base interface that both the class and its builder implement
+ virtual void GenerateInterface(io::Printer* printer) = 0;
// Generate code to register all contained extensions with an
// ExtensionRegistry.
- void GenerateExtensionRegistrationCode(io::Printer* printer);
+ virtual void GenerateExtensionRegistrationCode(io::Printer* printer) = 0;
+
+ protected:
+ const Descriptor* descriptor_;
private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
+};
+
+class ImmutableMessageGenerator : public MessageGenerator {
+ public:
+ explicit 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 GenerateStaticVariableInitializers(io::Printer* printer);
+
+ private:
+ enum UseMemoization {
+ MEMOIZE,
+ DONT_MEMOIZE
+ };
+
+ void GenerateFieldAccessorTable(io::Printer* printer);
+ void GenerateFieldAccessorTableInitializer(io::Printer* printer);
+
void GenerateMessageSerializationMethods(io::Printer* printer);
void GenerateParseFromMethods(io::Printer* printer);
void GenerateSerializeOneField(io::Printer* printer,
@@ -81,13 +117,19 @@ class MessageGenerator {
void GenerateBuilder(io::Printer* printer);
void GenerateCommonBuilderMethods(io::Printer* printer);
+ void GenerateDescriptorMethods(io::Printer* printer);
void GenerateBuilderParsingMethods(io::Printer* printer);
- void GenerateIsInitialized(io::Printer* printer);
+ void GenerateIsInitialized(io::Printer* printer,
+ UseMemoization useMemoization);
+ void GenerateEqualsAndHashCode(io::Printer* printer);
+ void GenerateParser(io::Printer* printer);
+ void GenerateParsingConstructor(io::Printer* printer);
- const Descriptor* descriptor_;
- FieldGeneratorMap field_generators_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+ FieldGeneratorMap<ImmutableFieldGenerator> field_generators_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageGenerator);
};
} // namespace java
diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc
index 71edc02..e681314 100644
--- a/src/google/protobuf/compiler/java/java_message_field.cc
+++ b/src/google/protobuf/compiler/java/java_message_field.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,8 +35,11 @@
#include <map>
#include <string>
+#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_message_field.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/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
@@ -48,88 +51,413 @@ namespace java {
namespace {
-// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
-// repeat code between this and the other field types.
void SetMessageVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ const FieldGeneratorInfo* info,
+ ClassNameResolver* name_resolver,
map<string, string>* variables) {
- (*variables)["name"] =
- UnderscoresToCamelCase(descriptor);
- (*variables)["capitalized_name"] =
- UnderscoresToCapitalizedCamelCase(descriptor);
- (*variables)["number"] = SimpleItoa(descriptor->number());
- (*variables)["type"] = ClassName(descriptor->message_type());
+ SetCommonFieldVariables(descriptor, info, variables);
+
+ (*variables)["type"] =
+ name_resolver->GetImmutableClassName(descriptor->message_type());
+ (*variables)["mutable_type"] =
+ name_resolver->GetMutableClassName(descriptor->message_type());
(*variables)["group_or_message"] =
(GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ?
"Group" : "Message";
+ // 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();" : "";
+
+ if (SupportFieldPresence(descriptor->file())) {
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+
+ // Note that these have a trailing ";".
+ (*variables)["set_has_field_bit_message"] =
+ GenerateSetBit(messageBitIndex) + ";";
+ (*variables)["set_has_field_bit_builder"] =
+ GenerateSetBit(builderBitIndex) + ";";
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex) + ";";
+
+ (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+ } else {
+ (*variables)["set_has_field_bit_message"] = "";
+ (*variables)["set_has_field_bit_builder"] = "";
+ (*variables)["clear_has_field_bit_builder"] = "";
+
+ (*variables)["is_field_present_message"] =
+ (*variables)["name"] + "_ != null";
+ }
+
+ // For repated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ // For repeated fields, one bit is used for whether the array is immutable
+ // in the parsing constructor.
+ (*variables)["get_mutable_bit_parser"] =
+ GenerateGetBitMutableLocal(builderBitIndex);
+ (*variables)["set_mutable_bit_parser"] =
+ GenerateSetBitMutableLocal(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
}
} // namespace
// ===================================================================
-MessageFieldGenerator::
-MessageFieldGenerator(const FieldDescriptor* descriptor)
- : descriptor_(descriptor) {
- SetMessageVariables(descriptor, &variables_);
+ImmutableMessageFieldGenerator::
+ImmutableMessageFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex), context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
}
-MessageFieldGenerator::~MessageFieldGenerator() {}
+ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {}
-void MessageFieldGenerator::
+int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
+ return 1;
+}
+
+int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ // TODO(jonp): In the future, consider having a method specific to the
+ // interface so that builders can choose dynamically to either return a
+ // message or a nested builder, so that asking for the interface doesn't
+ // cause a message to ever be built.
+ if (SupportFieldPresence(descriptor_->file()) ||
+ descriptor_->containing_oneof() == NULL) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n");
+ }
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$$type$ get$capitalized_name$();\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n");
+ }
+}
+
+void ImmutableMessageFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private boolean has$capitalized_name$;\n"
- "private $type$ $name$_;\n"
- "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
- "public $type$ get$capitalized_name$() { return $name$_; }\n");
+ "private $type$ $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder "
+ "get$capitalized_name$OrBuilder() {\n"
+ " return $name$_;\n"
+ "}\n");
+ }
+ } else {
+ WriteFieldDocComment(printer, descriptor_);
+ 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"
+ " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
+ "}\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder "
+ "get$capitalized_name$OrBuilder() {\n"
+ " return get$capitalized_name$();\n"
+ "}\n");
+ }
+ }
}
-void MessageFieldGenerator::
+void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
+ io::Printer* printer,
+ const char* regular_case,
+ const char* nested_builder_case) const {
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_, "if ($name$Builder_ == null) {\n");
+ printer->Indent();
+ printer->Print(variables_, regular_case);
+ printer->Outdent();
+ printer->Print("} else {\n");
+ printer->Indent();
+ printer->Print(variables_, nested_builder_case);
+ printer->Outdent();
+ printer->Print("}\n");
+ } else {
+ printer->Print(variables_, regular_case);
+ }
+}
+
+void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
+ io::Printer* printer,
+ const char* method_prototype,
+ const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const {
+ printer->Print(variables_, method_prototype);
+ printer->Print(" {\n");
+ printer->Indent();
+ PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
+ if (trailing_code != NULL) {
+ printer->Print(variables_, trailing_code);
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void ImmutableMessageFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
- printer->Print(variables_,
- "public boolean has$capitalized_name$() {\n"
- " return result.has$capitalized_name$();\n"
- "}\n"
- "public $type$ get$capitalized_name$() {\n"
- " return result.get$capitalized_name$();\n"
- "}\n"
- "public Builder set$capitalized_name$($type$ value) {\n"
- " if (value == null) {\n"
- " throw new NullPointerException();\n"
- " }\n"
- " result.has$capitalized_name$ = true;\n"
- " result.$name$_ = value;\n"
- " return this;\n"
- "}\n"
- "public Builder set$capitalized_name$($type$.Builder builderForValue) {\n"
- " result.has$capitalized_name$ = true;\n"
- " result.$name$_ = builderForValue.build();\n"
- " return this;\n"
- "}\n"
- "public Builder merge$capitalized_name$($type$ value) {\n"
- " if (result.has$capitalized_name$() &&\n"
- " result.$name$_ != $type$.getDefaultInstance()) {\n"
- " result.$name$_ =\n"
- " $type$.newBuilder(result.$name$_).mergeFrom(value).buildPartial();\n"
- " } else {\n"
- " result.$name$_ = value;\n"
- " }\n"
- " result.has$capitalized_name$ = true;\n"
- " return this;\n"
+ // When using nested-builders, the code initially works just like the
+ // non-nested builder case. It only creates a nested builder lazily on
+ // demand and then forever delegates to it after creation.
+
+ bool support_field_presence = SupportFieldPresence(descriptor_->file());
+
+ if (support_field_presence) {
+ printer->Print(variables_,
+ // Used when the builder is null.
+ "private $type$ $name$_ = $type$.getDefaultInstance();\n");
+ } else {
+ printer->Print(variables_,
+ "private $type$ $name$_ = null;\n");
+ }
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ // If this builder is non-null, it is used and the other fields are
+ // ignored.
+ "private com.google.protobuf.SingleFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
+ "\n");
+ }
+
+ // The comments above the methods below are based on a hypothetical
+ // field of type "Field" called "Field".
+
+ // boolean hasField()
+ WriteFieldDocComment(printer, descriptor_);
+ if (support_field_presence) {
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $name$Builder_ != null || $name$_ != null;\n"
+ "}\n");
+ }
+
+ // Field getField()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public $type$ get$capitalized_name$()",
+
+ support_field_presence
+ ? "return $name$_;\n"
+ : "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n",
+
+ "return $name$Builder_.getMessage();\n",
+
+ NULL);
+
+ // Field.Builder setField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$($type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
"}\n"
- "public Builder clear$capitalized_name$() {\n"
- " result.has$capitalized_name$ = false;\n"
- " result.$name$_ = $type$.getDefaultInstance();\n"
- " return this;\n"
- "}\n");
+ "$name$_ = value;\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(value);\n",
+
+ "$set_has_field_bit_builder$\n"
+ "return this;\n");
+
+ // Field.Builder setField(Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " $type$.Builder builderForValue)",
+
+ "$name$_ = builderForValue.build();\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(builderForValue.build());\n",
+
+ "$set_has_field_bit_builder$\n"
+ "return this;\n");
+
+ // Field.Builder mergeField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder merge$capitalized_name$($type$ value)",
+
+ support_field_presence
+ ? "if ($get_has_field_bit_builder$ &&\n"
+ " $name$_ != $type$.getDefaultInstance()) {\n"
+ " $name$_ =\n"
+ " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
+ "} else {\n"
+ " $name$_ = value;\n"
+ "}\n"
+ "$on_changed$\n"
+ : "if ($name$_ != null) {\n"
+ " $name$_ =\n"
+ " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
+ "} else {\n"
+ " $name$_ = value;\n"
+ "}\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.mergeFrom(value);\n",
+
+ "$set_has_field_bit_builder$\n"
+ "return this;\n");
+
+ // Field.Builder clearField()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder clear$capitalized_name$()",
+
+ support_field_presence
+ ? "$name$_ = $type$.getDefaultInstance();\n"
+ "$on_changed$\n"
+ : "$name$_ = null;\n"
+ "$on_changed$\n",
+
+ support_field_presence
+ ? "$name$Builder_.clear();\n"
+ : "$name$_ = null;\n"
+ "$name$Builder_ = null;\n",
+
+ "$clear_has_field_bit_builder$\n"
+ "return this;\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n"
+ " $set_has_field_bit_builder$\n"
+ " $on_changed$\n"
+ " return get$capitalized_name$FieldBuilder().getBuilder();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+ " if ($name$Builder_ != null) {\n"
+ " return $name$Builder_.getMessageOrBuilder();\n"
+ " } else {\n");
+ if (support_field_presence) {
+ printer->Print(variables_,
+ " return $name$_;\n");
+ } else {
+ printer->Print(variables_,
+ " return $name$_ == null ?\n"
+ " $type$.getDefaultInstance() : $name$_;\n");
+ }
+ printer->Print(variables_,
+ " }\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private com.google.protobuf.SingleFieldBuilder<\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"
+ " $type$, $type$.Builder, $type$OrBuilder>(\n"
+ " get$capitalized_name$(),\n"
+ " getParentForChildren(),\n"
+ " isClean());\n"
+ " $name$_ = null;\n"
+ " }\n"
+ " return $name$Builder_;\n"
+ "}\n");
+ }
}
-void MessageFieldGenerator::
+void ImmutableMessageFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ if (SupportFieldPresence(descriptor_->file())) {
+ printer->Print(variables_,
+ "get$capitalized_name$FieldBuilder();\n");
+ }
+}
+
+
+void ImmutableMessageFieldGenerator::
GenerateInitializationCode(io::Printer* printer) const {
- printer->Print(variables_, "$name$_ = $type$.getDefaultInstance();\n");
+ if (SupportFieldPresence(descriptor_->file())) {
+ printer->Print(variables_, "$name$_ = $type$.getDefaultInstance();\n");
+ }
}
-void MessageFieldGenerator::
+void ImmutableMessageFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ if (SupportFieldPresence(descriptor_->file())) {
+ PrintNestedBuilderCondition(printer,
+ "$name$_ = $type$.getDefaultInstance();\n",
+
+ "$name$Builder_.clear();\n");
+ printer->Print(variables_, "$clear_has_field_bit_builder$\n");
+ } else {
+ PrintNestedBuilderCondition(printer,
+ "$name$_ = null;\n",
+
+ "$name$_ = null;\n"
+ "$name$Builder_ = null;\n");
+ }
+}
+
+void ImmutableMessageFieldGenerator::
GenerateMergingCode(io::Printer* printer) const {
printer->Print(variables_,
"if (other.has$capitalized_name$()) {\n"
@@ -137,196 +465,876 @@ GenerateMergingCode(io::Printer* printer) const {
"}\n");
}
-void MessageFieldGenerator::
+void ImmutableMessageFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const {
- // Nothing to do for singular fields.
+ if (SupportFieldPresence(descriptor_->file())) {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n");
+ }
+
+ PrintNestedBuilderCondition(printer,
+ "result.$name$_ = $name$_;\n",
+
+ "result.$name$_ = $name$Builder_.build();\n");
}
-void MessageFieldGenerator::
+void ImmutableMessageFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
- "$type$.Builder subBuilder = $type$.newBuilder();\n"
- "if (has$capitalized_name$()) {\n"
- " subBuilder.mergeFrom(get$capitalized_name$());\n"
+ "$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_,
- "input.readGroup($number$, subBuilder, extensionRegistry);\n");
+ "$name$_ = input.readGroup($number$, $type$.PARSER,\n"
+ " extensionRegistry);\n");
} else {
printer->Print(variables_,
- "input.readMessage(subBuilder, extensionRegistry);\n");
+ "$name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n");
}
printer->Print(variables_,
- "set$capitalized_name$(subBuilder.buildPartial());\n");
+ "if (subBuilder != null) {\n"
+ " subBuilder.mergeFrom($name$_);\n"
+ " $name$_ = subBuilder.buildPartial();\n"
+ "}\n"
+ "$set_has_field_bit_message$\n");
}
-void MessageFieldGenerator::
+void ImmutableMessageFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+ // noop for messages.
+}
+
+void ImmutableMessageFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (has$capitalized_name$()) {\n"
- " output.write$group_or_message$($number$, get$capitalized_name$());\n"
+ "if ($is_field_present_message$) {\n"
+ " output.write$group_or_message$($number$, $name$_);\n"
"}\n");
}
-void MessageFieldGenerator::
+void ImmutableMessageFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (has$capitalized_name$()) {\n"
+ "if ($is_field_present_message$) {\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
+ " .compute$group_or_message$Size($number$, $name$_);\n"
"}\n");
}
-string MessageFieldGenerator::GetBoxedType() const {
- return ClassName(descriptor_->message_type());
+void ImmutableMessageFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$()\n"
+ " .equals(other.get$capitalized_name$());\n");
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n"
+ "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+}
+
+string ImmutableMessageFieldGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->message_type());
}
// ===================================================================
-RepeatedMessageFieldGenerator::
-RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor)
- : descriptor_(descriptor) {
- SetMessageVariables(descriptor, &variables_);
+ImmutableMessageOneofFieldGenerator::
+ImmutableMessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : ImmutableMessageFieldGenerator(
+ descriptor, messageBitIndex, builderBitIndex, context) {
+ const OneofGeneratorInfo* info =
+ context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+ SetCommonOneofVariables(descriptor, info, &variables_);
}
-RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
+ImmutableMessageOneofFieldGenerator::
+~ImmutableMessageOneofFieldGenerator() {}
-void RepeatedMessageFieldGenerator::
+void ImmutableMessageOneofFieldGenerator::
GenerateMembers(io::Printer* printer) const {
+ PrintExtraFieldInfo(variables_, printer);
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ }
+ WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
- "private java.util.List<$type$> $name$_ =\n"
- " java.util.Collections.emptyList();\n"
- "public java.util.List<$type$> get$capitalized_name$List() {\n"
- " return $name$_;\n" // note: unmodifiable list
- "}\n"
- "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
- "public $type$ get$capitalized_name$(int index) {\n"
- " return $name$_.get(index);\n"
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($type$) $oneof_name$_;\n"
+ " }\n"
+ " return $type$.getDefaultInstance();\n"
"}\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($type$) $oneof_name$_;\n"
+ " }\n"
+ " return $type$.getDefaultInstance();\n"
+ "}\n");
+ }
}
-void RepeatedMessageFieldGenerator::
+void ImmutableMessageOneofFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
- printer->Print(variables_,
- // Note: We return an unmodifiable list because otherwise the caller
- // could hold on to the returned list and modify it after the message
- // has been built, thus mutating the message which is supposed to be
- // immutable.
- "public java.util.List<$type$> get$capitalized_name$List() {\n"
- " return java.util.Collections.unmodifiableList(result.$name$_);\n"
+ // When using nested-builders, the code initially works just like the
+ // non-nested builder case. It only creates a nested builder lazily on
+ // demand and then forever delegates to it after creation.
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ // If this builder is non-null, it is used and the other fields are
+ // ignored.
+ "private com.google.protobuf.SingleFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
+ "\n");
+ }
+
+ // The comments above the methods below are based on a hypothetical
+ // field of type "Field" called "Field".
+
+ if (SupportFieldPresence(descriptor_->file())) {
+ // boolean hasField()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ }
+
+ // Field getField()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public $type$ get$capitalized_name$()",
+
+ "if ($has_oneof_case_message$) {\n"
+ " return ($type$) $oneof_name$_;\n"
"}\n"
- "public int get$capitalized_name$Count() {\n"
- " return result.get$capitalized_name$Count();\n"
+ "return $type$.getDefaultInstance();\n",
+
+ "if ($has_oneof_case_message$) {\n"
+ " return $name$Builder_.getMessage();\n"
"}\n"
- "public $type$ get$capitalized_name$(int index) {\n"
- " return result.get$capitalized_name$(index);\n"
+ "return $type$.getDefaultInstance();\n",
+
+ NULL);
+
+ // Field.Builder setField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$($type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
"}\n"
- "public Builder set$capitalized_name$(int index, $type$ value) {\n"
- " if (value == null) {\n"
- " throw new NullPointerException();\n"
- " }\n"
- " result.$name$_.set(index, value);\n"
- " return this;\n"
+ "$oneof_name$_ = value;\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(value);\n",
+
+ "$set_oneof_case_message$;\n"
+ "return this;\n");
+
+ // Field.Builder setField(Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " $type$.Builder builderForValue)",
+
+ "$oneof_name$_ = builderForValue.build();\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(builderForValue.build());\n",
+
+ "$set_oneof_case_message$;\n"
+ "return this;\n");
+
+ // Field.Builder mergeField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder merge$capitalized_name$($type$ value)",
+
+ "if ($has_oneof_case_message$ &&\n"
+ " $oneof_name$_ != $type$.getDefaultInstance()) {\n"
+ " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
+ " .mergeFrom(value).buildPartial();\n"
+ "} else {\n"
+ " $oneof_name$_ = value;\n"
"}\n"
- "public Builder set$capitalized_name$(int index, "
- "$type$.Builder builderForValue) {\n"
- " result.$name$_.set(index, builderForValue.build());\n"
- " return this;\n"
+ "$on_changed$\n",
+
+ "if ($has_oneof_case_message$) {\n"
+ " $name$Builder_.mergeFrom(value);\n"
"}\n"
- "public Builder add$capitalized_name$($type$ value) {\n"
- " if (value == null) {\n"
- " throw new NullPointerException();\n"
- " }\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
- " }\n"
- " result.$name$_.add(value);\n"
- " return this;\n"
+ "$name$Builder_.setMessage(value);\n",
+
+ "$set_oneof_case_message$;\n"
+ "return this;\n");
+
+ // Field.Builder clearField()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder clear$capitalized_name$()",
+
+ "if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ " $on_changed$\n"
+ "}\n",
+
+ "if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
"}\n"
- "public Builder add$capitalized_name$($type$.Builder builderForValue) {\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
- " }\n"
- " result.$name$_.add(builderForValue.build());\n"
- " return this;\n"
+ "$name$Builder_.clear();\n",
+
+ "return this;\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n"
+ " return get$capitalized_name$FieldBuilder().getBuilder();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+ " if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n"
+ " return $name$Builder_.getMessageOrBuilder();\n"
+ " } else {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($type$) $oneof_name$_;\n"
+ " }\n"
+ " return $type$.getDefaultInstance();\n"
+ " }\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private com.google.protobuf.SingleFieldBuilder<\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"
+ " $type$, $type$.Builder, $type$OrBuilder>(\n"
+ " ($type$) $oneof_name$_,\n"
+ " getParentForChildren(),\n"
+ " isClean());\n"
+ " $oneof_name$_ = null;\n"
+ " }\n"
+ " $set_oneof_case_message$;\n"
+ " return $name$Builder_;\n"
+ "}\n");
+ }
+}
+
+void ImmutableMessageOneofFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n");
+ printer->Indent();
+
+ PrintNestedBuilderCondition(printer,
+ "result.$oneof_name$_ = $oneof_name$_;\n",
+
+ "result.$oneof_name$_ = $name$Builder_.build();\n");
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void ImmutableMessageOneofFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "merge$capitalized_name$(other.get$capitalized_name$());\n");
+}
+
+void ImmutableMessageOneofFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$type$.Builder subBuilder = null;\n"
+ "if ($has_oneof_case_message$) {\n"
+ " subBuilder = (($type$) $oneof_name$_).toBuilder();\n"
+ "}\n");
+
+ if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
+ printer->Print(variables_,
+ "$oneof_name$_ = input.readGroup($number$, $type$.PARSER,\n"
+ " extensionRegistry);\n");
+ } else {
+ printer->Print(variables_,
+ "$oneof_name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n");
+ }
+
+ printer->Print(variables_,
+ "if (subBuilder != null) {\n"
+ " subBuilder.mergeFrom(($type$) $oneof_name$_);\n"
+ " $oneof_name$_ = subBuilder.buildPartial();\n"
+ "}\n");
+ printer->Print(variables_,
+ "$set_oneof_case_message$;\n");
+}
+
+void ImmutableMessageOneofFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n"
+ "}\n");
+}
+
+void ImmutableMessageOneofFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .compute$group_or_message$Size($number$, ($type$) $oneof_name$_);\n"
+ "}\n");
+}
+
+// ===================================================================
+
+RepeatedImmutableMessageFieldGenerator::
+RepeatedImmutableMessageFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex), context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+RepeatedImmutableMessageFieldGenerator::
+~RepeatedImmutableMessageFieldGenerator() {}
+
+int RepeatedImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ // TODO(jonp): In the future, consider having methods specific to the
+ // interface so that builders can choose dynamically to either return a
+ // message or a nested builder, so that asking for the interface doesn't
+ // cause a message to ever be built.
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$java.util.List<$type$> \n"
+ " get$capitalized_name$List();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$$type$ get$capitalized_name$(int index);\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$java.util.List<? extends $type$OrBuilder> \n"
+ " get$capitalized_name$OrBuilderList();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n"
+ " int index);\n");
+ }
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private java.util.List<$type$> $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
+ " return $name$_;\n" // note: unmodifiable list
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
+ " get$capitalized_name$OrBuilderList() {\n"
+ " return $name$_;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
+ " int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+
+}
+
+void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
+ io::Printer* printer,
+ const char* regular_case,
+ const char* nested_builder_case) const {
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_, "if ($name$Builder_ == null) {\n");
+ printer->Indent();
+ printer->Print(variables_, regular_case);
+ printer->Outdent();
+ printer->Print("} else {\n");
+ printer->Indent();
+ printer->Print(variables_, nested_builder_case);
+ printer->Outdent();
+ printer->Print("}\n");
+ } else {
+ printer->Print(variables_, regular_case);
+ }
+}
+
+void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
+ io::Printer* printer,
+ const char* method_prototype,
+ const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const {
+ printer->Print(variables_, method_prototype);
+ printer->Print(" {\n");
+ printer->Indent();
+ PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
+ if (trailing_code != NULL) {
+ printer->Print(variables_, trailing_code);
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ // When using nested-builders, the code initially works just like the
+ // non-nested builder case. It only creates a nested builder lazily on
+ // demand and then forever delegates to it after creation.
+
+ printer->Print(variables_,
+ // Used when the builder is null.
+ // One field is the list and the other field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a refererence to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ "private java.util.List<$type$> $name$_ =\n"
+ " java.util.Collections.emptyList();\n"
+
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
"}\n"
- "public Builder addAll$capitalized_name$(\n"
- " java.lang.Iterable<? extends $type$> values) {\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
- " }\n"
- " super.addAll(values, result.$name$_);\n"
- " return this;\n"
+ "\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ // If this builder is non-null, it is used and the other fields are
+ // ignored.
+ "private com.google.protobuf.RepeatedFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
+ "\n");
+ }
+
+ // The comments above the methods below are based on a hypothetical
+ // repeated field of type "Field" called "RepeatedField".
+
+ // List<Field> getRepeatedFieldList()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public java.util.List<$type$> get$capitalized_name$List()",
+
+ "return java.util.Collections.unmodifiableList($name$_);\n",
+ "return $name$Builder_.getMessageList();\n",
+
+ NULL);
+
+ // int getRepeatedFieldCount()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public int get$capitalized_name$Count()",
+
+ "return $name$_.size();\n",
+ "return $name$Builder_.getCount();\n",
+
+ NULL);
+
+ // Field getRepeatedField(int index)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public $type$ get$capitalized_name$(int index)",
+
+ "return $name$_.get(index);\n",
+
+ "return $name$Builder_.getMessage(index);\n",
+
+ NULL);
+
+ // Builder setRepeatedField(int index, Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$ value)",
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
"}\n"
- "public Builder clear$capitalized_name$() {\n"
- " result.$name$_ = java.util.Collections.emptyList();\n"
- " return this;\n"
- "}\n");
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.set(index, value);\n"
+ "$on_changed$\n",
+ "$name$Builder_.setMessage(index, value);\n",
+ "return this;\n");
+
+ // Builder setRepeatedField(int index, Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.set(index, builderForValue.build());\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(index, builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$($type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(value);\n"
+
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(value);\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(int index, Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " int index, $type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(index, value);\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(index, value);\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(builderForValue.build());\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(int index, Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " int index, $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(index, builderForValue.build());\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(index, builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addAllRepeatedField(Iterable<Field> values)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder addAll$capitalized_name$(\n"
+ " java.lang.Iterable<? extends $type$> values)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
+ " values, $name$_);\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addAllMessages(values);\n",
+
+ "return this;\n");
+
+ // Builder clearAllRepeatedField()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder clear$capitalized_name$()",
+
+ "$name$_ = java.util.Collections.emptyList();\n"
+ "$clear_mutable_bit_builder$;\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.clear();\n",
+
+ "return this;\n");
+
+ // Builder removeRepeatedField(int index)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder remove$capitalized_name$(int index)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.remove(index);\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.remove(index);\n",
+
+ "return this;\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder get$capitalized_name$Builder(\n"
+ " int index) {\n"
+ " return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
+ " int index) {\n"
+ " if ($name$Builder_ == null) {\n"
+ " return $name$_.get(index);"
+ " } else {\n"
+ " return $name$Builder_.getMessageOrBuilder(index);\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
+ " get$capitalized_name$OrBuilderList() {\n"
+ " if ($name$Builder_ != null) {\n"
+ " return $name$Builder_.getMessageOrBuilderList();\n"
+ " } else {\n"
+ " return java.util.Collections.unmodifiableList($name$_);\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n"
+ " return get$capitalized_name$FieldBuilder().addBuilder(\n"
+ " $type$.getDefaultInstance());\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder add$capitalized_name$Builder(\n"
+ " int index) {\n"
+ " return get$capitalized_name$FieldBuilder().addBuilder(\n"
+ " index, $type$.getDefaultInstance());\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<$type$.Builder> \n"
+ " get$capitalized_name$BuilderList() {\n"
+ " return get$capitalized_name$FieldBuilder().getBuilderList();\n"
+ "}\n"
+ "private com.google.protobuf.RepeatedFieldBuilder<\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"
+ " $type$, $type$.Builder, $type$OrBuilder>(\n"
+ " $name$_,\n"
+ " $get_mutable_bit_builder$,\n"
+ " getParentForChildren(),\n"
+ " isClean());\n"
+ " $name$_ = null;\n"
+ " }\n"
+ " return $name$Builder_;\n"
+ "}\n");
+ }
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "get$capitalized_name$FieldBuilder();\n");
}
-void RepeatedMessageFieldGenerator::
+void RepeatedImmutableMessageFieldGenerator::
GenerateInitializationCode(io::Printer* printer) const {
- // Initialized inline.
+ printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ PrintNestedBuilderCondition(printer,
+ "$name$_ = java.util.Collections.emptyList();\n"
+ "$clear_mutable_bit_builder$;\n",
+
+ "$name$Builder_.clear();\n");
}
-void RepeatedMessageFieldGenerator::
+void RepeatedImmutableMessageFieldGenerator::
GenerateMergingCode(io::Printer* printer) const {
- printer->Print(variables_,
+ // 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.
+ PrintNestedBuilderCondition(printer,
+ "if (!other.$name$_.isEmpty()) {\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
+ " }\n"
+ " $on_changed$\n"
+ "}\n",
+
"if (!other.$name$_.isEmpty()) {\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
+ " if ($name$Builder_.isEmpty()) {\n"
+ " $name$Builder_.dispose();\n"
+ " $name$Builder_ = null;\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $name$Builder_ = \n"
+ " com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?\n"
+ " get$capitalized_name$FieldBuilder() : null;\n"
+ " } else {\n"
+ " $name$Builder_.addAllMessages(other.$name$_);\n"
" }\n"
- " result.$name$_.addAll(other.$name$_);\n"
"}\n");
}
-void RepeatedMessageFieldGenerator::
+void RepeatedImmutableMessageFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const {
- printer->Print(variables_,
- "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n"
- " result.$name$_ =\n"
- " java.util.Collections.unmodifiableList(result.$name$_);\n"
- "}\n");
+ // The code below (non-nested builder case) ensures that the result has an
+ // immutable list. If our list is immutable, we can just reuse it. If not,
+ // we make it immutable.
+ PrintNestedBuilderCondition(printer,
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n",
+
+ "result.$name$_ = $name$Builder_.build();\n");
}
-void RepeatedMessageFieldGenerator::
+void RepeatedImmutableMessageFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
- "$type$.Builder subBuilder = $type$.newBuilder();\n");
+ "if (!$get_mutable_bit_parser$) {\n"
+ " $name$_ = new java.util.ArrayList<$type$>();\n"
+ " $set_mutable_bit_parser$;\n"
+ "}\n");
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "input.readGroup($number$, subBuilder, extensionRegistry);\n");
+ "$name$_.add(input.readGroup($number$, $type$.PARSER,\n"
+ " extensionRegistry));\n");
} else {
printer->Print(variables_,
- "input.readMessage(subBuilder, extensionRegistry);\n");
+ "$name$_.add(input.readMessage($type$.PARSER, extensionRegistry));\n");
}
+}
+void RepeatedImmutableMessageFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
printer->Print(variables_,
- "add$capitalized_name$(subBuilder.buildPartial());\n");
+ "if ($get_mutable_bit_parser$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ "}\n");
}
-void RepeatedMessageFieldGenerator::
+void RepeatedImmutableMessageFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
- " output.write$group_or_message$($number$, element);\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$group_or_message$($number$, $name$_.get(i));\n"
"}\n");
}
-void RepeatedMessageFieldGenerator::
+void RepeatedImmutableMessageFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .compute$group_or_message$Size($number$, element);\n"
+ " .compute$group_or_message$Size($number$, $name$_.get(i));\n"
+ "}\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
"}\n");
}
-string RepeatedMessageFieldGenerator::GetBoxedType() const {
- return ClassName(descriptor_->message_type());
+string RepeatedImmutableMessageFieldGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->message_type());
}
} // namespace java
diff --git a/src/google/protobuf/compiler/java/java_message_field.h b/src/google/protobuf/compiler/java/java_message_field.h
index 66bdd88..ea8225a 100644
--- a/src/google/protobuf/compiler/java/java_message_field.h
+++ b/src/google/protobuf/compiler/java/java_message_field.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -41,55 +41,128 @@
namespace google {
namespace protobuf {
+ namespace compiler {
+ namespace java {
+ class Context; // context.h
+ class ClassNameResolver; // name_resolver.h
+ }
+ }
+}
+
+namespace protobuf {
namespace compiler {
namespace java {
-class MessageFieldGenerator : public FieldGenerator {
+class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator {
public:
- explicit MessageFieldGenerator(const FieldDescriptor* descriptor);
- ~MessageFieldGenerator();
-
- // implements FieldGenerator ---------------------------------------
+ explicit ImmutableMessageFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~ImmutableMessageFieldGenerator();
+
+ // implements ImmutableFieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
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 GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
string GetBoxedType() const;
- private:
+ protected:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+
+ void PrintNestedBuilderCondition(io::Printer* printer,
+ const char* regular_case, const char* nested_builder_case) const;
+ void PrintNestedBuilderFunction(io::Printer* printer,
+ const char* method_prototype, const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldGenerator);
};
-class RepeatedMessageFieldGenerator : public FieldGenerator {
+class ImmutableMessageOneofFieldGenerator
+ : public ImmutableMessageFieldGenerator {
public:
- explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor);
- ~RepeatedMessageFieldGenerator();
+ ImmutableMessageOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~ImmutableMessageOneofFieldGenerator();
- // implements FieldGenerator ---------------------------------------
+ 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 GenerateParsingCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageOneofFieldGenerator);
+};
+
+class RepeatedImmutableMessageFieldGenerator : public ImmutableFieldGenerator {
+ public:
+ explicit RepeatedImmutableMessageFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~RepeatedImmutableMessageFieldGenerator();
+
+ // implements ImmutableFieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
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 GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
string GetBoxedType() const;
- private:
+ protected:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+
+ void PrintNestedBuilderCondition(io::Printer* printer,
+ const char* regular_case, const char* nested_builder_case) const;
+ void PrintNestedBuilderFunction(io::Printer* printer,
+ const char* method_prototype, const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableMessageFieldGenerator);
};
} // namespace java
diff --git a/src/google/protobuf/compiler/java/java_name_resolver.cc b/src/google/protobuf/compiler/java/java_name_resolver.cc
new file mode 100644
index 0000000..0c363f9
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_name_resolver.cc
@@ -0,0 +1,266 @@
+// 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_name_resolver.h>
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+// A suffix that will be appended to the file's outer class name if the name
+// conflicts with some other types defined in the file.
+const char* kOuterClassNameSuffix = "OuterClass";
+
+// Strip package name from a descriptor's full name.
+// For example:
+// Full name : foo.Bar.Baz
+// Package name: foo
+// After strip : Bar.Baz
+string StripPackageName(const string& full_name,
+ const FileDescriptor* file) {
+ if (file->package().empty()) {
+ return full_name;
+ } else {
+ // Strip package name
+ return full_name.substr(file->package().size() + 1);
+ }
+}
+
+// Get the name of a message's Java class without package name prefix.
+string ClassNameWithoutPackage(const Descriptor* descriptor,
+ bool immutable) {
+ return StripPackageName(descriptor->full_name(),
+ descriptor->file());
+}
+
+// Get the name of an enum's Java class without package name prefix.
+string ClassNameWithoutPackage(const EnumDescriptor* descriptor,
+ bool immutable) {
+ // Doesn't append "Mutable" for enum type's name.
+ const Descriptor* message_descriptor = descriptor->containing_type();
+ if (message_descriptor == NULL) {
+ return descriptor->name();
+ } else {
+ return ClassNameWithoutPackage(message_descriptor, immutable) +
+ "." + descriptor->name();
+ }
+}
+
+// Get the name of a service's Java class without package name prefix.
+string ClassNameWithoutPackage(const ServiceDescriptor* descriptor,
+ bool immutable) {
+ string full_name = StripPackageName(descriptor->full_name(),
+ descriptor->file());
+ // We don't allow nested service definitions.
+ GOOGLE_CHECK(full_name.find('.') == string::npos);
+ return full_name;
+}
+
+// Check whether a given message or its nested types has the given class name.
+bool MessageHasConflictingClassName(const Descriptor* message,
+ const string& classname) {
+ if (message->name() == classname) return true;
+ for (int i = 0; i < message->nested_type_count(); ++i) {
+ if (MessageHasConflictingClassName(message->nested_type(i), classname)) {
+ return true;
+ }
+ }
+ for (int i = 0; i < message->enum_type_count(); ++i) {
+ if (message->enum_type(i)->name() == classname) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+ClassNameResolver::ClassNameResolver() {
+}
+
+ClassNameResolver::~ClassNameResolver() {
+}
+
+string ClassNameResolver::GetFileDefaultImmutableClassName(
+ const FileDescriptor* file) {
+ string basename;
+ string::size_type last_slash = file->name().find_last_of('/');
+ if (last_slash == string::npos) {
+ basename = file->name();
+ } else {
+ basename = file->name().substr(last_slash + 1);
+ }
+ return UnderscoresToCamelCase(StripProto(basename), true);
+}
+
+string ClassNameResolver::GetFileImmutableClassName(
+ const FileDescriptor* file) {
+ string& class_name = file_immutable_outer_class_names_[file];
+ if (class_name.empty()) {
+ if (file->options().has_java_outer_classname()) {
+ class_name = file->options().java_outer_classname();
+ } else {
+ class_name = GetFileDefaultImmutableClassName(file);
+ if (HasConflictingClassName(file, class_name)) {
+ class_name += kOuterClassNameSuffix;
+ }
+ }
+ }
+ return class_name;
+}
+
+string ClassNameResolver::GetFileClassName(const FileDescriptor* file,
+ bool immutable) {
+ if (immutable) {
+ return GetFileImmutableClassName(file);
+ } else {
+ return "Mutable" + GetFileImmutableClassName(file);
+ }
+}
+
+// Check whether there is any type defined in the proto file that has
+// the given class name.
+bool ClassNameResolver::HasConflictingClassName(
+ const FileDescriptor* file, const string& classname) {
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ if (file->enum_type(i)->name() == classname) {
+ return true;
+ }
+ }
+ for (int i = 0; i < file->service_count(); i++) {
+ if (file->service(i)->name() == classname) {
+ return true;
+ }
+ }
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (MessageHasConflictingClassName(file->message_type(i), classname)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+string ClassNameResolver::GetDescriptorClassName(
+ const FileDescriptor* descriptor) {
+ return GetFileImmutableClassName(descriptor);
+}
+
+string ClassNameResolver::GetClassName(const FileDescriptor* descriptor,
+ bool immutable) {
+ string result = FileJavaPackage(descriptor, immutable);
+ if (!result.empty()) result += '.';
+ result += GetFileClassName(descriptor, immutable);
+ return result;
+}
+
+// Get the full name of a Java class by prepending the Java package name
+// or outer class name.
+string ClassNameResolver::GetClassFullName(const string& name_without_package,
+ const FileDescriptor* file,
+ bool immutable,
+ bool multiple_files) {
+ string result;
+ if (multiple_files) {
+ result = FileJavaPackage(file, immutable);
+ } else {
+ result = GetClassName(file, immutable);
+ }
+ if (!result.empty()) {
+ result += '.';
+ }
+ result += name_without_package;
+ return result;
+}
+
+string ClassNameResolver::GetClassName(const Descriptor* descriptor,
+ bool immutable) {
+ return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable),
+ descriptor->file(), immutable,
+ MultipleJavaFiles(descriptor->file(), immutable));
+}
+
+string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor,
+ bool immutable) {
+ return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable),
+ descriptor->file(), immutable,
+ MultipleJavaFiles(descriptor->file(), immutable));
+}
+
+string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor,
+ bool immutable) {
+ return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable),
+ descriptor->file(), immutable,
+ MultipleJavaFiles(descriptor->file(), immutable));
+}
+
+// Get the Java Class style full name of a message.
+string ClassNameResolver::GetJavaClassFullName(
+ const string& name_without_package,
+ const FileDescriptor* file,
+ bool immutable) {
+ string result;
+ if (MultipleJavaFiles(file, immutable)) {
+ result = FileJavaPackage(file, immutable);
+ if (!result.empty()) result += '.';
+ } else {
+ result = GetClassName(file, immutable);
+ if (!result.empty()) result += '$';
+ }
+ result += StringReplace(name_without_package, ".", "$", true);
+ return result;
+}
+
+string ClassNameResolver::GetExtensionIdentifierName(
+ const FieldDescriptor* descriptor, bool immutable) {
+ return GetClassName(descriptor->containing_type(), immutable) + "." +
+ descriptor->name();
+}
+
+
+string ClassNameResolver::GetJavaImmutableClassName(
+ const Descriptor* descriptor) {
+ return GetJavaClassFullName(
+ ClassNameWithoutPackage(descriptor, true),
+ descriptor->file(), true);
+}
+
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/java/java_name_resolver.h b/src/google/protobuf/compiler/java/java_name_resolver.h
new file mode 100644
index 0000000..ab60b0a
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_name_resolver.h
@@ -0,0 +1,124 @@
+// 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_NAME_RESOLVER_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_NAME_RESOLVER_H__
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+class Descriptor;
+class EnumDescriptor;
+class FieldDescriptor;
+class FileDescriptor;
+class ServiceDescriptor;
+
+namespace compiler {
+namespace java {
+
+// Used to get the Java class related names for a given descriptor. It caches
+// the results to avoid redundant calculation across multiple name queries.
+// Thread-safety note: This class is *not* thread-safe.
+class ClassNameResolver {
+ public:
+ ClassNameResolver();
+ ~ClassNameResolver();
+
+ // Gets the unqualified outer class name for the file.
+ string GetFileClassName(const FileDescriptor* file, bool immutable);
+ // Gets the unqualified immutable outer class name of a file.
+ string GetFileImmutableClassName(const FileDescriptor* file);
+ // Gets the unqualified default immutable outer class name of a file
+ // (converted from the proto file's name).
+ string GetFileDefaultImmutableClassName(const FileDescriptor* file);
+
+ // Check whether there is any type defined in the proto file that has
+ // the given class name.
+ bool HasConflictingClassName(const FileDescriptor* file,
+ const string& classname);
+
+ // Gets the name of the outer class that holds descriptor information.
+ // Descriptors are shared between immutable messages and mutable messages.
+ // Since both of them are generated optionally, the descriptors need to be
+ // put in another common place.
+ string GetDescriptorClassName(const FileDescriptor* file);
+
+ // Gets the fully-qualified class name corresponding to the given descriptor.
+ string GetClassName(const Descriptor* descriptor, bool immutable);
+ string GetClassName(const EnumDescriptor* descriptor, bool immutable);
+ string GetClassName(const ServiceDescriptor* descriptor, bool immutable);
+ string GetClassName(const FileDescriptor* descriptor, bool immutable);
+
+ template<class DescriptorType>
+ string GetImmutableClassName(const DescriptorType* descriptor) {
+ return GetClassName(descriptor, true);
+ }
+ template<class DescriptorType>
+ string GetMutableClassName(const DescriptorType* descriptor) {
+ return GetClassName(descriptor, false);
+ }
+
+ // Gets the fully qualified name of an extension identifier.
+ string GetExtensionIdentifierName(const FieldDescriptor* descriptor,
+ bool immutable);
+
+ // Gets the fully qualified name for generated classes in Java convention.
+ // Nested classes will be separated using '$' instead of '.'
+ // For example:
+ // com.package.OuterClass$OuterMessage$InnerMessage
+ string GetJavaImmutableClassName(const Descriptor* descriptor);
+ private:
+ // Get the full name of a Java class by prepending the Java package name
+ // or outer class name.
+ string GetClassFullName(const string& name_without_package,
+ const FileDescriptor* file,
+ bool immutable,
+ bool multiple_files);
+ // Get the Java Class style full name of a message.
+ string GetJavaClassFullName(
+ const string& name_without_package,
+ const FileDescriptor* file,
+ bool immutable);
+ // Caches the result to provide better performance.
+ map<const FileDescriptor*, string> file_immutable_outer_class_names_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ClassNameResolver);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_NAME_RESOLVER_H__
diff --git a/src/google/protobuf/compiler/java/java_plugin_unittest.cc b/src/google/protobuf/compiler/java/java_plugin_unittest.cc
index cfe0188..c4d6995 100644
--- a/src/google/protobuf/compiler/java/java_plugin_unittest.cc
+++ b/src/google/protobuf/compiler/java/java_plugin_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -34,6 +34,8 @@
// It seemed like parameterizing it would add more complexity than it is
// worth.
+#include <memory>
+
#include <google/protobuf/compiler/java/java_generator.h>
#include <google/protobuf/compiler/command_line_interface.h>
#include <google/protobuf/io/zero_copy_stream.h>
@@ -56,21 +58,22 @@ class TestGenerator : public CodeGenerator {
virtual bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
- TryInsert("Test.java", "outer_class_scope", output_directory);
- TryInsert("Test.java", "class_scope:foo.Bar", output_directory);
- TryInsert("Test.java", "class_scope:foo.Bar.Baz", output_directory);
- TryInsert("Test.java", "builder_scope:foo.Bar", output_directory);
- TryInsert("Test.java", "builder_scope:foo.Bar.Baz", output_directory);
- TryInsert("Test.java", "enum_scope:foo.Qux", output_directory);
+ string filename = "Test.java";
+ TryInsert(filename, "outer_class_scope", context);
+ TryInsert(filename, "class_scope:foo.Bar", context);
+ TryInsert(filename, "class_scope:foo.Bar.Baz", context);
+ TryInsert(filename, "builder_scope:foo.Bar", context);
+ TryInsert(filename, "builder_scope:foo.Bar.Baz", context);
+ TryInsert(filename, "enum_scope:foo.Qux", context);
return true;
}
void TryInsert(const string& filename, const string& insertion_point,
- OutputDirectory* output_directory) const {
+ GeneratorContext* context) const {
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->OpenForInsert(filename, insertion_point));
+ context->OpenForInsert(filename, insertion_point));
io::Printer printer(output.get(), '$');
printer.Print("// inserted $name$\n", "name", insertion_point);
}
@@ -80,16 +83,16 @@ class TestGenerator : public CodeGenerator {
// not verify that they are correctly-placed; that would require actually
// compiling the output which is a bit more than I care to do for this test.
TEST(JavaPluginTest, PluginTest) {
- File::WriteStringToFileOrDie(
- "syntax = \"proto2\";\n"
- "package foo;\n"
- "option java_package = \"\";\n"
- "option java_outer_classname = \"Test\";\n"
- "message Bar {\n"
- " message Baz {}\n"
- "}\n"
- "enum Qux { BLAH = 1; }\n",
- TestTempDir() + "/test.proto");
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto",
+ "syntax = \"proto2\";\n"
+ "package foo;\n"
+ "option java_package = \"\";\n"
+ "option java_outer_classname = \"Test\";\n"
+ "message Bar {\n"
+ " message Baz {}\n"
+ "}\n"
+ "enum Qux { BLAH = 1; }\n",
+ true));
google::protobuf::compiler::CommandLineInterface cli;
cli.SetInputsAreProtoPathRelative(true);
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc
index f6179bf..6713d29 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,9 +35,12 @@
#include <map>
#include <string>
-#include <google/protobuf/compiler/java/java_primitive_field.h>
#include <google/protobuf/stubs/common.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/compiler/java/java_primitive_field.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
@@ -72,98 +75,25 @@ const char* PrimitiveTypeName(JavaType type) {
return NULL;
}
-bool IsReferenceType(JavaType type) {
- switch (type) {
- case JAVATYPE_INT : return false;
- case JAVATYPE_LONG : return false;
- case JAVATYPE_FLOAT : return false;
- case JAVATYPE_DOUBLE : return false;
- case JAVATYPE_BOOLEAN: return false;
- case JAVATYPE_STRING : return true;
- case JAVATYPE_BYTES : return true;
- case JAVATYPE_ENUM : return true;
- case JAVATYPE_MESSAGE: return true;
-
- // No default because we want the compiler to complain if any new
- // JavaTypes are added.
- }
-
- GOOGLE_LOG(FATAL) << "Can't get here.";
- return false;
-}
-
-const char* GetCapitalizedType(const FieldDescriptor* field) {
- switch (GetType(field)) {
- 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_BOOL : return "Bool" ;
- case FieldDescriptor::TYPE_STRING : return "String" ;
- case FieldDescriptor::TYPE_BYTES : return "Bytes" ;
- case FieldDescriptor::TYPE_ENUM : return "Enum" ;
- case FieldDescriptor::TYPE_GROUP : return "Group" ;
- case FieldDescriptor::TYPE_MESSAGE : return "Message" ;
-
- // No default because we want the compiler to complain if any new
- // types are added.
- }
-
- GOOGLE_LOG(FATAL) << "Can't get here.";
- return NULL;
-}
-
-// For encodings with fixed sizes, returns that size in bytes. Otherwise
-// returns -1.
-int FixedSize(FieldDescriptor::Type type) {
- switch (type) {
- case FieldDescriptor::TYPE_INT32 : return -1;
- case FieldDescriptor::TYPE_INT64 : return -1;
- case FieldDescriptor::TYPE_UINT32 : return -1;
- case FieldDescriptor::TYPE_UINT64 : return -1;
- case FieldDescriptor::TYPE_SINT32 : return -1;
- case FieldDescriptor::TYPE_SINT64 : return -1;
- case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
- case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
- case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
- case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
- case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize;
- case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize;
-
- case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize;
- case FieldDescriptor::TYPE_ENUM : return -1;
-
- case FieldDescriptor::TYPE_STRING : return -1;
- case FieldDescriptor::TYPE_BYTES : return -1;
- case FieldDescriptor::TYPE_GROUP : return -1;
- case FieldDescriptor::TYPE_MESSAGE : return -1;
-
- // No default because we want the compiler to complain if any new
- // types are added.
- }
- GOOGLE_LOG(FATAL) << "Can't get here.";
- return -1;
-}
-
void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ const FieldGeneratorInfo* info,
+ ClassNameResolver* name_resolver,
map<string, string>* variables) {
- (*variables)["name"] =
- UnderscoresToCamelCase(descriptor);
- (*variables)["capitalized_name"] =
- UnderscoresToCapitalizedCamelCase(descriptor);
- (*variables)["number"] = SimpleItoa(descriptor->number());
+ SetCommonFieldVariables(descriptor, info, variables);
+
(*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
(*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
- (*variables)["default"] = DefaultValue(descriptor);
- (*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
+ (*variables)["field_type"] = (*variables)["type"];
+ (*variables)["field_list_type"] = "java.util.List<" +
+ (*variables)["boxed_type"] + ">";
+ (*variables)["empty_list"] = "java.util.Collections.emptyList()";
+ (*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)));
@@ -175,129 +105,517 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
} else {
(*variables)["null_check"] = "";
}
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] = descriptor->options().deprecated()
+ ? "@java.lang.Deprecated " : "";
int fixed_size = FixedSize(GetType(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.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+
+ // Note that these have a trailing ";".
+ (*variables)["set_has_field_bit_message"] =
+ GenerateSetBit(messageBitIndex) + ";";
+ (*variables)["set_has_field_bit_builder"] =
+ GenerateSetBit(builderBitIndex) + ";";
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex) + ";";
+
+ (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+ } else {
+ (*variables)["set_has_field_bit_message"] = "";
+ (*variables)["set_has_field_bit_builder"] = "";
+ (*variables)["clear_has_field_bit_builder"] = "";
+
+ if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
+ (*variables)["is_field_present_message"] =
+ "!" + (*variables)["name"] + "_.isEmpty()";
+ } else {
+ (*variables)["is_field_present_message"] =
+ (*variables)["name"] + "_ != " + (*variables)["default"];
+ }
+ }
+
+ // For repated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ // For repeated fields, one bit is used for whether the array is immutable
+ // in the parsing constructor.
+ (*variables)["get_mutable_bit_parser"] =
+ GenerateGetBitMutableLocal(builderBitIndex);
+ (*variables)["set_mutable_bit_parser"] =
+ GenerateSetBitMutableLocal(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
}
+
} // namespace
// ===================================================================
-PrimitiveFieldGenerator::
-PrimitiveFieldGenerator(const FieldDescriptor* descriptor)
- : descriptor_(descriptor) {
- SetPrimitiveVariables(descriptor, &variables_);
+ImmutablePrimitiveFieldGenerator::
+ImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex), context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
}
-PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
+ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() {}
+
+int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
+ return 1;
+}
+
+int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
-void PrimitiveFieldGenerator::
+void ImmutablePrimitiveFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n");
+ }
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$$type$ get$capitalized_name$();\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private boolean has$capitalized_name$;\n"
- "private $type$ $name$_ = $default$;\n"
- "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
- "public $type$ get$capitalized_name$() { return $name$_; }\n");
+ "private $field_type$ $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ }
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n");
}
-void PrimitiveFieldGenerator::
+void ImmutablePrimitiveFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
- "public boolean has$capitalized_name$() {\n"
- " return result.has$capitalized_name$();\n"
- "}\n"
- "public $type$ get$capitalized_name$() {\n"
- " return result.get$capitalized_name$();\n"
- "}\n"
- "public Builder set$capitalized_name$($type$ value) {\n"
+ "private $field_type$ $name$_ $default_init$;\n");
+
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+ }
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
"$null_check$"
- " result.has$capitalized_name$ = true;\n"
- " result.$name$_ = value;\n"
+ " $set_has_field_bit_builder$\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
" return this;\n"
- "}\n"
- "public Builder clear$capitalized_name$() {\n"
- " result.has$capitalized_name$ = false;\n");
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $clear_has_field_bit_builder$\n");
JavaType type = GetJavaType(descriptor_);
if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
// The default value is not a simple literal so we want to avoid executing
// it multiple times. Instead, get the default out of the default instance.
printer->Print(variables_,
- " result.$name$_ = getDefaultInstance().get$capitalized_name$();\n");
+ " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
} else {
printer->Print(variables_,
- " result.$name$_ = $default$;\n");
+ " $name$_ = $default$;\n");
}
printer->Print(variables_,
+ " $on_changed$\n"
" return this;\n"
"}\n");
}
-void PrimitiveFieldGenerator::
+void ImmutablePrimitiveFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void ImmutablePrimitiveFieldGenerator::
GenerateInitializationCode(io::Printer* printer) const {
- // Initialized inline.
+ printer->Print(variables_, "$name$_ = $default$;\n");
}
-void PrimitiveFieldGenerator::
-GenerateMergingCode(io::Printer* printer) const {
+void ImmutablePrimitiveFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (other.has$capitalized_name$()) {\n"
- " set$capitalized_name$(other.get$capitalized_name$());\n"
- "}\n");
+ "$name$_ = $default$;\n"
+ "$clear_has_field_bit_builder$\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateMergingCode(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");
+ } else {
+ printer->Print(variables_,
+ "if (other.get$capitalized_name$() != $default$) {\n"
+ " set$capitalized_name$(other.get$capitalized_name$());\n"
+ "}\n");
+ }
}
-void PrimitiveFieldGenerator::
+void ImmutablePrimitiveFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const {
- // Nothing to do here for primitive types.
+ if (SupportFieldPresence(descriptor_->file())) {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n");
+ }
+ printer->Print(variables_,
+ "result.$name$_ = $name$_;\n");
}
-void PrimitiveFieldGenerator::
+void ImmutablePrimitiveFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
- "set$capitalized_name$(input.read$capitalized_type$());\n");
+ "$set_has_field_bit_message$\n"
+ "$name$_ = input.read$capitalized_type$();\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+ // noop for primitives.
}
-void PrimitiveFieldGenerator::
+void ImmutablePrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (has$capitalized_name$()) {\n"
- " output.write$capitalized_type$($number$, get$capitalized_name$());\n"
+ "if ($is_field_present_message$) {\n"
+ " output.write$capitalized_type$($number$, $name$_);\n"
"}\n");
}
-void PrimitiveFieldGenerator::
+void ImmutablePrimitiveFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (has$capitalized_name$()) {\n"
+ "if ($is_field_present_message$) {\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .compute$capitalized_type$Size($number$, get$capitalized_name$());\n"
+ " .compute$capitalized_type$Size($number$, $name$_);\n"
"}\n");
}
-string PrimitiveFieldGenerator::GetBoxedType() const {
+void ImmutablePrimitiveFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ switch (GetJavaType(descriptor_)) {
+ case JAVATYPE_INT:
+ case JAVATYPE_LONG:
+ case JAVATYPE_BOOLEAN:
+ printer->Print(variables_,
+ "result = result && (get$capitalized_name$()\n"
+ " == other.get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_FLOAT:
+ printer->Print(variables_,
+ "result = result && (\n"
+ " java.lang.Float.floatToIntBits(get$capitalized_name$())\n"
+ " == java.lang.Float.floatToIntBits(\n"
+ " other.get$capitalized_name$()));\n");
+ break;
+
+ case JAVATYPE_DOUBLE:
+ printer->Print(variables_,
+ "result = result && (\n"
+ " java.lang.Double.doubleToLongBits(get$capitalized_name$())\n"
+ " == java.lang.Double.doubleToLongBits(\n"
+ " other.get$capitalized_name$()));\n");
+ break;
+
+ case JAVATYPE_STRING:
+ case JAVATYPE_BYTES:
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$()\n"
+ " .equals(other.get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_ENUM:
+ case JAVATYPE_MESSAGE:
+ default:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ break;
+ }
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n");
+ switch (GetJavaType(descriptor_)) {
+ case JAVATYPE_INT:
+ printer->Print(variables_,
+ "hash = (53 * hash) + get$capitalized_name$();\n");
+ break;
+
+ case JAVATYPE_LONG:
+ printer->Print(variables_,
+ "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
+ " get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_BOOLEAN:
+ printer->Print(variables_,
+ "hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(\n"
+ " get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_FLOAT:
+ printer->Print(variables_,
+ "hash = (53 * hash) + java.lang.Float.floatToIntBits(\n"
+ " get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_DOUBLE:
+ printer->Print(variables_,
+ "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
+ " java.lang.Double.doubleToLongBits(get$capitalized_name$()));\n");
+ break;
+
+ case JAVATYPE_STRING:
+ case JAVATYPE_BYTES:
+ printer->Print(variables_,
+ "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+ break;
+
+ case JAVATYPE_ENUM:
+ case JAVATYPE_MESSAGE:
+ default:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ break;
+ }
+}
+
+string ImmutablePrimitiveFieldGenerator::GetBoxedType() const {
return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
}
// ===================================================================
-RepeatedPrimitiveFieldGenerator::
-RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor)
- : descriptor_(descriptor) {
- SetPrimitiveVariables(descriptor, &variables_);
+ImmutablePrimitiveOneofFieldGenerator::
+ImmutablePrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : ImmutablePrimitiveFieldGenerator(
+ descriptor, messageBitIndex, builderBitIndex, context) {
+ const OneofGeneratorInfo* info =
+ context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+ SetCommonOneofVariables(descriptor, info, &variables_);
}
-RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
+ImmutablePrimitiveOneofFieldGenerator::
+~ImmutablePrimitiveOneofFieldGenerator() {}
-void RepeatedPrimitiveFieldGenerator::
+void ImmutablePrimitiveOneofFieldGenerator::
GenerateMembers(io::Printer* printer) const {
+ PrintExtraFieldInfo(variables_, printer);
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ }
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($boxed_type$) $oneof_name$_;\n"
+ " }\n"
+ " return $default$;\n"
+ "}\n");
+}
+
+
+void ImmutablePrimitiveOneofFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ }
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($boxed_type$) $oneof_name$_;\n"
+ " }\n"
+ " return $default$;\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
- "private java.util.List<$boxed_type$> $name$_ =\n"
- " java.util.Collections.emptyList();\n"
- "public java.util.List<$boxed_type$> get$capitalized_name$List() {\n"
+ "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
+ "$null_check$"
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ " $on_changed$\n"
+ " }\n"
+ " return this;\n"
+ "}\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " result.$oneof_name$_ = $oneof_name$_;\n"
+ "}\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "set$capitalized_name$(other.get$capitalized_name$());\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$set_oneof_case_message$;\n"
+ "$oneof_name$_ = input.read$capitalized_type$();\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " output.write$capitalized_type$(\n"
+ " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"
+ "}\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .compute$capitalized_type$Size(\n"
+ " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"
+ "}\n");
+}
+
+// ===================================================================
+
+RepeatedImmutablePrimitiveFieldGenerator::
+RepeatedImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex), context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+RepeatedImmutablePrimitiveFieldGenerator::
+~RepeatedImmutablePrimitiveFieldGenerator() {}
+
+int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$java.util.List<$boxed_type$> get$capitalized_name$List();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$$type$ get$capitalized_name$(int index);\n");
+}
+
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private $field_list_type$ $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<$boxed_type$>\n"
+ " get$capitalized_name$List() {\n"
" return $name$_;\n" // note: unmodifiable list
- "}\n"
- "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
- "public $type$ get$capitalized_name$(int index) {\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
" return $name$_.get(index);\n"
"}\n");
@@ -308,92 +626,170 @@ GenerateMembers(io::Printer* printer) const {
}
}
-void RepeatedPrimitiveFieldGenerator::
+void RepeatedImmutablePrimitiveFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
+ // One field is the list and the bit field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a refererence to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ printer->Print(variables_,
+ "private $field_list_type$ $name$_ = $empty_list$;\n");
+
printer->Print(variables_,
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new java.util.ArrayList<$boxed_type$>($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n");
+
// Note: We return an unmodifiable list because otherwise the caller
// could hold on to the returned list and modify it after the message
// has been built, thus mutating the message which is supposed to be
// immutable.
- "public java.util.List<$boxed_type$> get$capitalized_name$List() {\n"
- " return java.util.Collections.unmodifiableList(result.$name$_);\n"
- "}\n"
- "public int get$capitalized_name$Count() {\n"
- " return result.get$capitalized_name$Count();\n"
- "}\n"
- "public $type$ get$capitalized_name$(int index) {\n"
- " return result.get$capitalized_name$(index);\n"
- "}\n"
- "public Builder set$capitalized_name$(int index, $type$ value) {\n"
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<$boxed_type$>\n"
+ " get$capitalized_name$List() {\n"
+ " return java.util.Collections.unmodifiableList($name$_);\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$ value) {\n"
"$null_check$"
- " result.$name$_.set(index, value);\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value);\n"
+ " $on_changed$\n"
" return this;\n"
- "}\n"
- "public Builder add$capitalized_name$($type$ value) {\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
"$null_check$"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n"
- " }\n"
- " result.$name$_.add(value);\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
" return this;\n"
- "}\n"
- "public Builder addAll$capitalized_name$(\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder addAll$capitalized_name$(\n"
" java.lang.Iterable<? extends $boxed_type$> values) {\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n"
- " }\n"
- " super.addAll(values, result.$name$_);\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
+ " values, $name$_);\n"
+ " $on_changed$\n"
" return this;\n"
- "}\n"
- "public Builder clear$capitalized_name$() {\n"
- " result.$name$_ = java.util.Collections.emptyList();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $name$_ = $empty_list$;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $on_changed$\n"
" return this;\n"
"}\n");
}
-void RepeatedPrimitiveFieldGenerator::
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
GenerateInitializationCode(io::Printer* printer) const {
- // Initialized inline.
+ printer->Print(variables_, "$name$_ = $empty_list$;\n");
}
-void RepeatedPrimitiveFieldGenerator::
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $empty_list$;\n"
+ "$clear_mutable_bit_builder$;\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
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 (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
" }\n"
- " result.$name$_.addAll(other.$name$_);\n"
+ " $on_changed$\n"
"}\n");
}
-void RepeatedPrimitiveFieldGenerator::
+void RepeatedImmutablePrimitiveFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const {
+ // The code below ensures that the result has an immutable list. If our
+ // list is immutable, we can just reuse it. If not, we make it immutable.
printer->Print(variables_,
- "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n"
- " result.$name$_ =\n"
- " java.util.Collections.unmodifiableList(result.$name$_);\n"
- "}\n");
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
}
-void RepeatedPrimitiveFieldGenerator::
+void RepeatedImmutablePrimitiveFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
- "add$capitalized_name$(input.read$capitalized_type$());\n");
+ "if (!$get_mutable_bit_parser$) {\n"
+ " $name$_ = new java.util.ArrayList<$boxed_type$>();\n"
+ " $set_mutable_bit_parser$;\n"
+ "}\n"
+ "$name$_.add(input.read$capitalized_type$());\n");
}
-void RepeatedPrimitiveFieldGenerator::
+void RepeatedImmutablePrimitiveFieldGenerator::
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 java.util.ArrayList<$boxed_type$>();\n"
+ " $set_mutable_bit_parser$;\n"
+ "}\n"
"while (input.getBytesUntilLimit() > 0) {\n"
- " add$capitalized_name$(input.read$capitalized_type$());\n"
+ " $name$_.add(input.read$capitalized_type$());\n"
"}\n"
"input.popLimit(limit);\n");
}
-void RepeatedPrimitiveFieldGenerator::
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_mutable_bit_parser$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ "}\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
if (descriptor_->options().packed()) {
printer->Print(variables_,
@@ -401,18 +797,18 @@ GenerateSerializationCode(io::Printer* printer) const {
" output.writeRawVarint32($tag$);\n"
" output.writeRawVarint32($name$MemoizedSerializedSize);\n"
"}\n"
- "for ($type$ element : get$capitalized_name$List()) {\n"
- " output.write$capitalized_type$NoTag(element);\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$capitalized_type$NoTag($name$_.get(i));\n"
"}\n");
} else {
printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
- " output.write$capitalized_type$($number$, element);\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$capitalized_type$($number$, $name$_.get(i));\n"
"}\n");
}
}
-void RepeatedPrimitiveFieldGenerator::
+void RepeatedImmutablePrimitiveFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
"{\n"
@@ -421,9 +817,9 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
if (FixedSize(GetType(descriptor_)) == -1) {
printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
" dataSize += com.google.protobuf.CodedOutputStream\n"
- " .compute$capitalized_type$SizeNoTag(element);\n"
+ " .compute$capitalized_type$SizeNoTag($name$_.get(i));\n"
"}\n");
} else {
printer->Print(variables_,
@@ -455,7 +851,23 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print("}\n");
}
-string RepeatedPrimitiveFieldGenerator::GetBoxedType() const {
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
+ "}\n");
+}
+
+string RepeatedImmutablePrimitiveFieldGenerator::GetBoxedType() const {
return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
}
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.h b/src/google/protobuf/compiler/java/java_primitive_field.h
index 4e482a0..d0cd12d 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.h
+++ b/src/google/protobuf/compiler/java/java_primitive_field.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -41,56 +41,115 @@
namespace google {
namespace protobuf {
+ namespace compiler {
+ namespace java {
+ class Context; // context.h
+ class ClassNameResolver; // name_resolver.h
+ }
+ }
+}
+
+namespace protobuf {
namespace compiler {
namespace java {
-class PrimitiveFieldGenerator : public FieldGenerator {
+class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator {
public:
- explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor);
- ~PrimitiveFieldGenerator();
-
- // implements FieldGenerator ---------------------------------------
+ explicit ImmutablePrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~ImmutablePrimitiveFieldGenerator();
+
+ // implements ImmutableFieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
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 GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
string GetBoxedType() const;
- private:
+ protected:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveFieldGenerator);
};
-class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
+class ImmutablePrimitiveOneofFieldGenerator
+ : public ImmutablePrimitiveFieldGenerator {
public:
- explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor);
- ~RepeatedPrimitiveFieldGenerator();
+ ImmutablePrimitiveOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~ImmutablePrimitiveOneofFieldGenerator();
- // implements FieldGenerator ---------------------------------------
+ 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 GenerateParsingCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveOneofFieldGenerator);
+};
+
+class RepeatedImmutablePrimitiveFieldGenerator
+ : public ImmutableFieldGenerator {
+ public:
+ explicit RepeatedImmutablePrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ virtual ~RepeatedImmutablePrimitiveFieldGenerator();
+
+ // implements ImmutableFieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
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 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;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
string GetBoxedType() const;
private:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutablePrimitiveFieldGenerator);
};
} // namespace java
diff --git a/src/google/protobuf/compiler/java/java_service.cc b/src/google/protobuf/compiler/java/java_service.cc
index 5545bf7..7baead1 100644
--- a/src/google/protobuf/compiler/java/java_service.cc
+++ b/src/google/protobuf/compiler/java/java_service.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,7 +33,11 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/java/java_service.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/descriptor.pb.h>
#include <google/protobuf/stubs/strutil.h>
@@ -48,8 +52,18 @@ ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor)
ServiceGenerator::~ServiceGenerator() {}
-void ServiceGenerator::Generate(io::Printer* printer) {
- bool is_own_file = descriptor_->file()->options().java_multiple_files();
+// ===================================================================
+ImmutableServiceGenerator::ImmutableServiceGenerator(
+ const ServiceDescriptor* descriptor, Context* context)
+ : ServiceGenerator(descriptor), context_(context),
+ name_resolver_(context->GetNameResolver()) {}
+
+ImmutableServiceGenerator::~ImmutableServiceGenerator() {}
+
+void ImmutableServiceGenerator::Generate(io::Printer* printer) {
+ bool is_own_file =
+ MultipleJavaFiles(descriptor_->file(), /* immutable = */ true);
+ WriteServiceDocComment(printer, descriptor_);
printer->Print(
"public $static$ abstract class $classname$\n"
" implements com.google.protobuf.Service {\n",
@@ -75,7 +89,7 @@ void ServiceGenerator::Generate(io::Printer* printer) {
" getDescriptor() {\n"
" return $file$.getDescriptor().getServices().get($index$);\n"
"}\n",
- "file", ClassName(descriptor_->file()),
+ "file", name_resolver_->GetImmutableClassName(descriptor_->file()),
"index", SimpleItoa(descriptor_->index()));
GenerateGetDescriptorForType(printer);
@@ -86,11 +100,18 @@ void ServiceGenerator::Generate(io::Printer* printer) {
GenerateStub(printer);
GenerateBlockingStub(printer);
+ // Add an insertion point.
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(class_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
printer->Outdent();
printer->Print("}\n\n");
}
-void ServiceGenerator::GenerateGetDescriptorForType(io::Printer* printer) {
+void ImmutableServiceGenerator::GenerateGetDescriptorForType(
+ io::Printer* printer) {
printer->Print(
"public final com.google.protobuf.Descriptors.ServiceDescriptor\n"
" getDescriptorForType() {\n"
@@ -98,7 +119,7 @@ void ServiceGenerator::GenerateGetDescriptorForType(io::Printer* printer) {
"}\n");
}
-void ServiceGenerator::GenerateInterface(io::Printer* printer) {
+void ImmutableServiceGenerator::GenerateInterface(io::Printer* printer) {
printer->Print("public interface Interface {\n");
printer->Indent();
GenerateAbstractMethods(printer);
@@ -106,7 +127,7 @@ void ServiceGenerator::GenerateInterface(io::Printer* printer) {
printer->Print("}\n\n");
}
-void ServiceGenerator::GenerateNewReflectiveServiceMethod(
+void ImmutableServiceGenerator::GenerateNewReflectiveServiceMethod(
io::Printer* printer) {
printer->Print(
"public static com.google.protobuf.Service newReflectiveService(\n"
@@ -118,7 +139,7 @@ void ServiceGenerator::GenerateNewReflectiveServiceMethod(
for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor* method = descriptor_->method(i);
- printer->Print("@Override\n");
+ printer->Print("@java.lang.Override\n");
GenerateMethodSignature(printer, method, IS_CONCRETE);
printer->Print(
" {\n"
@@ -133,7 +154,7 @@ void ServiceGenerator::GenerateNewReflectiveServiceMethod(
printer->Print("}\n\n");
}
-void ServiceGenerator::GenerateNewReflectiveBlockingServiceMethod(
+void ImmutableServiceGenerator::GenerateNewReflectiveBlockingServiceMethod(
io::Printer* printer) {
printer->Print(
"public static com.google.protobuf.BlockingService\n"
@@ -154,15 +175,16 @@ void ServiceGenerator::GenerateNewReflectiveBlockingServiceMethod(
printer->Print("}\n\n");
}
-void ServiceGenerator::GenerateAbstractMethods(io::Printer* printer) {
+void ImmutableServiceGenerator::GenerateAbstractMethods(io::Printer* printer) {
for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor* method = descriptor_->method(i);
+ WriteMethodDocComment(printer, method);
GenerateMethodSignature(printer, method, IS_ABSTRACT);
printer->Print(";\n\n");
}
}
-void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
+void ImmutableServiceGenerator::GenerateCallMethod(io::Printer* printer) {
printer->Print(
"\n"
"public final void callMethod(\n"
@@ -185,8 +207,10 @@ void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
map<string, string> vars;
vars["index"] = SimpleItoa(i);
vars["method"] = UnderscoresToCamelCase(method);
- vars["input"] = ClassName(method->input_type());
- vars["output"] = ClassName(method->output_type());
+ vars["input"] = name_resolver_->GetImmutableClassName(
+ method->input_type());
+ vars["output"] = name_resolver_->GetImmutableClassName(
+ method->output_type());
printer->Print(vars,
"case $index$:\n"
" this.$method$(controller, ($input$)request,\n"
@@ -208,7 +232,8 @@ void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
"\n");
}
-void ServiceGenerator::GenerateCallBlockingMethod(io::Printer* printer) {
+void ImmutableServiceGenerator::GenerateCallBlockingMethod(
+ io::Printer* printer) {
printer->Print(
"\n"
"public final com.google.protobuf.Message callBlockingMethod(\n"
@@ -230,8 +255,10 @@ void ServiceGenerator::GenerateCallBlockingMethod(io::Printer* printer) {
map<string, string> vars;
vars["index"] = SimpleItoa(i);
vars["method"] = UnderscoresToCamelCase(method);
- vars["input"] = ClassName(method->input_type());
- vars["output"] = ClassName(method->output_type());
+ vars["input"] = name_resolver_->GetImmutableClassName(
+ method->input_type());
+ vars["output"] = name_resolver_->GetImmutableClassName(
+ method->output_type());
printer->Print(vars,
"case $index$:\n"
" return impl.$method$(controller, ($input$)request);\n");
@@ -250,7 +277,7 @@ void ServiceGenerator::GenerateCallBlockingMethod(io::Printer* printer) {
"\n");
}
-void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
+void ImmutableServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
io::Printer* printer) {
/*
* TODO(cpovirk): The exception message says "Service.foo" when it may be
@@ -274,7 +301,7 @@ void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
const MethodDescriptor* method = descriptor_->method(i);
map<string, string> vars;
vars["index"] = SimpleItoa(i);
- vars["type"] = ClassName(
+ vars["type"] = name_resolver_->GetImmutableClassName(
(which == REQUEST) ? method->input_type() : method->output_type());
printer->Print(vars,
"case $index$:\n"
@@ -294,7 +321,7 @@ void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
"\n");
}
-void ServiceGenerator::GenerateStub(io::Printer* printer) {
+void ImmutableServiceGenerator::GenerateStub(io::Printer* printer) {
printer->Print(
"public static Stub newStub(\n"
" com.google.protobuf.RpcChannel channel) {\n"
@@ -303,7 +330,7 @@ void ServiceGenerator::GenerateStub(io::Printer* printer) {
"\n"
"public static final class Stub extends $classname$ implements Interface {"
"\n",
- "classname", ClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
printer->Indent();
printer->Print(
@@ -326,7 +353,8 @@ void ServiceGenerator::GenerateStub(io::Printer* printer) {
map<string, string> vars;
vars["index"] = SimpleItoa(i);
- vars["output"] = ClassName(method->output_type());
+ vars["output"] = name_resolver_->GetImmutableClassName(
+ method->output_type());
printer->Print(vars,
"channel.callMethod(\n"
" getDescriptor().getMethods().get($index$),\n"
@@ -348,7 +376,7 @@ void ServiceGenerator::GenerateStub(io::Printer* printer) {
"\n");
}
-void ServiceGenerator::GenerateBlockingStub(io::Printer* printer) {
+void ImmutableServiceGenerator::GenerateBlockingStub(io::Printer* printer) {
printer->Print(
"public static BlockingInterface newBlockingStub(\n"
" com.google.protobuf.BlockingRpcChannel channel) {\n"
@@ -390,7 +418,8 @@ void ServiceGenerator::GenerateBlockingStub(io::Printer* printer) {
map<string, string> vars;
vars["index"] = SimpleItoa(i);
- vars["output"] = ClassName(method->output_type());
+ vars["output"] = name_resolver_->GetImmutableClassName(
+ method->output_type());
printer->Print(vars,
"return ($output$) channel.callBlockingMethod(\n"
" getDescriptor().getMethods().get($index$),\n"
@@ -408,13 +437,13 @@ void ServiceGenerator::GenerateBlockingStub(io::Printer* printer) {
printer->Print("}\n");
}
-void ServiceGenerator::GenerateMethodSignature(io::Printer* printer,
+void ImmutableServiceGenerator::GenerateMethodSignature(io::Printer* printer,
const MethodDescriptor* method,
IsAbstract is_abstract) {
map<string, string> vars;
vars["name"] = UnderscoresToCamelCase(method);
- vars["input"] = ClassName(method->input_type());
- vars["output"] = ClassName(method->output_type());
+ vars["input"] = name_resolver_->GetImmutableClassName(method->input_type());
+ vars["output"] = name_resolver_->GetImmutableClassName(method->output_type());
vars["abstract"] = (is_abstract == IS_ABSTRACT) ? "abstract" : "";
printer->Print(vars,
"public $abstract$ void $name$(\n"
@@ -423,13 +452,13 @@ void ServiceGenerator::GenerateMethodSignature(io::Printer* printer,
" com.google.protobuf.RpcCallback<$output$> done)");
}
-void ServiceGenerator::GenerateBlockingMethodSignature(
+void ImmutableServiceGenerator::GenerateBlockingMethodSignature(
io::Printer* printer,
const MethodDescriptor* method) {
map<string, string> vars;
vars["method"] = UnderscoresToCamelCase(method);
- vars["input"] = ClassName(method->input_type());
- vars["output"] = ClassName(method->output_type());
+ vars["input"] = name_resolver_->GetImmutableClassName(method->input_type());
+ vars["output"] = name_resolver_->GetImmutableClassName(method->output_type());
printer->Print(vars,
"\n"
"public $output$ $method$(\n"
diff --git a/src/google/protobuf/compiler/java/java_service.h b/src/google/protobuf/compiler/java/java_service.h
index e07eebf..6707e82 100644
--- a/src/google/protobuf/compiler/java/java_service.h
+++ b/src/google/protobuf/compiler/java/java_service.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -40,8 +40,14 @@
namespace google {
namespace protobuf {
+ namespace compiler {
+ namespace java {
+ class Context; // context.h
+ class ClassNameResolver; // name_resolver.h
+ }
+ }
namespace io {
- class Printer; // printer.h
+ class Printer; // printer.h
}
}
@@ -52,9 +58,27 @@ namespace java {
class ServiceGenerator {
public:
explicit ServiceGenerator(const ServiceDescriptor* descriptor);
- ~ServiceGenerator();
+ virtual ~ServiceGenerator();
+
+ virtual void Generate(io::Printer* printer) = 0;
+
+ enum RequestOrResponse { REQUEST, RESPONSE };
+ enum IsAbstract { IS_ABSTRACT, IS_CONCRETE };
+
+ protected:
+ const ServiceDescriptor* descriptor_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator);
+};
- void Generate(io::Printer* printer);
+class ImmutableServiceGenerator : public ServiceGenerator {
+ public:
+ explicit ImmutableServiceGenerator(const ServiceDescriptor* descriptor,
+ Context* context);
+ virtual ~ImmutableServiceGenerator();
+
+ virtual void Generate(io::Printer* printer);
private:
@@ -80,7 +104,6 @@ class ServiceGenerator {
void GenerateCallBlockingMethod(io::Printer* printer);
// Generate the implementations of Service.get{Request,Response}Prototype().
- enum RequestOrResponse { REQUEST, RESPONSE };
void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer);
// Generate a stub implementation of the service.
@@ -88,7 +111,6 @@ class ServiceGenerator {
// Generate a method signature, possibly abstract, without body or trailing
// semicolon.
- enum IsAbstract { IS_ABSTRACT, IS_CONCRETE };
void GenerateMethodSignature(io::Printer* printer,
const MethodDescriptor* method,
IsAbstract is_abstract);
@@ -100,9 +122,9 @@ class ServiceGenerator {
void GenerateBlockingMethodSignature(io::Printer* printer,
const MethodDescriptor* method);
- const ServiceDescriptor* descriptor_;
-
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator);
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableServiceGenerator);
};
} // namespace java
diff --git a/src/google/protobuf/compiler/java/java_shared_code_generator.cc b/src/google/protobuf/compiler/java/java_shared_code_generator.cc
new file mode 100644
index 0000000..ea77f79
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_shared_code_generator.cc
@@ -0,0 +1,201 @@
+// 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: xiaofeng@google.com (Feng Xiao)
+
+#include <google/protobuf/compiler/java/java_shared_code_generator.h>
+
+#include <memory>
+
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+#include <google/protobuf/compiler/code_generator.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 java {
+
+SharedCodeGenerator::SharedCodeGenerator(const FileDescriptor* file)
+ : name_resolver_(new ClassNameResolver), file_(file) {
+}
+
+SharedCodeGenerator::~SharedCodeGenerator() {
+}
+
+void SharedCodeGenerator::Generate(GeneratorContext* context,
+ vector<string>* file_list) {
+ string java_package = FileJavaPackage(file_);
+ string package_dir = JavaPackageToDir(java_package);
+
+ if (HasDescriptorMethods(file_)) {
+ // Generate descriptors.
+ string classname = name_resolver_->GetDescriptorClassName(file_);
+ string filename = package_dir + classname + ".java";
+ file_list->push_back(filename);
+ scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+ scoped_ptr<io::Printer> printer(new io::Printer(output.get(), '$'));
+
+ printer->Print(
+ "// 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);
+ }
+ printer->Print(
+ "public final class $classname$ {\n"
+ " public static com.google.protobuf.Descriptors.FileDescriptor\n"
+ " descriptor;\n"
+ " static {\n",
+ "classname", classname);
+ printer->Indent();
+ printer->Indent();
+ GenerateDescriptors(printer.get());
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " }\n"
+ "}\n");
+
+ printer.reset();
+ output.reset();
+ }
+}
+
+
+void SharedCodeGenerator::GenerateDescriptors(io::Printer* printer) {
+ // 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. We unfortunately have to put it in
+ // a string literal, not a byte array, because apparently using a literal
+ // byte array causes the Java compiler to generate *instructions* to
+ // initialize each and every byte of the array, e.g. as if you typed:
+ // b[0] = 123; b[1] = 456; b[2] = 789;
+ // This makes huge bytecode files and can easily hit the compiler's internal
+ // code size limits (error "code to large"). String literals are apparently
+ // embedded raw, which is what we want.
+ FileDescriptorProto file_proto;
+ file_->CopyTo(&file_proto);
+
+
+ string file_data;
+ file_proto.SerializeToString(&file_data);
+
+ printer->Print(
+ "java.lang.String[] descriptorData = {\n");
+ printer->Indent();
+
+ // Only write 40 bytes per line.
+ static const int kBytesPerLine = 40;
+ for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
+ if (i > 0) {
+ // Every 400 lines, start a new string literal, in order to avoid the
+ // 64k length limit.
+ if (i % 400 == 0) {
+ printer->Print(",\n");
+ } else {
+ printer->Print(" +\n");
+ }
+ }
+ printer->Print("\"$data$\"",
+ "data", CEscape(file_data.substr(i, kBytesPerLine)));
+ }
+
+ printer->Outdent();
+ printer->Print("\n};\n");
+
+ // -----------------------------------------------------------------
+ // Create the InternalDescriptorAssigner.
+
+ printer->Print(
+ "com.google.protobuf.Descriptors.FileDescriptor."
+ "InternalDescriptorAssigner assigner =\n"
+ " new com.google.protobuf.Descriptors.FileDescriptor."
+ " InternalDescriptorAssigner() {\n"
+ " public com.google.protobuf.ExtensionRegistry assignDescriptors(\n"
+ " com.google.protobuf.Descriptors.FileDescriptor root) {\n"
+ " descriptor = root;\n"
+ // Custom options will be handled when immutable messages' outer class is
+ // loaded. Here we just return null and let custom options be unknown
+ // fields.
+ " return null;\n"
+ " }\n"
+ " };\n");
+
+ // -----------------------------------------------------------------
+ // Find out all dependencies.
+ vector<pair<string, string> > dependencies;
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ if (ShouldIncludeDependency(file_->dependency(i))) {
+ string filename = file_->dependency(i)->name();
+ string classname = FileJavaPackage(file_->dependency(i)) + "." +
+ name_resolver_->GetDescriptorClassName(
+ file_->dependency(i));
+ dependencies.push_back(make_pair(filename, classname));
+ }
+ }
+
+ // -----------------------------------------------------------------
+ // Invoke internalBuildGeneratedFileFrom() to build the file.
+ printer->Print(
+ "com.google.protobuf.Descriptors.FileDescriptor\n"
+ " .internalBuildGeneratedFileFrom(descriptorData,\n"
+ " new com.google.protobuf.Descriptors.FileDescriptor[] {\n");
+
+ for (int i = 0; i < dependencies.size(); i++) {
+ const string& dependency = dependencies[i].second;
+ printer->Print(
+ " $dependency$.getDescriptor(),\n",
+ "dependency", dependency);
+ }
+
+ printer->Print(
+ " }, assigner);\n");
+}
+
+bool SharedCodeGenerator::ShouldIncludeDependency(
+ const FileDescriptor* descriptor) {
+ return true;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/java/java_shared_code_generator.h b/src/google/protobuf/compiler/java/java_shared_code_generator.h
new file mode 100644
index 0000000..1bb2f3d
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_shared_code_generator.h
@@ -0,0 +1,90 @@
+// 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: xiaofeng@google.com (Feng Xiao)
+//
+// Generators that generate shared code between immutable API and mutable API.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+ class FileDescriptor; // descriptor.h
+ namespace compiler {
+ class GeneratorContext; // code_generator.h
+ namespace java {
+ class ClassNameResolver; // name_resolver.h
+ }
+ }
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// A generator that generates code that are shared between immutable API
+// and mutable API. Currently only descriptors are shared.
+class SharedCodeGenerator {
+ public:
+ explicit SharedCodeGenerator(const FileDescriptor* file);
+ ~SharedCodeGenerator();
+
+ void Generate(GeneratorContext* generator_context,
+ vector<string>* file_list);
+ void GenerateDescriptors(io::Printer* printer);
+
+ private:
+ // Returns whether the dependency should be included in the output file.
+ // Always returns true for opensource, but used internally at Google to help
+ // improve compatibility with version 1 of protocol buffers.
+ bool ShouldIncludeDependency(const FileDescriptor* descriptor);
+
+ scoped_ptr<ClassNameResolver> name_resolver_;
+ const FileDescriptor* file_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SharedCodeGenerator);
+};
+
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__
diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc
new file mode 100644
index 0000000..8889a74
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_string_field.cc
@@ -0,0 +1,1056 @@
+// 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: kenton@google.com (Kenton Varda)
+// Author: jonp@google.com (Jon Perlow)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/stubs/common.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/compiler/java/java_string_field.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ const FieldGeneratorInfo* info,
+ ClassNameResolver* name_resolver,
+ map<string, string>* variables) {
+ SetCommonFieldVariables(descriptor, info, variables);
+
+ (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY";
+
+ (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
+ (*variables)["default_init"] =
+ "= " + ImmutableDefaultValue(descriptor, name_resolver);
+ (*variables)["capitalized_type"] = "String";
+ (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
+ (*variables)["tag_size"] = SimpleItoa(
+ WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+ (*variables)["null_check"] =
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n";
+
+ // 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();" : "";
+
+ if (SupportFieldPresence(descriptor->file())) {
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+
+ // Note that these have a trailing ";".
+ (*variables)["set_has_field_bit_message"] =
+ GenerateSetBit(messageBitIndex) + ";";
+ (*variables)["set_has_field_bit_builder"] =
+ GenerateSetBit(builderBitIndex) + ";";
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex) + ";";
+
+ (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+ } else {
+ (*variables)["set_has_field_bit_message"] = "";
+ (*variables)["set_has_field_bit_builder"] = "";
+ (*variables)["clear_has_field_bit_builder"] = "";
+
+ (*variables)["is_field_present_message"] =
+ "!get" + (*variables)["capitalized_name"] + "Bytes().isEmpty()";
+ }
+
+ // For repeated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ // For repeated fields, one bit is used for whether the array is immutable
+ // in the parsing constructor.
+ (*variables)["get_mutable_bit_parser"] =
+ GenerateGetBitMutableLocal(builderBitIndex);
+ (*variables)["set_mutable_bit_parser"] =
+ GenerateSetBitMutableLocal(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+}
+
+bool CheckUtf8(const FieldDescriptor* descriptor) {
+ return descriptor->file()->options().java_string_check_utf8();
+}
+
+} // namespace
+
+// ===================================================================
+
+ImmutableStringFieldGenerator::
+ImmutableStringFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex), context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+ImmutableStringFieldGenerator::~ImmutableStringFieldGenerator() {}
+
+int ImmutableStringFieldGenerator::GetNumBitsForMessage() const {
+ return 1;
+}
+
+int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+// A note about how strings are handled. This code used to just store a String
+// in the Message. This had two issues:
+//
+// 1. It wouldn't roundtrip byte arrays that were not vaid UTF-8 encoded
+// strings, but rather fields that were raw bytes incorrectly marked
+// as strings in the proto file. This is common because in the proto1
+// syntax, string was the way to indicate bytes and C++ engineers can
+// easily make this mistake without affecting the C++ API. By converting to
+// strings immediately, some java code might corrupt these byte arrays as
+// it passes through a java server even if the field was never accessed by
+// application code.
+//
+// 2. There's a performance hit to converting between bytes and strings and
+// it many cases, the field is never even read by the application code. This
+// avoids unnecessary conversions in the common use cases.
+//
+// So now, the field for String is maintained as an Object reference which can
+// either store a String or a ByteString. The code uses an instanceof check
+// to see which one it has and converts to the other one if needed. It remembers
+// the last value requested (in a thread safe manner) as this is most likely
+// the one needed next. The thread safety is such that if two threads both
+// convert the field because the changes made by each thread were not visible to
+// the other, they may cause a conversion to happen more times than would
+// otherwise be necessary. This was deemed better than adding synchronization
+// overhead. It will not cause any corruption issues or affect the behavior of
+// the API. The instanceof check is also highly optimized in the JVM and we
+// decided it was better to reduce the memory overhead by not having two
+// separate fields but rather use dynamic type checking.
+//
+// For single fields, the logic for this is done inside the generated code. For
+// repeated fields, the logic is done in LazyStringArrayList and
+// UnmodifiableLazyStringList.
+void ImmutableStringFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n");
+ }
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$java.lang.String get$capitalized_name$();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$com.google.protobuf.ByteString\n"
+ " get$capitalized_name$Bytes();\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private java.lang.Object $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ }
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.lang.String get$capitalized_name$() {\n"
+ " java.lang.Object ref = $name$_;\n"
+ " if (ref instanceof java.lang.String) {\n"
+ " return (java.lang.String) ref;\n"
+ " } else {\n"
+ " com.google.protobuf.ByteString bs = \n"
+ " (com.google.protobuf.ByteString) ref;\n"
+ " java.lang.String s = bs.toStringUtf8();\n");
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_,
+ " $name$_ = s;\n");
+ } else {
+ printer->Print(variables_,
+ " if (bs.isValidUtf8()) {\n"
+ " $name$_ = s;\n"
+ " }\n");
+ }
+ printer->Print(variables_,
+ " return s;\n"
+ " }\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " get$capitalized_name$Bytes() {\n"
+ " java.lang.Object ref = $name$_;\n"
+ " if (ref instanceof java.lang.String) {\n"
+ " com.google.protobuf.ByteString b = \n"
+ " com.google.protobuf.ByteString.copyFromUtf8(\n"
+ " (java.lang.String) ref);\n"
+ " $name$_ = b;\n"
+ " return b;\n"
+ " } else {\n"
+ " return (com.google.protobuf.ByteString) ref;\n"
+ " }\n"
+ "}\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private java.lang.Object $name$_ $default_init$;\n");
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+ }
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.lang.String get$capitalized_name$() {\n"
+ " java.lang.Object ref = $name$_;\n"
+ " if (!(ref instanceof java.lang.String)) {\n"
+ " com.google.protobuf.ByteString bs =\n"
+ " (com.google.protobuf.ByteString) ref;\n"
+ " java.lang.String s = bs.toStringUtf8();\n");
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_,
+ " $name$_ = s;\n");
+ } else {
+ printer->Print(variables_,
+ " if (bs.isValidUtf8()) {\n"
+ " $name$_ = s;\n"
+ " }\n");
+ }
+ printer->Print(variables_,
+ " return s;\n"
+ " } else {\n"
+ " return (java.lang.String) ref;\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " get$capitalized_name$Bytes() {\n"
+ " java.lang.Object ref = $name$_;\n"
+ " if (ref instanceof String) {\n"
+ " com.google.protobuf.ByteString b = \n"
+ " com.google.protobuf.ByteString.copyFromUtf8(\n"
+ " (java.lang.String) ref);\n"
+ " $name$_ = b;\n"
+ " return b;\n"
+ " } else {\n"
+ " return (com.google.protobuf.ByteString) ref;\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " java.lang.String value) {\n"
+ "$null_check$"
+ " $set_has_field_bit_builder$\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $clear_has_field_bit_builder$\n");
+ // The default value is not a simple literal so we want to avoid executing
+ // it multiple times. Instead, get the default out of the default instance.
+ printer->Print(variables_,
+ " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
+ printer->Print(variables_,
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$Bytes(\n"
+ " com.google.protobuf.ByteString value) {\n"
+ "$null_check$");
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_,
+ " checkByteStringIsUtf8(value);\n");
+ }
+ printer->Print(variables_,
+ " $set_has_field_bit_builder$\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void ImmutableStringFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $default$;\n"
+ "$clear_has_field_bit_builder$\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateMergingCode(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_builder$\n"
+ " $name$_ = other.$name$_;\n"
+ " $on_changed$\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "if (!other.get$capitalized_name$().isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $on_changed$\n"
+ "}\n");
+ }
+}
+
+void ImmutableStringFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ if (SupportFieldPresence(descriptor_->file())) {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n");
+ }
+ printer->Print(variables_,
+ "result.$name$_ = $name$_;\n");
+}
+
+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 {
+ printer->Print(variables_,
+ "com.google.protobuf.ByteString bs = input.readBytes();\n"
+ "$set_has_field_bit_message$\n"
+ "$name$_ = bs;\n");
+ }
+}
+
+void ImmutableStringFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+ // noop for strings.
+}
+
+void ImmutableStringFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($is_field_present_message$) {\n"
+ " output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+ "}\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($is_field_present_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+ "}\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$()\n"
+ " .equals(other.get$capitalized_name$());\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n");
+ printer->Print(variables_,
+ "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+}
+
+string ImmutableStringFieldGenerator::GetBoxedType() const {
+ return "java.lang.String";
+}
+
+// ===================================================================
+
+ImmutableStringOneofFieldGenerator::
+ImmutableStringOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : ImmutableStringFieldGenerator(
+ descriptor, messageBitIndex, builderBitIndex, context) {
+ const OneofGeneratorInfo* info =
+ context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+ SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutableStringOneofFieldGenerator::
+~ImmutableStringOneofFieldGenerator() {}
+
+void ImmutableStringOneofFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ PrintExtraFieldInfo(variables_, printer);
+
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ }
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.lang.String get$capitalized_name$() {\n"
+ " java.lang.Object ref $default_init$;\n"
+ " if ($has_oneof_case_message$) {\n"
+ " ref = $oneof_name$_;\n"
+ " }\n"
+ " if (ref instanceof java.lang.String) {\n"
+ " return (java.lang.String) ref;\n"
+ " } else {\n"
+ " com.google.protobuf.ByteString bs = \n"
+ " (com.google.protobuf.ByteString) ref;\n"
+ " java.lang.String s = bs.toStringUtf8();\n");
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_,
+ " if ($has_oneof_case_message$) {\n"
+ " $oneof_name$_ = s;\n"
+ " }\n");
+ } else {
+ printer->Print(variables_,
+ " if (bs.isValidUtf8() && ($has_oneof_case_message$)) {\n"
+ " $oneof_name$_ = s;\n"
+ " }\n");
+ }
+ printer->Print(variables_,
+ " return s;\n"
+ " }\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " get$capitalized_name$Bytes() {\n"
+ " java.lang.Object ref $default_init$;\n"
+ " if ($has_oneof_case_message$) {\n"
+ " ref = $oneof_name$_;\n"
+ " }\n"
+ " if (ref instanceof java.lang.String) {\n"
+ " com.google.protobuf.ByteString b = \n"
+ " com.google.protobuf.ByteString.copyFromUtf8(\n"
+ " (java.lang.String) ref);\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $oneof_name$_ = b;\n"
+ " }\n"
+ " return b;\n"
+ " } else {\n"
+ " return (com.google.protobuf.ByteString) ref;\n"
+ " }\n"
+ "}\n");
+}
+
+void ImmutableStringOneofFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ if (SupportFieldPresence(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ }
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.lang.String get$capitalized_name$() {\n"
+ " java.lang.Object ref $default_init$;\n"
+ " if ($has_oneof_case_message$) {\n"
+ " ref = $oneof_name$_;\n"
+ " }\n"
+ " if (!(ref instanceof java.lang.String)) {\n"
+ " com.google.protobuf.ByteString bs =\n"
+ " (com.google.protobuf.ByteString) ref;\n"
+ " java.lang.String s = bs.toStringUtf8();\n"
+ " if ($has_oneof_case_message$) {\n");
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_,
+ " $oneof_name$_ = s;\n");
+ } else {
+ printer->Print(variables_,
+ " if (bs.isValidUtf8()) {\n"
+ " $oneof_name$_ = s;\n"
+ " }\n");
+ }
+ printer->Print(variables_,
+ " }\n"
+ " return s;\n"
+ " } else {\n"
+ " return (java.lang.String) ref;\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " get$capitalized_name$Bytes() {\n"
+ " java.lang.Object ref $default_init$;\n"
+ " if ($has_oneof_case_message$) {\n"
+ " ref = $oneof_name$_;\n"
+ " }\n"
+ " if (ref instanceof String) {\n"
+ " com.google.protobuf.ByteString b = \n"
+ " com.google.protobuf.ByteString.copyFromUtf8(\n"
+ " (java.lang.String) ref);\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $oneof_name$_ = b;\n"
+ " }\n"
+ " return b;\n"
+ " } else {\n"
+ " return (com.google.protobuf.ByteString) ref;\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " java.lang.String value) {\n"
+ "$null_check$"
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ " $on_changed$\n"
+ " }\n"
+ " return this;\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$Bytes(\n"
+ " com.google.protobuf.ByteString value) {\n"
+ "$null_check$");
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_,
+ " checkByteStringIsUtf8(value);\n");
+ }
+ printer->Print(variables_,
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+}
+
+void ImmutableStringOneofFieldGenerator::
+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.
+ printer->Print(variables_,
+ "$set_oneof_case_message$;\n"
+ "$oneof_name$_ = other.$oneof_name$_;\n"
+ "$on_changed$\n");
+}
+
+void ImmutableStringOneofFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " result.$oneof_name$_ = $oneof_name$_;\n"
+ "}\n");
+}
+
+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}\n");
+ } else {
+ printer->Print(variables_,
+ "com.google.protobuf.ByteString bs = input.readBytes();\n"
+ "$set_oneof_case_message$;\n"
+ "$oneof_name$_ = bs;\n");
+ }
+}
+
+void ImmutableStringOneofFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+ "}\n");
+}
+
+void ImmutableStringOneofFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+ "}\n");
+}
+
+// ===================================================================
+
+RepeatedImmutableStringFieldGenerator::
+RepeatedImmutableStringFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex), context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+RepeatedImmutableStringFieldGenerator::
+~RepeatedImmutableStringFieldGenerator() {}
+
+int RepeatedImmutableStringFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$com.google.protobuf.ProtocolStringList\n"
+ " get$capitalized_name$List();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$java.lang.String get$capitalized_name$(int index);\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$com.google.protobuf.ByteString\n"
+ " get$capitalized_name$Bytes(int index);\n");
+}
+
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private com.google.protobuf.LazyStringList $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ProtocolStringList\n"
+ " get$capitalized_name$List() {\n"
+ " return $name$_;\n" // note: unmodifiable list
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " 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::
+GenerateBuilderMembers(io::Printer* printer) const {
+ // One field is the list and the bit field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a refererence to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ printer->Print(variables_,
+ "private com.google.protobuf.LazyStringList $name$_ = $empty_list$;\n");
+
+ printer->Print(variables_,
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n");
+
+ // Note: We return an unmodifiable list because otherwise the caller
+ // could hold on to the returned list and modify it after the message
+ // has been built, thus mutating the message which is supposed to be
+ // immutable.
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ProtocolStringList\n"
+ " get$capitalized_name$List() {\n"
+ " return $name$_.getUnmodifiableView();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " get$capitalized_name$Bytes(int index) {\n"
+ " return $name$_.getByteString(index);\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, java.lang.String value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " java.lang.String value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder addAll$capitalized_name$(\n"
+ " java.lang.Iterable<java.lang.String> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
+ " values, $name$_);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $name$_ = $empty_list$;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder add$capitalized_name$Bytes(\n"
+ " com.google.protobuf.ByteString value) {\n"
+ "$null_check$");
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_,
+ " checkByteStringIsUtf8(value);\n");
+ }
+ printer->Print(variables_,
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $empty_list$;\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $empty_list$;\n"
+ "$clear_mutable_bit_builder$;\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+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"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
+ " }\n"
+ " $on_changed$\n"
+ "}\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ // The code below ensures that the result has an immutable list. If our
+ // list is immutable, we can just reuse it. If not, we make it immutable.
+
+ printer->Print(variables_,
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = $name$_.getUnmodifiableView();\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_,
+ "String s = input.readStringRequireUtf8();\n");
+ } else {
+ printer->Print(variables_,
+ "com.google.protobuf.ByteString bs = input.readBytes();\n");
+ }
+ printer->Print(variables_,
+ "if (!$get_mutable_bit_parser$) {\n"
+ " $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
+ " $set_mutable_bit_parser$;\n"
+ "}\n");
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_,
+ "$name$_.add(s);\n");
+ } else {
+ printer->Print(variables_,
+ "$name$_.add(bs);\n");
+ }
+}
+
+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"
+ " $name$_ = $name$_.getUnmodifiableView();\n"
+ "}\n");
+}
+
+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"
+ " output.write$capitalized_type$NoTag($name$_.get(i));\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.writeBytes($number$, $name$_.getByteString(i));\n"
+ "}\n");
+ }
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "{\n"
+ " int dataSize = 0;\n");
+ printer->Indent();
+
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " dataSize += com.google.protobuf.CodedOutputStream\n"
+ " .computeBytesSizeNoTag($name$_.getByteString(i));\n"
+ "}\n");
+
+ 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->Outdent();
+ printer->Print("}\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
+ "}\n");
+}
+
+string RepeatedImmutableStringFieldGenerator::GetBoxedType() const {
+ return "String";
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/java/java_string_field.h b/src/google/protobuf/compiler/java/java_string_field.h
new file mode 100644
index 0000000..1ea44de
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_string_field.h
@@ -0,0 +1,160 @@
+// 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: kenton@google.com (Kenton Varda)
+// Author: jonp@google.com (Jon Perlow)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+ namespace compiler {
+ namespace java {
+ class Context; // context.h
+ class ClassNameResolver; // name_resolver.h
+ }
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableStringFieldGenerator : public ImmutableFieldGenerator {
+ public:
+ explicit ImmutableStringFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~ImmutableStringFieldGenerator();
+
+ // implements ImmutableFieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer) const;
+ 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 GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateParsingDoneCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
+
+ string GetBoxedType() const;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringFieldGenerator);
+};
+
+class ImmutableStringOneofFieldGenerator
+ : public ImmutableStringFieldGenerator {
+ public:
+ ImmutableStringOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~ImmutableStringOneofFieldGenerator();
+
+ private:
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringOneofFieldGenerator);
+};
+
+class RepeatedImmutableStringFieldGenerator : public ImmutableFieldGenerator {
+ public:
+ explicit RepeatedImmutableStringFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~RepeatedImmutableStringFieldGenerator();
+
+ // implements ImmutableFieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer) const;
+ 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 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;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
+
+ string GetBoxedType() const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableStringFieldGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
diff --git a/src/google/protobuf/compiler/javamicro/javamicro_file.h b/src/google/protobuf/compiler/javamicro/javamicro_file.h
index 430172a..1804abf 100644
--- a/src/google/protobuf/compiler/javamicro/javamicro_file.h
+++ b/src/google/protobuf/compiler/javamicro/javamicro_file.h
@@ -38,6 +38,7 @@
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/javamicro/javamicro_params.h>
namespace google {
@@ -46,9 +47,6 @@ namespace protobuf {
namespace io {
class Printer; // printer.h
}
- namespace compiler {
- class OutputDirectory; // code_generator.h
- }
}
namespace protobuf {
diff --git a/src/google/protobuf/compiler/javanano/javanano_enum.cc b/src/google/protobuf/compiler/javanano/javanano_enum.cc
index f934b05..c6e8dfe 100644
--- a/src/google/protobuf/compiler/javanano/javanano_enum.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_enum.cc
@@ -73,13 +73,45 @@ void EnumGenerator::Generate(io::Printer* printer) {
"// enum $classname$\n",
"classname", descriptor_->name());
+ const string classname = RenameJavaKeywords(descriptor_->name());
+
// Start of container interface
+ // If generating intdefs, we use the container interface as the intdef if
+ // present. Otherwise, we just make an empty @interface parallel to the
+ // constants.
+ bool use_intdef = params_.generate_intdefs();
bool use_shell_class = params_.java_enum_style();
- if (use_shell_class) {
- printer->Print(
- "public interface $classname$ {\n",
- "classname", RenameJavaKeywords(descriptor_->name()));
+ if (use_intdef) {
+ // @IntDef annotation so tools can enforce correctness
+ // Annotations will be discarded by the compiler
+ printer->Print("@java.lang.annotation.Retention("
+ "java.lang.annotation.RetentionPolicy.SOURCE)\n"
+ "@android.support.annotation.IntDef({\n");
printer->Indent();
+ for (int i = 0; i < canonical_values_.size(); i++) {
+ const string constant_name =
+ RenameJavaKeywords(canonical_values_[i]->name());
+ if (use_shell_class) {
+ printer->Print("$classname$.$name$,\n",
+ "classname", classname,
+ "name", constant_name);
+ } else {
+ printer->Print("$name$,\n", "name", constant_name);
+ }
+ }
+ printer->Outdent();
+ printer->Print("})\n");
+ }
+ if (use_shell_class || use_intdef) {
+ printer->Print(
+ "public $at_for_intdef$interface $classname$ {\n",
+ "classname", classname,
+ "at_for_intdef", use_intdef ? "@" : "");
+ if (use_shell_class) {
+ printer->Indent();
+ } else {
+ printer->Print("}\n\n");
+ }
}
// Canonical values
diff --git a/src/google/protobuf/compiler/javanano/javanano_enum_field.cc b/src/google/protobuf/compiler/javanano/javanano_enum_field.cc
index 6a18834..7666db3 100644
--- a/src/google/protobuf/compiler/javanano/javanano_enum_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_enum_field.cc
@@ -59,6 +59,7 @@ void SetEnumVariables(const Params& params,
RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor));
(*variables)["number"] = SimpleItoa(descriptor->number());
if (params.use_reference_types_for_primitives()
+ && !params.reftypes_primitive_enums()
&& !descriptor->is_repeated()) {
(*variables)["type"] = "java.lang.Integer";
(*variables)["default"] = "null";
@@ -75,6 +76,10 @@ void SetEnumVariables(const Params& params,
internal::WireFormatLite::MakeTag(descriptor->number(),
internal::WireFormat::WireTypeForFieldType(descriptor->type())));
(*variables)["message_name"] = descriptor->containing_type()->name();
+ const EnumDescriptor* enum_type = descriptor->enum_type();
+ (*variables)["message_type_intdef"] = "@"
+ + ToJavaName(params, enum_type->name(), true,
+ enum_type->containing_type(), enum_type->file());
}
void LoadEnumValues(const Params& params,
@@ -115,8 +120,10 @@ EnumFieldGenerator::~EnumFieldGenerator() {}
void EnumFieldGenerator::
GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
- printer->Print(variables_,
- "public $type$ $name$;\n");
+ if (params_.generate_intdefs()) {
+ printer->Print(variables_, "$message_type_intdef$\n");
+ }
+ printer->Print(variables_, "public $type$ $name$;\n");
if (params_.generate_has()) {
printer->Print(variables_,
@@ -197,7 +204,8 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
}
void EnumFieldGenerator::GenerateEqualsCode(io::Printer* printer) const {
- if (params_.use_reference_types_for_primitives()) {
+ if (params_.use_reference_types_for_primitives()
+ && !params_.reftypes_primitive_enums()) {
printer->Print(variables_,
"if (this.$name$ == null) {\n"
" if (other.$name$ != null) {\n"
@@ -228,7 +236,8 @@ void EnumFieldGenerator::GenerateEqualsCode(io::Printer* printer) const {
void EnumFieldGenerator::GenerateHashCodeCode(io::Printer* printer) const {
printer->Print(
"result = 31 * result + ");
- if (params_.use_reference_types_for_primitives()) {
+ if (params_.use_reference_types_for_primitives()
+ && !params_.reftypes_primitive_enums()) {
printer->Print(variables_,
"(this.$name$ == null ? 0 : this.$name$)");
} else {
@@ -253,12 +262,22 @@ AccessorEnumFieldGenerator::~AccessorEnumFieldGenerator() {}
void AccessorEnumFieldGenerator::
GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
+ printer->Print(variables_, "private int $name$_;\n");
+ if (params_.generate_intdefs()) {
+ printer->Print(variables_, "$message_type_intdef$\n");
+ }
printer->Print(variables_,
- "private int $name$_;\n"
"public int get$capitalized_name$() {\n"
" return $name$_;\n"
"}\n"
- "public $message_name$ set$capitalized_name$(int value) {\n"
+ "public $message_name$ set$capitalized_name$(");
+ if (params_.generate_intdefs()) {
+ printer->Print(variables_,
+ "\n"
+ " $message_type_intdef$ ");
+ }
+ printer->Print(variables_,
+ "int value) {\n"
" $name$_ = value;\n"
" $set_has$;\n"
" return this;\n"
@@ -496,6 +515,14 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
}
void RepeatedEnumFieldGenerator::
+GenerateFixClonedCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (this.$name$ != null && this.$name$.length > 0) {\n"
+ " cloned.$name$ = this.$name$.clone();\n"
+ "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
GenerateEqualsCode(io::Printer* printer) const {
printer->Print(variables_,
"if (!com.google.protobuf.nano.InternalNano.equals(\n"
diff --git a/src/google/protobuf/compiler/javanano/javanano_enum_field.h b/src/google/protobuf/compiler/javanano/javanano_enum_field.h
index 55bf635..8622463 100644
--- a/src/google/protobuf/compiler/javanano/javanano_enum_field.h
+++ b/src/google/protobuf/compiler/javanano/javanano_enum_field.h
@@ -106,6 +106,7 @@ class RepeatedEnumFieldGenerator : public FieldGenerator {
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateEqualsCode(io::Printer* printer) const;
void GenerateHashCodeCode(io::Printer* printer) const;
+ void GenerateFixClonedCode(io::Printer* printer) const;
private:
void GenerateRepeatedDataSizeCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/javanano/javanano_extension.cc b/src/google/protobuf/compiler/javanano/javanano_extension.cc
index 754ed55..0b9d1d8 100644
--- a/src/google/protobuf/compiler/javanano/javanano_extension.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_extension.cc
@@ -140,7 +140,7 @@ void ExtensionGenerator::Generate(io::Printer* printer) const {
" com.google.protobuf.nano.Extension.create$repeated$$ext_type$(\n"
" com.google.protobuf.nano.Extension.$type$,\n"
" $class$.class,\n"
- " $tag_params$);\n");
+ " $tag_params$L);\n");
}
} // namespace javanano
diff --git a/src/google/protobuf/compiler/javanano/javanano_field.h b/src/google/protobuf/compiler/javanano/javanano_field.h
index 61fc621..e015259 100644
--- a/src/google/protobuf/compiler/javanano/javanano_field.h
+++ b/src/google/protobuf/compiler/javanano/javanano_field.h
@@ -82,6 +82,7 @@ class FieldGenerator {
virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0;
virtual void GenerateEqualsCode(io::Printer* printer) const = 0;
virtual void GenerateHashCodeCode(io::Printer* printer) const = 0;
+ virtual void GenerateFixClonedCode(io::Printer* printer) const {}
protected:
const Params& params_;
diff --git a/src/google/protobuf/compiler/javanano/javanano_file.h b/src/google/protobuf/compiler/javanano/javanano_file.h
index 9472721..cfcd7c6 100644
--- a/src/google/protobuf/compiler/javanano/javanano_file.h
+++ b/src/google/protobuf/compiler/javanano/javanano_file.h
@@ -38,6 +38,7 @@
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/javanano/javanano_params.h>
namespace google {
@@ -46,9 +47,6 @@ namespace protobuf {
namespace io {
class Printer; // printer.h
}
- namespace compiler {
- class OutputDirectory; // code_generator.h
- }
}
namespace protobuf {
diff --git a/src/google/protobuf/compiler/javanano/javanano_generator.cc b/src/google/protobuf/compiler/javanano/javanano_generator.cc
index 61ef2ca..99ebe12 100644
--- a/src/google/protobuf/compiler/javanano/javanano_generator.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_generator.cc
@@ -139,13 +139,25 @@ bool JavaNanoGenerator::Generate(const FileDescriptor* file,
params.set_java_enum_style(option_value == "java");
} else if (option_name == "optional_field_style") {
params.set_optional_field_accessors(option_value == "accessors");
- params.set_use_reference_types_for_primitives(option_value == "reftypes");
+ params.set_use_reference_types_for_primitives(option_value == "reftypes"
+ || option_value == "reftypes_compat_mode");
+ params.set_reftypes_primitive_enums(
+ option_value == "reftypes_compat_mode");
+ if (option_value == "reftypes_compat_mode") {
+ params.set_generate_clear(false);
+ }
} else if (option_name == "generate_equals") {
params.set_generate_equals(option_value == "true");
} else if (option_name == "ignore_services") {
params.set_ignore_services(option_value == "true");
} else if (option_name == "parcelable_messages") {
params.set_parcelable_messages(option_value == "true");
+ } else if (option_name == "generate_clone") {
+ params.set_generate_clone(option_value == "true");
+ } else if (option_name == "generate_intdefs") {
+ params.set_generate_intdefs(option_value == "true");
+ } else if (option_name == "generate_clear") {
+ params.set_generate_clear(option_value == "true");
} else {
*error = "Ignore unknown javanano generator option: " + option_name;
}
diff --git a/src/google/protobuf/compiler/javanano/javanano_helpers.cc b/src/google/protobuf/compiler/javanano/javanano_helpers.cc
index bf88f25..2149418 100644
--- a/src/google/protobuf/compiler/javanano/javanano_helpers.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_helpers.cc
@@ -392,6 +392,10 @@ string DefaultValue(const Params& params, const FieldDescriptor* field) {
}
if (params.use_reference_types_for_primitives()) {
+ if (params.reftypes_primitive_enums()
+ && field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ return "Integer.MIN_VALUE";
+ }
return "null";
}
diff --git a/src/google/protobuf/compiler/javanano/javanano_message.cc b/src/google/protobuf/compiler/javanano/javanano_message.cc
index 7a2b4a0..4026031 100644
--- a/src/google/protobuf/compiler/javanano/javanano_message.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_message.cc
@@ -134,18 +134,23 @@ void MessageGenerator::Generate(io::Printer* printer) {
}
if (params_.store_unknown_fields() && params_.parcelable_messages()) {
printer->Print(
- " com.google.protobuf.nano.android.ParcelableExtendableMessageNano<$classname$> {\n",
+ " com.google.protobuf.nano.android.ParcelableExtendableMessageNano<$classname$>",
"classname", descriptor_->name());
} else if (params_.store_unknown_fields()) {
printer->Print(
- " com.google.protobuf.nano.ExtendableMessageNano<$classname$> {\n",
+ " com.google.protobuf.nano.ExtendableMessageNano<$classname$>",
"classname", descriptor_->name());
} else if (params_.parcelable_messages()) {
printer->Print(
- " com.google.protobuf.nano.android.ParcelableMessageNano {\n");
+ " com.google.protobuf.nano.android.ParcelableMessageNano");
} else {
printer->Print(
- " com.google.protobuf.nano.MessageNano {\n");
+ " com.google.protobuf.nano.MessageNano");
+ }
+ if (params_.generate_clone()) {
+ printer->Print(" implements java.lang.Cloneable {\n");
+ } else {
+ printer->Print(" {\n");
}
printer->Indent();
@@ -245,22 +250,34 @@ void MessageGenerator::Generate(io::Printer* printer) {
" _classInitialized = true;\n"
" }\n"
" }\n"
- " }\n"
- " clear();\n"
- "}\n");
+ " }\n");
+ if (params_.generate_clear()) {
+ printer->Print(" clear();\n");
+ }
+ printer->Print("}\n");
} else {
printer->Print(
"\n"
- "public $classname$() {\n"
- " clear();\n"
- "}\n",
+ "public $classname$() {\n",
"classname", descriptor_->name());
+ if (params_.generate_clear()) {
+ printer->Print(" clear();\n");
+ } else {
+ printer->Indent();
+ GenerateFieldInitializers(printer);
+ printer->Outdent();
+ }
+ printer->Print("}\n");
}
// Other methods in this class
GenerateClear(printer);
+ if (params_.generate_clone()) {
+ GenerateClone(printer);
+ }
+
if (params_.generate_equals()) {
GenerateEquals(printer);
GenerateHashCode(printer);
@@ -440,12 +457,24 @@ void MessageGenerator::GenerateSerializeOneField(
}
void MessageGenerator::GenerateClear(io::Printer* printer) {
+ if (!params_.generate_clear()) {
+ return;
+ }
printer->Print(
"\n"
"public $classname$ clear() {\n",
"classname", descriptor_->name());
printer->Indent();
+ GenerateFieldInitializers(printer);
+
+ printer->Outdent();
+ printer->Print(
+ " return this;\n"
+ "}\n");
+}
+
+void MessageGenerator::GenerateFieldInitializers(io::Printer* printer) {
// Clear bit fields.
int totalInts = (field_generators_.total_bits() + 31) / 32;
for (int i = 0; i < totalInts; i++) {
@@ -463,12 +492,34 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
if (params_.store_unknown_fields()) {
printer->Print("unknownFieldData = null;\n");
}
+ printer->Print("cachedSize = -1;\n");
+}
+
+void MessageGenerator::GenerateClone(io::Printer* printer) {
+ printer->Print(
+ "@Override\n"
+ "public $classname$ clone() {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+
+ printer->Print(
+ "$classname$ cloned;\n"
+ "try {\n"
+ " cloned = ($classname$) super.clone();\n"
+ "} catch (java.lang.CloneNotSupportedException e) {\n"
+ " throw new java.lang.AssertionError(e);\n"
+ "}\n",
+ "classname", descriptor_->name());
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i)).GenerateFixClonedCode(printer);
+ }
printer->Outdent();
printer->Print(
- " cachedSize = -1;\n"
- " return this;\n"
- "}\n");
+ " return cloned;\n"
+ "}\n"
+ "\n");
}
void MessageGenerator::GenerateEquals(io::Printer* printer) {
@@ -501,7 +552,11 @@ void MessageGenerator::GenerateEquals(io::Printer* printer) {
if (params_.store_unknown_fields()) {
printer->Print(
- "return unknownFieldDataEquals(other);\n");
+ "if (unknownFieldData == null || unknownFieldData.isEmpty()) {\n"
+ " return other.unknownFieldData == null || other.unknownFieldData.isEmpty();\n"
+ "} else {\n"
+ " return unknownFieldData.equals(other.unknownFieldData);\n"
+ "}");
} else {
printer->Print(
"return true;\n");
@@ -523,6 +578,7 @@ void MessageGenerator::GenerateHashCode(io::Printer* printer) {
printer->Indent();
printer->Print("int result = 17;\n");
+ printer->Print("result = 31 * result + getClass().getName().hashCode();\n");
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
field_generators_.get(field).GenerateHashCodeCode(printer);
@@ -530,7 +586,9 @@ void MessageGenerator::GenerateHashCode(io::Printer* printer) {
if (params_.store_unknown_fields()) {
printer->Print(
- "result = 31 * result + unknownFieldDataHashCode();\n");
+ "result = 31 * result + \n"
+ " (unknownFieldData == null || unknownFieldData.isEmpty() ? 0 : \n"
+ " unknownFieldData.hashCode());\n");
}
printer->Print("return result;\n");
diff --git a/src/google/protobuf/compiler/javanano/javanano_message.h b/src/google/protobuf/compiler/javanano/javanano_message.h
index f87f84f..1bb6557 100644
--- a/src/google/protobuf/compiler/javanano/javanano_message.h
+++ b/src/google/protobuf/compiler/javanano/javanano_message.h
@@ -77,8 +77,10 @@ class MessageGenerator {
const FieldDescriptor* field);
void GenerateClear(io::Printer* printer);
+ void GenerateFieldInitializers(io::Printer* printer);
void GenerateEquals(io::Printer* printer);
void GenerateHashCode(io::Printer* printer);
+ void GenerateClone(io::Printer* printer);
const Params& params_;
const Descriptor* descriptor_;
diff --git a/src/google/protobuf/compiler/javanano/javanano_message_field.cc b/src/google/protobuf/compiler/javanano/javanano_message_field.cc
index a46081d..4752644 100644
--- a/src/google/protobuf/compiler/javanano/javanano_message_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_message_field.cc
@@ -127,6 +127,14 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
}
void MessageFieldGenerator::
+GenerateFixClonedCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (this.$name$ != null) {\n"
+ " cloned.$name$ = this.$name$.clone();\n"
+ "}\n");
+}
+
+void MessageFieldGenerator::
GenerateEqualsCode(io::Printer* printer) const {
printer->Print(variables_,
"if (this.$name$ == null) { \n"
@@ -238,6 +246,19 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
}
void RepeatedMessageFieldGenerator::
+GenerateFixClonedCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (this.$name$ != null && this.$name$.length > 0) {\n"
+ " cloned.$name$ = new $type$[this.$name$.length];\n"
+ " for (int i = 0; i < this.$name$.length; i++) {\n"
+ " if (this.$name$[i] != null) {\n"
+ " cloned.$name$[i] = this.$name$[i].clone();\n"
+ " }\n"
+ " }\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
GenerateEqualsCode(io::Printer* printer) const {
printer->Print(variables_,
"if (!com.google.protobuf.nano.InternalNano.equals(\n"
diff --git a/src/google/protobuf/compiler/javanano/javanano_message_field.h b/src/google/protobuf/compiler/javanano/javanano_message_field.h
index e94a37b..1edff25 100644
--- a/src/google/protobuf/compiler/javanano/javanano_message_field.h
+++ b/src/google/protobuf/compiler/javanano/javanano_message_field.h
@@ -58,6 +58,7 @@ class MessageFieldGenerator : public FieldGenerator {
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateEqualsCode(io::Printer* printer) const;
void GenerateHashCodeCode(io::Printer* printer) const;
+ void GenerateFixClonedCode(io::Printer* printer) const;
private:
const FieldDescriptor* descriptor_;
@@ -80,6 +81,7 @@ class RepeatedMessageFieldGenerator : public FieldGenerator {
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateEqualsCode(io::Printer* printer) const;
void GenerateHashCodeCode(io::Printer* printer) const;
+ void GenerateFixClonedCode(io::Printer* printer) const;
private:
const FieldDescriptor* descriptor_;
diff --git a/src/google/protobuf/compiler/javanano/javanano_params.h b/src/google/protobuf/compiler/javanano/javanano_params.h
index d0626a2..e3b4bb9 100644
--- a/src/google/protobuf/compiler/javanano/javanano_params.h
+++ b/src/google/protobuf/compiler/javanano/javanano_params.h
@@ -64,6 +64,10 @@ class Params {
bool generate_equals_;
bool ignore_services_;
bool parcelable_messages_;
+ bool reftypes_primitive_enums_;
+ bool generate_clear_;
+ bool generate_clone_;
+ bool generate_intdefs_;
public:
Params(const string & base_name) :
@@ -77,7 +81,11 @@ class Params {
use_reference_types_for_primitives_(false),
generate_equals_(false),
ignore_services_(false),
- parcelable_messages_(false) {
+ parcelable_messages_(false),
+ reftypes_primitive_enums_(false),
+ generate_clear_(true),
+ generate_clone_(false),
+ generate_intdefs_(false) {
}
const string& base_name() const {
@@ -213,6 +221,34 @@ class Params {
bool parcelable_messages() const {
return parcelable_messages_;
}
+
+ void set_reftypes_primitive_enums(bool value) {
+ reftypes_primitive_enums_ = value;
+ }
+ bool reftypes_primitive_enums() const {
+ return reftypes_primitive_enums_;
+ }
+
+ void set_generate_clear(bool value) {
+ generate_clear_ = value;
+ }
+ bool generate_clear() const {
+ return generate_clear_;
+ }
+
+ void set_generate_clone(bool value) {
+ generate_clone_ = value;
+ }
+ bool generate_clone() const {
+ return generate_clone_;
+ }
+
+ void set_generate_intdefs(bool value) {
+ generate_intdefs_ = value;
+ }
+ bool generate_intdefs() const {
+ return generate_intdefs_;
+ }
};
} // namespace javanano
diff --git a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
index a3bc3a8..bda52c6 100644
--- a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
@@ -385,6 +385,14 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
}
}
+void RepeatedPrimitiveFieldGenerator::
+GenerateFixClonedCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (this.$name$ != null && this.$name$.length > 0) {\n"
+ " cloned.$name$ = this.$name$.clone();\n"
+ "}\n");
+}
+
void PrimitiveFieldGenerator::
GenerateEqualsCode(io::Printer* printer) const {
// We define equality as serialized form equality. If generate_has(),
diff --git a/src/google/protobuf/compiler/javanano/javanano_primitive_field.h b/src/google/protobuf/compiler/javanano/javanano_primitive_field.h
index c04a19b..5ace0de 100644
--- a/src/google/protobuf/compiler/javanano/javanano_primitive_field.h
+++ b/src/google/protobuf/compiler/javanano/javanano_primitive_field.h
@@ -108,6 +108,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateEqualsCode(io::Printer* printer) const;
void GenerateHashCodeCode(io::Printer* printer) const;
+ void GenerateFixClonedCode(io::Printer* printer) const;
private:
void GenerateRepeatedDataSizeCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc
index 8bd71b1..1fc60ce 100644
--- a/src/google/protobuf/compiler/main.cc
+++ b/src/google/protobuf/compiler/main.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -45,7 +45,7 @@ int main(int argc, char* argv[]) {
// Proto2 C++
google::protobuf::compiler::cpp::CppGenerator cpp_generator;
- cli.RegisterGenerator("--cpp_out", &cpp_generator,
+ cli.RegisterGenerator("--cpp_out", "--cpp_opt", &cpp_generator,
"Generate C++ header and source.");
// Proto2 Java
diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc
index 83d5a4e..916b0cc 100644
--- a/src/google/protobuf/compiler/mock_code_generator.cc
+++ b/src/google/protobuf/compiler/mock_code_generator.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,19 +32,32 @@
#include <google/protobuf/compiler/mock_code_generator.h>
+#include <memory>
+
#include <google/protobuf/testing/file.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-inl.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
namespace compiler {
+// Returns the list of the names of files in all_files in the form of a
+// comma-separated string.
+string CommaSeparatedList(const vector<const FileDescriptor*> all_files) {
+ vector<string> names;
+ for (int i = 0; i < all_files.size(); i++) {
+ names.push_back(all_files[i]->name());
+ }
+ return Join(names, ",");
+}
+
static const char* kFirstInsertionPointName = "first_mock_insertion_point";
static const char* kSecondInsertionPointName = "second_mock_insertion_point";
static const char* kFirstInsertionPoint =
@@ -63,13 +76,14 @@ void MockCodeGenerator::ExpectGenerated(
const string& insertions,
const string& file,
const string& first_message_name,
+ const string& first_parsed_file_name,
const string& output_directory) {
string content;
- ASSERT_TRUE(File::ReadFileToString(
- output_directory + "/" + GetOutputFileName(name, file), &content));
+ GOOGLE_CHECK_OK(
+ File::GetContents(output_directory + "/" + GetOutputFileName(name, file),
+ &content, true));
- vector<string> lines;
- SplitStringUsing(content, "\n", &lines);
+ vector<string> lines = Split(content, "\n", true);
while (!lines.empty() && lines.back().empty()) {
lines.pop_back();
@@ -83,8 +97,9 @@ void MockCodeGenerator::ExpectGenerated(
SplitStringUsing(insertions, ",", &insertion_list);
}
- ASSERT_EQ(lines.size(), 3 + insertion_list.size() * 2);
- EXPECT_EQ(GetOutputFileContent(name, parameter, file, first_message_name),
+ EXPECT_EQ(lines.size(), 3 + insertion_list.size() * 2);
+ EXPECT_EQ(GetOutputFileContent(name, parameter, file,
+ first_parsed_file_name, first_message_name),
lines[0]);
EXPECT_EQ(kFirstInsertionPoint, lines[1 + insertion_list.size()]);
@@ -92,12 +107,12 @@ void MockCodeGenerator::ExpectGenerated(
for (int i = 0; i < insertion_list.size(); i++) {
EXPECT_EQ(GetOutputFileContent(insertion_list[i], "first_insert",
- file, first_message_name),
+ file, file, first_message_name),
lines[1 + i]);
// Second insertion point is indented, so the inserted text should
// automatically be indented too.
EXPECT_EQ(" " + GetOutputFileContent(insertion_list[i], "second_insert",
- file, first_message_name),
+ file, file, first_message_name),
lines[2 + insertion_list.size() + i]);
}
}
@@ -105,7 +120,7 @@ void MockCodeGenerator::ExpectGenerated(
bool MockCodeGenerator::Generate(
const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
for (int i = 0; i < file->message_type_count(); i++) {
if (HasPrefixString(file->message_type(i)->name(), "MockCodeGenerator_")) {
@@ -120,6 +135,15 @@ bool MockCodeGenerator::Generate(
} else if (command == "Abort") {
cerr << "Saw message type MockCodeGenerator_Abort." << endl;
abort();
+ } else if (command == "HasSourceCodeInfo") {
+ FileDescriptorProto file_descriptor_proto;
+ file->CopySourceCodeInfoTo(&file_descriptor_proto);
+ bool has_source_code_info =
+ file_descriptor_proto.has_source_code_info() &&
+ file_descriptor_proto.source_code_info().location_size() > 0;
+ cerr << "Saw message type MockCodeGenerator_HasSourceCodeInfo: "
+ << has_source_code_info << "." << endl;
+ abort();
} else {
GOOGLE_LOG(FATAL) << "Unknown MockCodeGenerator command: " << command;
}
@@ -133,12 +157,11 @@ bool MockCodeGenerator::Generate(
for (int i = 0; i < insert_into.size(); i++) {
{
- scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->OpenForInsert(
- GetOutputFileName(insert_into[i], file),
- kFirstInsertionPointName));
+ scoped_ptr<io::ZeroCopyOutputStream> output(context->OpenForInsert(
+ GetOutputFileName(insert_into[i], file), kFirstInsertionPointName));
io::Printer printer(output.get(), '$');
- printer.PrintRaw(GetOutputFileContent(name_, "first_insert", file));
+ printer.PrintRaw(GetOutputFileContent(name_, "first_insert",
+ file, context));
if (printer.failed()) {
*error = "MockCodeGenerator detected write error.";
return false;
@@ -147,11 +170,11 @@ bool MockCodeGenerator::Generate(
{
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->OpenForInsert(
- GetOutputFileName(insert_into[i], file),
- kSecondInsertionPointName));
+ context->OpenForInsert(GetOutputFileName(insert_into[i], file),
+ kSecondInsertionPointName));
io::Printer printer(output.get(), '$');
- printer.PrintRaw(GetOutputFileContent(name_, "second_insert", file));
+ printer.PrintRaw(GetOutputFileContent(name_, "second_insert",
+ file, context));
if (printer.failed()) {
*error = "MockCodeGenerator detected write error.";
return false;
@@ -160,10 +183,11 @@ bool MockCodeGenerator::Generate(
}
} else {
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(GetOutputFileName(name_, file)));
+ context->Open(GetOutputFileName(name_, file)));
io::Printer printer(output.get(), '$');
- printer.PrintRaw(GetOutputFileContent(name_, parameter, file));
+ printer.PrintRaw(GetOutputFileContent(name_, parameter,
+ file, context));
printer.PrintRaw(kFirstInsertionPoint);
printer.PrintRaw(kSecondInsertionPoint);
@@ -186,11 +210,16 @@ string MockCodeGenerator::GetOutputFileName(const string& generator_name,
return file + ".MockCodeGenerator." + generator_name;
}
-string MockCodeGenerator::GetOutputFileContent(const string& generator_name,
- const string& parameter,
- const FileDescriptor* file) {
+string MockCodeGenerator::GetOutputFileContent(
+ const string& generator_name,
+ const string& parameter,
+ const FileDescriptor* file,
+ GeneratorContext *context) {
+ vector<const FileDescriptor*> all_files;
+ context->ListParsedFiles(&all_files);
return GetOutputFileContent(
generator_name, parameter, file->name(),
+ CommaSeparatedList(all_files),
file->message_type_count() > 0 ?
file->message_type(0)->name() : "(none)");
}
@@ -199,9 +228,11 @@ string MockCodeGenerator::GetOutputFileContent(
const string& generator_name,
const string& parameter,
const string& file,
+ const string& parsed_file_list,
const string& first_message_name) {
- return strings::Substitute("$0: $1, $2, $3\n",
- generator_name, parameter, file, first_message_name);
+ return strings::Substitute("$0: $1, $2, $3, $4\n",
+ generator_name, parameter, file,
+ first_message_name, parsed_file_list);
}
} // namespace compiler
diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h
index 01d69dd..8c8348d 100644
--- a/src/google/protobuf/compiler/mock_code_generator.h
+++ b/src/google/protobuf/compiler/mock_code_generator.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -59,6 +59,10 @@ namespace compiler {
// MockCodeGenerator_Exit." to stderr and then calls exit(123).
// MockCodeGenerator_Abort: Generate() prints "Saw message type
// MockCodeGenerator_Abort." to stderr and then calls abort().
+// MockCodeGenerator_HasSourceCodeInfo: Causes Generate() to abort after
+// printing "Saw message type MockCodeGenerator_HasSourceCodeInfo: FOO." to
+// stderr, where FOO is "1" if the supplied FileDescriptorProto has source
+// code info, and "0" otherwise.
class MockCodeGenerator : public CodeGenerator {
public:
MockCodeGenerator(const string& name);
@@ -69,11 +73,14 @@ class MockCodeGenerator : public CodeGenerator {
//
// |insertions| is a comma-separated list of names of MockCodeGenerators which
// should have inserted lines into this file.
+ // |parsed_file_list| is a comma-separated list of names of the files
+ // that are being compiled together in this run.
static void ExpectGenerated(const string& name,
const string& parameter,
const string& insertions,
const string& file,
const string& first_message_name,
+ const string& parsed_file_list,
const string& output_directory);
// Get the name of the file which would be written by the given generator.
@@ -86,7 +93,7 @@ class MockCodeGenerator : public CodeGenerator {
virtual bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const;
private:
@@ -94,10 +101,12 @@ class MockCodeGenerator : public CodeGenerator {
static string GetOutputFileContent(const string& generator_name,
const string& parameter,
- const FileDescriptor* file);
+ const FileDescriptor* file,
+ GeneratorContext *context);
static string GetOutputFileContent(const string& generator_name,
const string& parameter,
const string& file,
+ const string& parsed_file_list,
const string& first_message_name);
};
diff --git a/src/google/protobuf/compiler/package_info.h b/src/google/protobuf/compiler/package_info.h
index b897126..fb6b473 100644
--- a/src/google/protobuf/compiler/package_info.h
+++ b/src/google/protobuf/compiler/package_info.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index 758f70d..474a8f8 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -46,7 +46,7 @@
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/map_util.h>
namespace google {
namespace protobuf {
@@ -174,6 +174,20 @@ bool Parser::ConsumeInteger(int* output, const char* error) {
}
}
+bool Parser::ConsumeSignedInteger(int* output, const char* error) {
+ bool is_negative = false;
+ uint64 max_value = kint32max;
+ if (TryConsume("-")) {
+ is_negative = true;
+ max_value += 1;
+ }
+ uint64 value = 0;
+ DO(ConsumeInteger64(max_value, &value, error));
+ if (is_negative) value *= -1;
+ *output = value;
+ return true;
+}
+
bool Parser::ConsumeInteger64(uint64 max_value, uint64* output,
const char* error) {
if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
@@ -237,6 +251,35 @@ bool Parser::ConsumeString(string* output, const char* error) {
}
}
+bool Parser::TryConsumeEndOfDeclaration(const char* text,
+ const LocationRecorder* location) {
+ if (LookingAt(text)) {
+ string leading, trailing;
+ input_->NextWithComments(&trailing, NULL, &leading);
+
+ // Save the leading comments for next time, and recall the leading comments
+ // from last time.
+ leading.swap(upcoming_doc_comments_);
+
+ if (location != NULL) {
+ location->AttachComments(&leading, &trailing);
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool Parser::ConsumeEndOfDeclaration(const char* text,
+ const LocationRecorder* location) {
+ if (TryConsumeEndOfDeclaration(text, location)) {
+ return true;
+ } else {
+ AddError("Expected \"" + string(text) + "\".");
+ return false;
+ }
+}
+
// -------------------------------------------------------------------
void Parser::AddError(int line, int column, const string& error) {
@@ -250,20 +293,87 @@ void Parser::AddError(const string& error) {
AddError(input_->current().line, input_->current().column, error);
}
-void Parser::RecordLocation(
- const Message* descriptor,
- DescriptorPool::ErrorCollector::ErrorLocation location,
- int line, int column) {
- if (source_location_table_ != NULL) {
- source_location_table_->Add(descriptor, location, line, column);
+// -------------------------------------------------------------------
+
+Parser::LocationRecorder::LocationRecorder(Parser* parser)
+ : parser_(parser),
+ location_(parser_->source_code_info_->add_location()) {
+ location_->add_span(parser_->input_->current().line);
+ location_->add_span(parser_->input_->current().column);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent) {
+ Init(parent);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
+ int path1) {
+ Init(parent);
+ AddPath(path1);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
+ int path1, int path2) {
+ Init(parent);
+ AddPath(path1);
+ AddPath(path2);
+}
+
+void Parser::LocationRecorder::Init(const LocationRecorder& parent) {
+ parser_ = parent.parser_;
+ location_ = parser_->source_code_info_->add_location();
+ location_->mutable_path()->CopyFrom(parent.location_->path());
+
+ location_->add_span(parser_->input_->current().line);
+ location_->add_span(parser_->input_->current().column);
+}
+
+Parser::LocationRecorder::~LocationRecorder() {
+ if (location_->span_size() <= 2) {
+ EndAt(parser_->input_->previous());
}
}
-void Parser::RecordLocation(
- const Message* descriptor,
+void Parser::LocationRecorder::AddPath(int path_component) {
+ location_->add_path(path_component);
+}
+
+void Parser::LocationRecorder::StartAt(const io::Tokenizer::Token& token) {
+ location_->set_span(0, token.line);
+ location_->set_span(1, token.column);
+}
+
+void Parser::LocationRecorder::StartAt(const LocationRecorder& other) {
+ location_->set_span(0, other.location_->span(0));
+ location_->set_span(1, other.location_->span(1));
+}
+
+void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) {
+ if (token.line != location_->span(0)) {
+ location_->add_span(token.line);
+ }
+ location_->add_span(token.end_column);
+}
+
+void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location) {
- RecordLocation(descriptor, location,
- input_->current().line, input_->current().column);
+ if (parser_->source_location_table_ != NULL) {
+ parser_->source_location_table_->Add(
+ descriptor, location, location_->span(0), location_->span(1));
+ }
+}
+
+void Parser::LocationRecorder::AttachComments(
+ string* leading, string* trailing) const {
+ GOOGLE_CHECK(!location_->has_leading_comments());
+ GOOGLE_CHECK(!location_->has_trailing_comments());
+
+ if (!leading->empty()) {
+ location_->mutable_leading_comments()->swap(*leading);
+ }
+ if (!trailing->empty()) {
+ location_->mutable_trailing_comments()->swap(*trailing);
+ }
}
// -------------------------------------------------------------------
@@ -273,7 +383,7 @@ void Parser::SkipStatement() {
if (AtEnd()) {
return;
} else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
- if (TryConsume(";")) {
+ if (TryConsumeEndOfDeclaration(";", NULL)) {
return;
} else if (TryConsume("{")) {
SkipRestOfBlock();
@@ -291,7 +401,7 @@ void Parser::SkipRestOfBlock() {
if (AtEnd()) {
return;
} else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
- if (TryConsume("}")) {
+ if (TryConsumeEndOfDeclaration("}", NULL)) {
return;
} else if (TryConsume("{")) {
SkipRestOfBlock();
@@ -308,38 +418,51 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
had_errors_ = false;
syntax_identifier_.clear();
+ // Note that |file| could be NULL at this point if
+ // stop_after_syntax_identifier_ is true. So, we conservatively allocate
+ // SourceCodeInfo on the stack, then swap it into the FileDescriptorProto
+ // later on.
+ SourceCodeInfo source_code_info;
+ source_code_info_ = &source_code_info;
+
if (LookingAtType(io::Tokenizer::TYPE_START)) {
// Advance to first token.
- input_->Next();
+ input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_);
}
- if (require_syntax_identifier_ || LookingAt("syntax")) {
- if (!ParseSyntaxIdentifier()) {
- // Don't attempt to parse the file if we didn't recognize the syntax
- // identifier.
- return false;
+ {
+ LocationRecorder root_location(this);
+
+ if (require_syntax_identifier_ || LookingAt("syntax")) {
+ if (!ParseSyntaxIdentifier()) {
+ // Don't attempt to parse the file if we didn't recognize the syntax
+ // identifier.
+ return false;
+ }
+ } else if (!stop_after_syntax_identifier_) {
+ syntax_identifier_ = "proto2";
}
- } else if (!stop_after_syntax_identifier_) {
- syntax_identifier_ = "proto2";
- }
- if (stop_after_syntax_identifier_) return !had_errors_;
+ if (stop_after_syntax_identifier_) return !had_errors_;
- // Repeatedly parse statements until we reach the end of the file.
- while (!AtEnd()) {
- if (!ParseTopLevelStatement(file)) {
- // This statement failed to parse. Skip it, but keep looping to parse
- // other statements.
- SkipStatement();
+ // Repeatedly parse statements until we reach the end of the file.
+ while (!AtEnd()) {
+ if (!ParseTopLevelStatement(file, root_location)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
- if (LookingAt("}")) {
- AddError("Unmatched \"}\".");
- input_->Next();
+ if (LookingAt("}")) {
+ AddError("Unmatched \"}\".");
+ input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_);
+ }
}
}
}
input_ = NULL;
+ source_code_info_ = NULL;
+ source_code_info.Swap(file->mutable_source_code_info());
return !had_errors_;
}
@@ -349,7 +472,7 @@ bool Parser::ParseSyntaxIdentifier() {
io::Tokenizer::Token syntax_token = input_->current();
string syntax;
DO(ConsumeString(&syntax, "Expected syntax identifier."));
- DO(Consume(";"));
+ DO(ConsumeEndOfDeclaration(";", NULL));
syntax_identifier_ = syntax;
@@ -363,25 +486,43 @@ bool Parser::ParseSyntaxIdentifier() {
return true;
}
-bool Parser::ParseTopLevelStatement(FileDescriptorProto* file) {
- if (TryConsume(";")) {
+bool Parser::ParseTopLevelStatement(FileDescriptorProto* file,
+ const LocationRecorder& root_location) {
+ if (TryConsumeEndOfDeclaration(";", NULL)) {
// empty statement; ignore
return true;
} else if (LookingAt("message")) {
- return ParseMessageDefinition(file->add_message_type());
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kMessageTypeFieldNumber, file->message_type_size());
+ return ParseMessageDefinition(file->add_message_type(), location, file);
} else if (LookingAt("enum")) {
- return ParseEnumDefinition(file->add_enum_type());
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kEnumTypeFieldNumber, file->enum_type_size());
+ return ParseEnumDefinition(file->add_enum_type(), location, file);
} else if (LookingAt("service")) {
- return ParseServiceDefinition(file->add_service());
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kServiceFieldNumber, file->service_size());
+ return ParseServiceDefinition(file->add_service(), location, file);
} else if (LookingAt("extend")) {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kExtensionFieldNumber);
return ParseExtend(file->mutable_extension(),
- file->mutable_message_type());
+ file->mutable_message_type(),
+ root_location,
+ FileDescriptorProto::kMessageTypeFieldNumber,
+ location, file);
} else if (LookingAt("import")) {
- return ParseImport(file->add_dependency());
+ return ParseImport(file->mutable_dependency(),
+ file->mutable_public_dependency(),
+ file->mutable_weak_dependency(),
+ root_location, file);
} else if (LookingAt("package")) {
- return ParsePackage(file);
+ return ParsePackage(file, root_location, file);
} else if (LookingAt("option")) {
- return ParseOption(file->mutable_options());
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kOptionsFieldNumber);
+ return ParseOption(file->mutable_options(), location, file,
+ OPTION_STATEMENT);
} else {
AddError("Expected top-level statement (e.g. \"message\").");
return false;
@@ -391,93 +532,234 @@ bool Parser::ParseTopLevelStatement(FileDescriptorProto* file) {
// -------------------------------------------------------------------
// Messages
-bool Parser::ParseMessageDefinition(DescriptorProto* message) {
+bool Parser::ParseMessageDefinition(
+ DescriptorProto* message,
+ const LocationRecorder& message_location,
+ const FileDescriptorProto* containing_file) {
DO(Consume("message"));
- RecordLocation(message, DescriptorPool::ErrorCollector::NAME);
- DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
- DO(ParseMessageBlock(message));
+ {
+ LocationRecorder location(message_location,
+ DescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ message, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
+ }
+ DO(ParseMessageBlock(message, message_location, containing_file));
return true;
}
-bool Parser::ParseMessageBlock(DescriptorProto* message) {
- DO(Consume("{"));
+namespace {
+
+const int kMaxExtensionRangeSentinel = -1;
- while (!TryConsume("}")) {
+bool IsMessageSetWireFormatMessage(const DescriptorProto& message) {
+ const MessageOptions& options = message.options();
+ for (int i = 0; i < options.uninterpreted_option_size(); ++i) {
+ const UninterpretedOption& uninterpreted = options.uninterpreted_option(i);
+ if (uninterpreted.name_size() == 1 &&
+ uninterpreted.name(0).name_part() == "message_set_wire_format" &&
+ uninterpreted.identifier_value() == "true") {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Modifies any extension ranges that specified 'max' as the end of the
+// extension range, and sets them to the type-specific maximum. The actual max
+// tag number can only be determined after all options have been parsed.
+void AdjustExtensionRangesWithMaxEndNumber(DescriptorProto* message) {
+ const bool is_message_set = IsMessageSetWireFormatMessage(*message);
+ const int max_extension_number = is_message_set ?
+ kint32max :
+ FieldDescriptor::kMaxNumber + 1;
+ for (int i = 0; i < message->extension_range_size(); ++i) {
+ if (message->extension_range(i).end() == kMaxExtensionRangeSentinel) {
+ message->mutable_extension_range(i)->set_end(max_extension_number);
+ }
+ }
+}
+
+} // namespace
+
+bool Parser::ParseMessageBlock(DescriptorProto* message,
+ const LocationRecorder& message_location,
+ const FileDescriptorProto* containing_file) {
+ DO(ConsumeEndOfDeclaration("{", &message_location));
+
+ while (!TryConsumeEndOfDeclaration("}", NULL)) {
if (AtEnd()) {
AddError("Reached end of input in message definition (missing '}').");
return false;
}
- if (!ParseMessageStatement(message)) {
+ if (!ParseMessageStatement(message, message_location, containing_file)) {
// This statement failed to parse. Skip it, but keep looping to parse
// other statements.
SkipStatement();
}
}
+ if (message->extension_range_size() > 0) {
+ AdjustExtensionRangesWithMaxEndNumber(message);
+ }
return true;
}
-bool Parser::ParseMessageStatement(DescriptorProto* message) {
- if (TryConsume(";")) {
+bool Parser::ParseMessageStatement(DescriptorProto* message,
+ const LocationRecorder& message_location,
+ const FileDescriptorProto* containing_file) {
+ if (TryConsumeEndOfDeclaration(";", NULL)) {
// empty statement; ignore
return true;
} else if (LookingAt("message")) {
- return ParseMessageDefinition(message->add_nested_type());
+ LocationRecorder location(message_location,
+ DescriptorProto::kNestedTypeFieldNumber,
+ message->nested_type_size());
+ return ParseMessageDefinition(message->add_nested_type(), location,
+ containing_file);
} else if (LookingAt("enum")) {
- return ParseEnumDefinition(message->add_enum_type());
+ LocationRecorder location(message_location,
+ DescriptorProto::kEnumTypeFieldNumber,
+ message->enum_type_size());
+ return ParseEnumDefinition(message->add_enum_type(), location,
+ containing_file);
} else if (LookingAt("extensions")) {
- return ParseExtensions(message);
+ LocationRecorder location(message_location,
+ DescriptorProto::kExtensionRangeFieldNumber);
+ return ParseExtensions(message, location, containing_file);
} else if (LookingAt("extend")) {
+ LocationRecorder location(message_location,
+ DescriptorProto::kExtensionFieldNumber);
return ParseExtend(message->mutable_extension(),
- message->mutable_nested_type());
+ message->mutable_nested_type(),
+ message_location,
+ DescriptorProto::kNestedTypeFieldNumber,
+ location, containing_file);
} else if (LookingAt("option")) {
- return ParseOption(message->mutable_options());
+ LocationRecorder location(message_location,
+ DescriptorProto::kOptionsFieldNumber);
+ return ParseOption(message->mutable_options(), location,
+ containing_file, OPTION_STATEMENT);
+ } else if (LookingAt("oneof")) {
+ int oneof_index = message->oneof_decl_size();
+ LocationRecorder oneof_location(message_location,
+ DescriptorProto::kOneofDeclFieldNumber,
+ oneof_index);
+
+ return ParseOneof(message->add_oneof_decl(), message,
+ oneof_index, oneof_location, message_location,
+ containing_file);
} else {
+ LocationRecorder location(message_location,
+ DescriptorProto::kFieldFieldNumber,
+ message->field_size());
return ParseMessageField(message->add_field(),
- message->mutable_nested_type());
+ message->mutable_nested_type(),
+ message_location,
+ DescriptorProto::kNestedTypeFieldNumber,
+ location,
+ containing_file);
}
}
bool Parser::ParseMessageField(FieldDescriptorProto* field,
- RepeatedPtrField<DescriptorProto>* messages) {
- // Parse label and type.
- FieldDescriptorProto::Label label;
- DO(ParseLabel(&label));
- field->set_label(label);
-
- RecordLocation(field, DescriptorPool::ErrorCollector::TYPE);
- FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32;
- string type_name;
- DO(ParseType(&type, &type_name));
- if (type_name.empty()) {
- field->set_type(type);
- } else {
- field->set_type_name(type_name);
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file) {
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kLabelFieldNumber);
+ FieldDescriptorProto::Label label;
+ DO(ParseLabel(&label, containing_file));
+ field->set_label(label);
+ }
+
+ return ParseMessageFieldNoLabel(field, messages, parent_location,
+ location_field_number_for_nested_type,
+ field_location,
+ containing_file);
+}
+
+bool Parser::ParseMessageFieldNoLabel(
+ FieldDescriptorProto* field,
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file) {
+ // Parse type.
+ {
+ LocationRecorder location(field_location); // add path later
+ location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::TYPE);
+
+ FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32;
+ string type_name;
+ DO(ParseType(&type, &type_name));
+ if (type_name.empty()) {
+ location.AddPath(FieldDescriptorProto::kTypeFieldNumber);
+ field->set_type(type);
+ } else {
+ location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber);
+ field->set_type_name(type_name);
+ }
}
// Parse name and '='.
- RecordLocation(field, DescriptorPool::ErrorCollector::NAME);
io::Tokenizer::Token name_token = input_->current();
- DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
+ }
DO(Consume("=", "Missing field number."));
// Parse field number.
- RecordLocation(field, DescriptorPool::ErrorCollector::NUMBER);
- int number;
- DO(ConsumeInteger(&number, "Expected field number."));
- field->set_number(number);
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kNumberFieldNumber);
+ location.RecordLegacyLocation(
+ field, DescriptorPool::ErrorCollector::NUMBER);
+ int number;
+ DO(ConsumeInteger(&number, "Expected field number."));
+ field->set_number(number);
+ }
// Parse options.
- DO(ParseFieldOptions(field));
+ DO(ParseFieldOptions(field, field_location, containing_file));
// Deal with groups.
- if (type_name.empty() && type == FieldDescriptorProto::TYPE_GROUP) {
+ if (field->has_type() && field->type() == FieldDescriptorProto::TYPE_GROUP) {
+ // Awkward: Since a group declares both a message type and a field, we
+ // have to create overlapping locations.
+ LocationRecorder group_location(parent_location);
+ group_location.StartAt(field_location);
+ group_location.AddPath(location_field_number_for_nested_type);
+ group_location.AddPath(messages->size());
+
DescriptorProto* group = messages->Add();
group->set_name(field->name());
+
// Record name location to match the field name's location.
- RecordLocation(group, DescriptorPool::ErrorCollector::NAME,
- name_token.line, name_token.column);
+ {
+ LocationRecorder location(group_location,
+ DescriptorProto::kNameFieldNumber);
+ location.StartAt(name_token);
+ location.EndAt(name_token);
+ location.RecordLegacyLocation(
+ group, DescriptorPool::ErrorCollector::NAME);
+ }
+
+ // The field's type_name also comes from the name. Confusing!
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kTypeNameFieldNumber);
+ location.StartAt(name_token);
+ location.EndAt(name_token);
+ }
// As a hack for backwards-compatibility, we force the group name to start
// with a capital letter and lower-case the field name. New code should
@@ -490,27 +772,37 @@ bool Parser::ParseMessageField(FieldDescriptorProto* field,
field->set_type_name(group->name());
if (LookingAt("{")) {
- DO(ParseMessageBlock(group));
+ DO(ParseMessageBlock(group, group_location, containing_file));
} else {
AddError("Missing group body.");
return false;
}
} else {
- DO(Consume(";"));
+ DO(ConsumeEndOfDeclaration(";", &field_location));
}
return true;
}
-bool Parser::ParseFieldOptions(FieldDescriptorProto* field) {
- if (!TryConsume("[")) return true;
+bool Parser::ParseFieldOptions(FieldDescriptorProto* field,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file) {
+ if (!LookingAt("[")) return true;
+
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kOptionsFieldNumber);
+
+ DO(Consume("["));
// Parse field options.
do {
if (LookingAt("default")) {
- DO(ParseDefaultAssignment(field));
+ // We intentionally pass field_location rather than location here, since
+ // the default value is not actually an option.
+ DO(ParseDefaultAssignment(field, field_location, containing_file));
} else {
- DO(ParseOptionAssignment(field->mutable_options()));
+ DO(ParseOption(field->mutable_options(), location,
+ containing_file, OPTION_ASSIGNMENT));
}
} while (TryConsume(","));
@@ -518,7 +810,10 @@ bool Parser::ParseFieldOptions(FieldDescriptorProto* field) {
return true;
}
-bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
+bool Parser::ParseDefaultAssignment(
+ FieldDescriptorProto* field,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file) {
if (field->has_default_value()) {
AddError("Already set option \"default\".");
field->clear_default_value();
@@ -527,13 +822,24 @@ bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
DO(Consume("default"));
DO(Consume("="));
- RecordLocation(field, DescriptorPool::ErrorCollector::DEFAULT_VALUE);
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kDefaultValueFieldNumber);
+ location.RecordLegacyLocation(
+ field, DescriptorPool::ErrorCollector::DEFAULT_VALUE);
string* default_value = field->mutable_default_value();
if (!field->has_type()) {
// The field has a type name, but we don't know if it is a message or an
- // enum yet. Assume an enum for now.
- DO(ConsumeIdentifier(default_value, "Expected identifier."));
+ // enum yet. (If it were a primitive type, |field| would have a type set
+ // already.) In this case, simply take the current string as the default
+ // value; we will catch the error later if it is not a valid enum value.
+ // (N.B. that we do not check whether the current token is an identifier:
+ // doing so throws strange errors when the user mistypes a primitive
+ // typename and we assume it's an enum. E.g.: "optional int foo = 1 [default
+ // = 42]". In such a case the fundamental error is really that "int" is not
+ // a type, not that "42" is not an identifier. See b/12533582.)
+ *default_value = input_->current().text;
+ input_->Next();
return true;
}
@@ -559,7 +865,8 @@ bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
}
// Parse the integer to verify that it is not out-of-range.
uint64 value;
- DO(ConsumeInteger64(max_value, &value, "Expected integer."));
+ DO(ConsumeInteger64(max_value, &value,
+ "Expected integer for field default value."));
// And stringify it again.
default_value->append(SimpleItoa(value));
break;
@@ -581,7 +888,8 @@ bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
}
// Parse the integer to verify that it is not out-of-range.
uint64 value;
- DO(ConsumeInteger64(max_value, &value, "Expected integer."));
+ DO(ConsumeInteger64(max_value, &value,
+ "Expected integer for field default value."));
// And stringify it again.
default_value->append(SimpleItoa(value));
break;
@@ -613,7 +921,11 @@ bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
break;
case FieldDescriptorProto::TYPE_STRING:
- DO(ConsumeString(default_value, "Expected string."));
+ // Note: When file opton java_string_check_utf8 is true, if a
+ // non-string representation (eg byte[]) is later supported, it must
+ // be checked for UTF-8-ness.
+ DO(ConsumeString(default_value, "Expected string for field default "
+ "value."));
break;
case FieldDescriptorProto::TYPE_BYTES:
@@ -622,7 +934,8 @@ bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
break;
case FieldDescriptorProto::TYPE_ENUM:
- DO(ConsumeIdentifier(default_value, "Expected identifier."));
+ DO(ConsumeIdentifier(default_value, "Expected enum identifier for field "
+ "default value."));
break;
case FieldDescriptorProto::TYPE_MESSAGE:
@@ -634,26 +947,36 @@ bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
return true;
}
-bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option) {
+bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
+ const LocationRecorder& part_location,
+ const FileDescriptorProto* containing_file) {
UninterpretedOption::NamePart* name = uninterpreted_option->add_name();
string identifier; // We parse identifiers into this string.
if (LookingAt("(")) { // This is an extension.
DO(Consume("("));
- // An extension name consists of dot-separated identifiers, and may begin
- // with a dot.
- if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
- DO(ConsumeIdentifier(&identifier, "Expected identifier."));
- name->mutable_name_part()->append(identifier);
- }
- while (LookingAt(".")) {
- DO(Consume("."));
- name->mutable_name_part()->append(".");
- DO(ConsumeIdentifier(&identifier, "Expected identifier."));
- name->mutable_name_part()->append(identifier);
+
+ {
+ LocationRecorder location(
+ part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
+ // An extension name consists of dot-separated identifiers, and may begin
+ // with a dot.
+ if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ name->mutable_name_part()->append(identifier);
+ }
+ while (LookingAt(".")) {
+ DO(Consume("."));
+ name->mutable_name_part()->append(".");
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ name->mutable_name_part()->append(identifier);
+ }
}
+
DO(Consume(")"));
name->set_is_extension(true);
} else { // This is a regular field.
+ LocationRecorder location(
+ part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
DO(ConsumeIdentifier(&identifier, "Expected identifier."));
name->mutable_name_part()->append(identifier);
name->set_is_extension(false);
@@ -661,116 +984,214 @@ bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option) {
return true;
}
+bool Parser::ParseUninterpretedBlock(string* value) {
+ // Note that enclosing braces are not added to *value.
+ // We do NOT use ConsumeEndOfStatement for this brace because it's delimiting
+ // an expression, not a block of statements.
+ DO(Consume("{"));
+ int brace_depth = 1;
+ while (!AtEnd()) {
+ if (LookingAt("{")) {
+ brace_depth++;
+ } else if (LookingAt("}")) {
+ brace_depth--;
+ if (brace_depth == 0) {
+ input_->Next();
+ return true;
+ }
+ }
+ // TODO(sanjay): Interpret line/column numbers to preserve formatting
+ if (!value->empty()) value->push_back(' ');
+ value->append(input_->current().text);
+ input_->Next();
+ }
+ AddError("Unexpected end of stream while parsing aggregate value.");
+ return false;
+}
+
// We don't interpret the option here. Instead we store it in an
// UninterpretedOption, to be interpreted later.
-bool Parser::ParseOptionAssignment(Message* options) {
+bool Parser::ParseOption(Message* options,
+ const LocationRecorder& options_location,
+ const FileDescriptorProto* containing_file,
+ OptionStyle style) {
// Create an entry in the uninterpreted_option field.
const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()->
FindFieldByName("uninterpreted_option");
GOOGLE_CHECK(uninterpreted_option_field != NULL)
<< "No field named \"uninterpreted_option\" in the Options proto.";
+ const Reflection* reflection = options->GetReflection();
+
+ LocationRecorder location(
+ options_location, uninterpreted_option_field->number(),
+ reflection->FieldSize(*options, uninterpreted_option_field));
+
+ if (style == OPTION_STATEMENT) {
+ DO(Consume("option"));
+ }
+
UninterpretedOption* uninterpreted_option = down_cast<UninterpretedOption*>(
options->GetReflection()->AddMessage(options,
uninterpreted_option_field));
// Parse dot-separated name.
- RecordLocation(uninterpreted_option,
- DescriptorPool::ErrorCollector::OPTION_NAME);
-
- DO(ParseOptionNamePart(uninterpreted_option));
+ {
+ LocationRecorder name_location(location,
+ UninterpretedOption::kNameFieldNumber);
+ name_location.RecordLegacyLocation(
+ uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_NAME);
+
+ {
+ LocationRecorder part_location(name_location,
+ uninterpreted_option->name_size());
+ DO(ParseOptionNamePart(uninterpreted_option, part_location,
+ containing_file));
+ }
- while (LookingAt(".")) {
- DO(Consume("."));
- DO(ParseOptionNamePart(uninterpreted_option));
+ while (LookingAt(".")) {
+ DO(Consume("."));
+ LocationRecorder part_location(name_location,
+ uninterpreted_option->name_size());
+ DO(ParseOptionNamePart(uninterpreted_option, part_location,
+ containing_file));
+ }
}
DO(Consume("="));
- RecordLocation(uninterpreted_option,
- DescriptorPool::ErrorCollector::OPTION_VALUE);
+ {
+ LocationRecorder value_location(location);
+ value_location.RecordLegacyLocation(
+ uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE);
- // All values are a single token, except for negative numbers, which consist
- // of a single '-' symbol, followed by a positive number.
- bool is_negative = TryConsume("-");
+ // All values are a single token, except for negative numbers, which consist
+ // of a single '-' symbol, followed by a positive number.
+ bool is_negative = TryConsume("-");
- switch (input_->current().type) {
- case io::Tokenizer::TYPE_START:
- GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read.";
- return false;
-
- case io::Tokenizer::TYPE_END:
- AddError("Unexpected end of stream while parsing option value.");
- return false;
+ switch (input_->current().type) {
+ case io::Tokenizer::TYPE_START:
+ GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read.";
+ return false;
- case io::Tokenizer::TYPE_IDENTIFIER: {
- if (is_negative) {
- AddError("Invalid '-' symbol before identifier.");
+ case io::Tokenizer::TYPE_END:
+ AddError("Unexpected end of stream while parsing option value.");
return false;
+
+ case io::Tokenizer::TYPE_IDENTIFIER: {
+ value_location.AddPath(
+ UninterpretedOption::kIdentifierValueFieldNumber);
+ if (is_negative) {
+ AddError("Invalid '-' symbol before identifier.");
+ return false;
+ }
+ string value;
+ DO(ConsumeIdentifier(&value, "Expected identifier."));
+ uninterpreted_option->set_identifier_value(value);
+ break;
}
- string value;
- DO(ConsumeIdentifier(&value, "Expected identifier."));
- uninterpreted_option->set_identifier_value(value);
- break;
- }
- case io::Tokenizer::TYPE_INTEGER: {
- uint64 value;
- uint64 max_value =
- is_negative ? static_cast<uint64>(kint64max) + 1 : kuint64max;
- DO(ConsumeInteger64(max_value, &value, "Expected integer."));
- if (is_negative) {
- uninterpreted_option->set_negative_int_value(-value);
- } else {
- uninterpreted_option->set_positive_int_value(value);
+ case io::Tokenizer::TYPE_INTEGER: {
+ uint64 value;
+ uint64 max_value =
+ is_negative ? static_cast<uint64>(kint64max) + 1 : kuint64max;
+ DO(ConsumeInteger64(max_value, &value, "Expected integer."));
+ if (is_negative) {
+ value_location.AddPath(
+ UninterpretedOption::kNegativeIntValueFieldNumber);
+ uninterpreted_option->set_negative_int_value(
+ -static_cast<int64>(value));
+ } else {
+ value_location.AddPath(
+ UninterpretedOption::kPositiveIntValueFieldNumber);
+ uninterpreted_option->set_positive_int_value(value);
+ }
+ break;
}
- break;
- }
- case io::Tokenizer::TYPE_FLOAT: {
- double value;
- DO(ConsumeNumber(&value, "Expected number."));
- uninterpreted_option->set_double_value(is_negative ? -value : value);
- break;
- }
+ case io::Tokenizer::TYPE_FLOAT: {
+ value_location.AddPath(UninterpretedOption::kDoubleValueFieldNumber);
+ double value;
+ DO(ConsumeNumber(&value, "Expected number."));
+ uninterpreted_option->set_double_value(is_negative ? -value : value);
+ break;
+ }
- case io::Tokenizer::TYPE_STRING: {
- if (is_negative) {
- AddError("Invalid '-' symbol before string.");
- return false;
+ case io::Tokenizer::TYPE_STRING: {
+ value_location.AddPath(UninterpretedOption::kStringValueFieldNumber);
+ if (is_negative) {
+ AddError("Invalid '-' symbol before string.");
+ return false;
+ }
+ string value;
+ DO(ConsumeString(&value, "Expected string."));
+ uninterpreted_option->set_string_value(value);
+ break;
}
- string value;
- DO(ConsumeString(&value, "Expected string."));
- uninterpreted_option->set_string_value(value);
- break;
+
+ case io::Tokenizer::TYPE_SYMBOL:
+ if (LookingAt("{")) {
+ value_location.AddPath(
+ UninterpretedOption::kAggregateValueFieldNumber);
+ DO(ParseUninterpretedBlock(
+ uninterpreted_option->mutable_aggregate_value()));
+ } else {
+ AddError("Expected option value.");
+ return false;
+ }
+ break;
}
+ }
- case io::Tokenizer::TYPE_SYMBOL:
- AddError("Expected option value.");
- return false;
+ if (style == OPTION_STATEMENT) {
+ DO(ConsumeEndOfDeclaration(";", &location));
}
+
return true;
}
-bool Parser::ParseExtensions(DescriptorProto* message) {
+bool Parser::ParseExtensions(DescriptorProto* message,
+ const LocationRecorder& extensions_location,
+ const FileDescriptorProto* containing_file) {
// Parse the declaration.
DO(Consume("extensions"));
do {
+ // Note that kExtensionRangeFieldNumber was already pushed by the parent.
+ LocationRecorder location(extensions_location,
+ message->extension_range_size());
+
DescriptorProto::ExtensionRange* range = message->add_extension_range();
- RecordLocation(range, DescriptorPool::ErrorCollector::NUMBER);
+ location.RecordLegacyLocation(
+ range, DescriptorPool::ErrorCollector::NUMBER);
int start, end;
- DO(ConsumeInteger(&start, "Expected field number range."));
+ io::Tokenizer::Token start_token;
+
+ {
+ LocationRecorder start_location(
+ location, DescriptorProto::ExtensionRange::kStartFieldNumber);
+ start_token = input_->current();
+ DO(ConsumeInteger(&start, "Expected field number range."));
+ }
if (TryConsume("to")) {
+ LocationRecorder end_location(
+ location, DescriptorProto::ExtensionRange::kEndFieldNumber);
if (TryConsume("max")) {
- end = FieldDescriptor::kMaxNumber;
+ // Set to the sentinel value - 1 since we increment the value below.
+ // The actual value of the end of the range should be set with
+ // AdjustExtensionRangesWithMaxEndNumber.
+ end = kMaxExtensionRangeSentinel - 1;
} else {
DO(ConsumeInteger(&end, "Expected integer."));
}
} else {
+ LocationRecorder end_location(
+ location, DescriptorProto::ExtensionRange::kEndFieldNumber);
+ end_location.StartAt(start_token);
+ end_location.EndAt(start_token);
end = start;
}
@@ -782,24 +1203,26 @@ bool Parser::ParseExtensions(DescriptorProto* message) {
range->set_end(end);
} while (TryConsume(","));
- DO(Consume(";"));
+ DO(ConsumeEndOfDeclaration(";", &extensions_location));
return true;
}
bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
- RepeatedPtrField<DescriptorProto>* messages) {
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& extend_location,
+ const FileDescriptorProto* containing_file) {
DO(Consume("extend"));
- // We expect to see at least one extension field defined in the extend block.
- // We need to create it now so we can record the extendee's location.
- FieldDescriptorProto* first_field = extensions->Add();
-
// Parse the extendee type.
- RecordLocation(first_field, DescriptorPool::ErrorCollector::EXTENDEE);
- DO(ParseUserDefinedType(first_field->mutable_extendee()));
+ io::Tokenizer::Token extendee_start = input_->current();
+ string extendee;
+ DO(ParseUserDefinedType(&extendee));
+ io::Tokenizer::Token extendee_end = input_->previous();
// Parse the block.
- DO(Consume("{"));
+ DO(ConsumeEndOfDeclaration("{", &extend_location));
bool is_first = true;
@@ -809,21 +1232,92 @@ bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
return false;
}
- FieldDescriptorProto* field;
- if (is_first) {
- field = first_field;
- is_first = false;
- } else {
- field = extensions->Add();
- field->set_extendee(first_field->extendee());
+ // Note that kExtensionFieldNumber was already pushed by the parent.
+ LocationRecorder location(extend_location, extensions->size());
+
+ FieldDescriptorProto* field = extensions->Add();
+
+ {
+ LocationRecorder extendee_location(
+ location, FieldDescriptorProto::kExtendeeFieldNumber);
+ extendee_location.StartAt(extendee_start);
+ extendee_location.EndAt(extendee_end);
+
+ if (is_first) {
+ extendee_location.RecordLegacyLocation(
+ field, DescriptorPool::ErrorCollector::EXTENDEE);
+ is_first = false;
+ }
}
- if (!ParseMessageField(field, messages)) {
+ field->set_extendee(extendee);
+
+ if (!ParseMessageField(field, messages, parent_location,
+ location_field_number_for_nested_type,
+ location,
+ containing_file)) {
// This statement failed to parse. Skip it, but keep looping to parse
// other statements.
SkipStatement();
}
- } while(!TryConsume("}"));
+ } while (!TryConsumeEndOfDeclaration("}", NULL));
+
+ return true;
+}
+
+bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl,
+ DescriptorProto* containing_type,
+ int oneof_index,
+ const LocationRecorder& oneof_location,
+ const LocationRecorder& containing_type_location,
+ const FileDescriptorProto* containing_file) {
+ DO(Consume("oneof"));
+
+ {
+ LocationRecorder name_location(oneof_location,
+ OneofDescriptorProto::kNameFieldNumber);
+ DO(ConsumeIdentifier(oneof_decl->mutable_name(), "Expected oneof name."));
+ }
+
+ DO(ConsumeEndOfDeclaration("{", &oneof_location));
+
+ do {
+ if (AtEnd()) {
+ AddError("Reached end of input in oneof definition (missing '}').");
+ return false;
+ }
+
+ // Print a nice error if the user accidentally tries to place a label
+ // on an individual member of a oneof.
+ if (LookingAt("required") ||
+ LookingAt("optional") ||
+ LookingAt("repeated")) {
+ AddError("Fields in oneofs must not have labels (required / optional "
+ "/ repeated).");
+ // We can continue parsing here because we understand what the user
+ // meant. The error report will still make parsing fail overall.
+ input_->Next();
+ }
+
+ LocationRecorder field_location(containing_type_location,
+ DescriptorProto::kFieldFieldNumber,
+ containing_type->field_size());
+
+ FieldDescriptorProto* field = containing_type->add_field();
+ field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
+ field->set_oneof_index(oneof_index);
+
+ if (!ParseMessageFieldNoLabel(field,
+ containing_type->mutable_nested_type(),
+ containing_type_location,
+ DescriptorProto::kNestedTypeFieldNumber,
+ field_location,
+ containing_file)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
+ }
+ } while (!TryConsumeEndOfDeclaration("}", NULL));
return true;
}
@@ -831,24 +1325,35 @@ bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
// -------------------------------------------------------------------
// Enums
-bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type) {
+bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location,
+ const FileDescriptorProto* containing_file) {
DO(Consume("enum"));
- RecordLocation(enum_type, DescriptorPool::ErrorCollector::NAME);
- DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name."));
- DO(ParseEnumBlock(enum_type));
+
+ {
+ LocationRecorder location(enum_location,
+ EnumDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ enum_type, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name."));
+ }
+
+ DO(ParseEnumBlock(enum_type, enum_location, containing_file));
return true;
}
-bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type) {
- DO(Consume("{"));
+bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location,
+ const FileDescriptorProto* containing_file) {
+ DO(ConsumeEndOfDeclaration("{", &enum_location));
- while (!TryConsume("}")) {
+ while (!TryConsumeEndOfDeclaration("}", NULL)) {
if (AtEnd()) {
AddError("Reached end of input in enum definition (missing '}').");
return false;
}
- if (!ParseEnumStatement(enum_type)) {
+ if (!ParseEnumStatement(enum_type, enum_location, containing_file)) {
// This statement failed to parse. Skip it, but keep looping to parse
// other statements.
SkipStatement();
@@ -858,41 +1363,73 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type) {
return true;
}
-bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type) {
- if (TryConsume(";")) {
+bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location,
+ const FileDescriptorProto* containing_file) {
+ if (TryConsumeEndOfDeclaration(";", NULL)) {
// empty statement; ignore
return true;
} else if (LookingAt("option")) {
- return ParseOption(enum_type->mutable_options());
+ LocationRecorder location(enum_location,
+ EnumDescriptorProto::kOptionsFieldNumber);
+ return ParseOption(enum_type->mutable_options(), location,
+ containing_file, OPTION_STATEMENT);
} else {
- return ParseEnumConstant(enum_type->add_value());
+ LocationRecorder location(enum_location,
+ EnumDescriptorProto::kValueFieldNumber, enum_type->value_size());
+ return ParseEnumConstant(enum_type->add_value(), location, containing_file);
}
}
-bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value) {
- RecordLocation(enum_value, DescriptorPool::ErrorCollector::NAME);
- DO(ConsumeIdentifier(enum_value->mutable_name(),
- "Expected enum constant name."));
+bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value,
+ const LocationRecorder& enum_value_location,
+ const FileDescriptorProto* containing_file) {
+ // Parse name.
+ {
+ LocationRecorder location(enum_value_location,
+ EnumValueDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ enum_value, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(enum_value->mutable_name(),
+ "Expected enum constant name."));
+ }
+
DO(Consume("=", "Missing numeric value for enum constant."));
- bool is_negative = TryConsume("-");
- int number;
- DO(ConsumeInteger(&number, "Expected integer."));
- if (is_negative) number *= -1;
- enum_value->set_number(number);
+ // Parse value.
+ {
+ LocationRecorder location(
+ enum_value_location, EnumValueDescriptorProto::kNumberFieldNumber);
+ location.RecordLegacyLocation(
+ enum_value, DescriptorPool::ErrorCollector::NUMBER);
- DO(ParseEnumConstantOptions(enum_value));
+ int number;
+ DO(ConsumeSignedInteger(&number, "Expected integer."));
+ enum_value->set_number(number);
+ }
- DO(Consume(";"));
+ DO(ParseEnumConstantOptions(enum_value, enum_value_location,
+ containing_file));
+
+ DO(ConsumeEndOfDeclaration(";", &enum_value_location));
return true;
}
-bool Parser::ParseEnumConstantOptions(EnumValueDescriptorProto* value) {
- if (!TryConsume("[")) return true;
+bool Parser::ParseEnumConstantOptions(
+ EnumValueDescriptorProto* value,
+ const LocationRecorder& enum_value_location,
+ const FileDescriptorProto* containing_file) {
+ if (!LookingAt("[")) return true;
+
+ LocationRecorder location(
+ enum_value_location, EnumValueDescriptorProto::kOptionsFieldNumber);
+
+ DO(Consume("["));
do {
- DO(ParseOptionAssignment(value->mutable_options()));
+ DO(ParseOption(value->mutable_options(), location,
+ containing_file, OPTION_ASSIGNMENT));
} while (TryConsume(","));
DO(Consume("]"));
@@ -902,24 +1439,36 @@ bool Parser::ParseEnumConstantOptions(EnumValueDescriptorProto* value) {
// -------------------------------------------------------------------
// Services
-bool Parser::ParseServiceDefinition(ServiceDescriptorProto* service) {
+bool Parser::ParseServiceDefinition(
+ ServiceDescriptorProto* service,
+ const LocationRecorder& service_location,
+ const FileDescriptorProto* containing_file) {
DO(Consume("service"));
- RecordLocation(service, DescriptorPool::ErrorCollector::NAME);
- DO(ConsumeIdentifier(service->mutable_name(), "Expected service name."));
- DO(ParseServiceBlock(service));
+
+ {
+ LocationRecorder location(service_location,
+ ServiceDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ service, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(service->mutable_name(), "Expected service name."));
+ }
+
+ DO(ParseServiceBlock(service, service_location, containing_file));
return true;
}
-bool Parser::ParseServiceBlock(ServiceDescriptorProto* service) {
- DO(Consume("{"));
+bool Parser::ParseServiceBlock(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location,
+ const FileDescriptorProto* containing_file) {
+ DO(ConsumeEndOfDeclaration("{", &service_location));
- while (!TryConsume("}")) {
+ while (!TryConsumeEndOfDeclaration("}", NULL)) {
if (AtEnd()) {
AddError("Reached end of input in service definition (missing '}').");
return false;
}
- if (!ParseServiceStatement(service)) {
+ if (!ParseServiceStatement(service, service_location, containing_file)) {
// This statement failed to parse. Skip it, but keep looping to parse
// other statements.
SkipStatement();
@@ -929,55 +1478,98 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service) {
return true;
}
-bool Parser::ParseServiceStatement(ServiceDescriptorProto* service) {
- if (TryConsume(";")) {
+bool Parser::ParseServiceStatement(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location,
+ const FileDescriptorProto* containing_file) {
+ if (TryConsumeEndOfDeclaration(";", NULL)) {
// empty statement; ignore
return true;
} else if (LookingAt("option")) {
- return ParseOption(service->mutable_options());
+ LocationRecorder location(
+ service_location, ServiceDescriptorProto::kOptionsFieldNumber);
+ return ParseOption(service->mutable_options(), location,
+ containing_file, OPTION_STATEMENT);
} else {
- return ParseServiceMethod(service->add_method());
+ LocationRecorder location(service_location,
+ ServiceDescriptorProto::kMethodFieldNumber, service->method_size());
+ return ParseServiceMethod(service->add_method(), location, containing_file);
}
}
-bool Parser::ParseServiceMethod(MethodDescriptorProto* method) {
+bool Parser::ParseServiceMethod(MethodDescriptorProto* method,
+ const LocationRecorder& method_location,
+ const FileDescriptorProto* containing_file) {
DO(Consume("rpc"));
- RecordLocation(method, DescriptorPool::ErrorCollector::NAME);
- DO(ConsumeIdentifier(method->mutable_name(), "Expected method name."));
+
+ {
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ method, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(method->mutable_name(), "Expected method name."));
+ }
// Parse input type.
DO(Consume("("));
- RecordLocation(method, DescriptorPool::ErrorCollector::INPUT_TYPE);
- DO(ParseUserDefinedType(method->mutable_input_type()));
+ {
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kInputTypeFieldNumber);
+ location.RecordLegacyLocation(
+ method, DescriptorPool::ErrorCollector::INPUT_TYPE);
+ DO(ParseUserDefinedType(method->mutable_input_type()));
+ }
DO(Consume(")"));
// Parse output type.
DO(Consume("returns"));
DO(Consume("("));
- RecordLocation(method, DescriptorPool::ErrorCollector::OUTPUT_TYPE);
- DO(ParseUserDefinedType(method->mutable_output_type()));
+ {
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kOutputTypeFieldNumber);
+ location.RecordLegacyLocation(
+ method, DescriptorPool::ErrorCollector::OUTPUT_TYPE);
+ DO(ParseUserDefinedType(method->mutable_output_type()));
+ }
DO(Consume(")"));
- if (TryConsume("{")) {
+ if (LookingAt("{")) {
// Options!
- while (!TryConsume("}")) {
- if (AtEnd()) {
- AddError("Reached end of input in method options (missing '}').");
- return false;
- }
+ DO(ParseOptions(method_location,
+ containing_file,
+ MethodDescriptorProto::kOptionsFieldNumber,
+ method->mutable_options()));
+ } else {
+ DO(ConsumeEndOfDeclaration(";", &method_location));
+ }
- if (TryConsume(";")) {
- // empty statement; ignore
- } else {
- if (!ParseOption(method->mutable_options())) {
- // This statement failed to parse. Skip it, but keep looping to
- // parse other statements.
- SkipStatement();
- }
+ return true;
+}
+
+
+bool Parser::ParseOptions(const LocationRecorder& parent_location,
+ const FileDescriptorProto* containing_file,
+ const int optionsFieldNumber,
+ Message* mutable_options) {
+ // Options!
+ ConsumeEndOfDeclaration("{", &parent_location);
+ while (!TryConsumeEndOfDeclaration("}", NULL)) {
+ if (AtEnd()) {
+ AddError("Reached end of input in method options (missing '}').");
+ return false;
+ }
+
+ if (TryConsumeEndOfDeclaration(";", NULL)) {
+ // empty statement; ignore
+ } else {
+ LocationRecorder location(parent_location,
+ optionsFieldNumber);
+ if (!ParseOption(mutable_options, location, containing_file,
+ OPTION_STATEMENT)) {
+ // This statement failed to parse. Skip it, but keep looping to
+ // parse other statements.
+ SkipStatement();
}
}
- } else {
- DO(Consume(";"));
}
return true;
@@ -985,7 +1577,8 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method) {
// -------------------------------------------------------------------
-bool Parser::ParseLabel(FieldDescriptorProto::Label* label) {
+bool Parser::ParseLabel(FieldDescriptorProto::Label* label,
+ const FileDescriptorProto* containing_file) {
if (TryConsume("optional")) {
*label = FieldDescriptorProto::LABEL_OPTIONAL;
return true;
@@ -1053,7 +1646,9 @@ bool Parser::ParseUserDefinedType(string* type_name) {
// ===================================================================
-bool Parser::ParsePackage(FileDescriptorProto* file) {
+bool Parser::ParsePackage(FileDescriptorProto* file,
+ const LocationRecorder& root_location,
+ const FileDescriptorProto* containing_file) {
if (file->has_package()) {
AddError("Multiple package definitions.");
// Don't append the new package to the old one. Just replace it. Not
@@ -1063,32 +1658,57 @@ bool Parser::ParsePackage(FileDescriptorProto* file) {
DO(Consume("package"));
- RecordLocation(file, DescriptorPool::ErrorCollector::NAME);
+ {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kPackageFieldNumber);
+ location.RecordLegacyLocation(file, DescriptorPool::ErrorCollector::NAME);
- while (true) {
- string identifier;
- DO(ConsumeIdentifier(&identifier, "Expected identifier."));
- file->mutable_package()->append(identifier);
- if (!TryConsume(".")) break;
- file->mutable_package()->append(".");
+ while (true) {
+ string identifier;
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ file->mutable_package()->append(identifier);
+ if (!TryConsume(".")) break;
+ file->mutable_package()->append(".");
+ }
+
+ location.EndAt(input_->previous());
+
+ DO(ConsumeEndOfDeclaration(";", &location));
}
- DO(Consume(";"));
return true;
}
-bool Parser::ParseImport(string* import_filename) {
+bool Parser::ParseImport(RepeatedPtrField<string>* dependency,
+ RepeatedField<int32>* public_dependency,
+ RepeatedField<int32>* weak_dependency,
+ const LocationRecorder& root_location,
+ const FileDescriptorProto* containing_file) {
DO(Consume("import"));
- DO(ConsumeString(import_filename,
- "Expected a string naming the file to import."));
- DO(Consume(";"));
- return true;
-}
+ if (LookingAt("public")) {
+ LocationRecorder location(
+ root_location, FileDescriptorProto::kPublicDependencyFieldNumber,
+ public_dependency->size());
+ DO(Consume("public"));
+ *public_dependency->Add() = dependency->size();
+ } else if (LookingAt("weak")) {
+ LocationRecorder location(
+ root_location, FileDescriptorProto::kWeakDependencyFieldNumber,
+ weak_dependency->size());
+ DO(Consume("weak"));
+ *weak_dependency->Add() = dependency->size();
+ }
+ {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kDependencyFieldNumber,
+ dependency->size());
+ DO(ConsumeString(dependency->Add(),
+ "Expected a string naming the file to import."));
+
+ location.EndAt(input_->previous());
-bool Parser::ParseOption(Message* options) {
- DO(Consume("option"));
- DO(ParseOptionAssignment(options));
- DO(Consume(";"));
+ DO(ConsumeEndOfDeclaration(";", &location));
+ }
return true;
}
diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h
index 72c96d0..d0a2359 100644
--- a/src/google/protobuf/compiler/parser.h
+++ b/src/google/protobuf/compiler/parser.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -40,7 +40,6 @@
#include <map>
#include <string>
#include <utility>
-#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/repeated_field.h>
@@ -74,6 +73,9 @@ class LIBPROTOBUF_EXPORT Parser {
// Optional fetaures:
+ // DEPRECATED: New code should use the SourceCodeInfo embedded in the
+ // FileDescriptorProto.
+ //
// Requests that locations of certain definitions be recorded to the given
// SourceLocationTable while parsing. This can be used to look up exact line
// and column numbers for errors reported by DescriptorPool during validation.
@@ -82,7 +84,7 @@ class LIBPROTOBUF_EXPORT Parser {
source_location_table_ = location_table;
}
- // Requsets that errors be recorded to the given ErrorCollector while
+ // Requests that errors be recorded to the given ErrorCollector while
// parsing. Set to NULL (the default) to discard error messages.
void RecordErrorsTo(io::ErrorCollector* error_collector) {
error_collector_ = error_collector;
@@ -113,6 +115,8 @@ class LIBPROTOBUF_EXPORT Parser {
}
private:
+ class LocationRecorder;
+
// =================================================================
// Error recovery helpers
@@ -161,6 +165,8 @@ class LIBPROTOBUF_EXPORT Parser {
bool ConsumeIdentifier(string* output, const char* error);
// Consume an integer and store its value in "output".
bool ConsumeInteger(int* output, const char* error);
+ // Consume a signed integer and store its value in "output".
+ bool ConsumeSignedInteger(int* output, const char* error);
// Consume a 64-bit integer and store its value in "output". If the value
// is greater than max_value, an error will be reported.
bool ConsumeInteger64(uint64 max_value, uint64* output, const char* error);
@@ -170,6 +176,20 @@ class LIBPROTOBUF_EXPORT Parser {
// Consume a string literal and store its (unescaped) value in "output".
bool ConsumeString(string* output, const char* error);
+ // Consume a token representing the end of the statement. Comments between
+ // this token and the next will be harvested for documentation. The given
+ // LocationRecorder should refer to the declaration that was just parsed;
+ // it will be populated with these comments.
+ //
+ // TODO(kenton): The LocationRecorder is const because historically locations
+ // have been passed around by const reference, for no particularly good
+ // reason. We should probably go through and change them all to mutable
+ // pointer to make this more intuitive.
+ bool TryConsumeEndOfDeclaration(const char* text,
+ const LocationRecorder* location);
+ bool ConsumeEndOfDeclaration(const char* text,
+ const LocationRecorder* location);
+
// -----------------------------------------------------------------
// Error logging helpers
@@ -180,16 +200,67 @@ class LIBPROTOBUF_EXPORT Parser {
// of the current token.
void AddError(const string& error);
- // Record the given line and column and associate it with this descriptor
- // in the SourceLocationTable.
- void RecordLocation(const Message* descriptor,
- DescriptorPool::ErrorCollector::ErrorLocation location,
- int line, int column);
-
- // Record the current line and column and associate it with this descriptor
- // in the SourceLocationTable.
- void RecordLocation(const Message* descriptor,
- DescriptorPool::ErrorCollector::ErrorLocation location);
+ // Records a location in the SourceCodeInfo.location table (see
+ // descriptor.proto). We use RAII to ensure that the start and end locations
+ // are recorded -- the constructor records the start location and the
+ // destructor records the end location. Since the parser is
+ // recursive-descent, this works out beautifully.
+ class LIBPROTOBUF_EXPORT LocationRecorder {
+ public:
+ // Construct the file's "root" location.
+ LocationRecorder(Parser* parser);
+
+ // Construct a location that represents a declaration nested within the
+ // given parent. E.g. a field's location is nested within the location
+ // for a message type. The parent's path will be copied, so you should
+ // call AddPath() only to add the path components leading from the parent
+ // to the child (as opposed to leading from the root to the child).
+ LocationRecorder(const LocationRecorder& parent);
+
+ // Convenience constructors that call AddPath() one or two times.
+ LocationRecorder(const LocationRecorder& parent, int path1);
+ LocationRecorder(const LocationRecorder& parent, int path1, int path2);
+
+ ~LocationRecorder();
+
+ // Add a path component. See SourceCodeInfo.Location.path in
+ // descriptor.proto.
+ void AddPath(int path_component);
+
+ // By default the location is considered to start at the current token at
+ // the time the LocationRecorder is created. StartAt() sets the start
+ // location to the given token instead.
+ void StartAt(const io::Tokenizer::Token& token);
+
+ // Start at the same location as some other LocationRecorder.
+ void StartAt(const LocationRecorder& other);
+
+ // By default the location is considered to end at the previous token at
+ // the time the LocationRecorder is destroyed. EndAt() sets the end
+ // location to the given token instead.
+ void EndAt(const io::Tokenizer::Token& token);
+
+ // Records the start point of this location to the SourceLocationTable that
+ // was passed to RecordSourceLocationsTo(), if any. SourceLocationTable
+ // is an older way of keeping track of source locations which is still
+ // used in some places.
+ void RecordLegacyLocation(const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location);
+
+ // Attaches leading and trailing comments to the location. The two strings
+ // will be swapped into place, so after this is called *leading and
+ // *trailing will be empty.
+ //
+ // TODO(kenton): See comment on TryConsumeEndOfDeclaration(), above, for
+ // why this is const.
+ void AttachComments(string* leading, string* trailing) const;
+
+ private:
+ Parser* parser_;
+ SourceCodeInfo::Location* location_;
+
+ void Init(const LocationRecorder& parent);
+ };
// =================================================================
// Parsers for various language constructs
@@ -210,54 +281,131 @@ class LIBPROTOBUF_EXPORT Parser {
// makes logic much simpler for the caller.
// Parse a top-level message, enum, service, etc.
- bool ParseTopLevelStatement(FileDescriptorProto* file);
+ bool ParseTopLevelStatement(FileDescriptorProto* file,
+ const LocationRecorder& root_location);
// Parse various language high-level language construrcts.
- bool ParseMessageDefinition(DescriptorProto* message);
- bool ParseEnumDefinition(EnumDescriptorProto* enum_type);
- bool ParseServiceDefinition(ServiceDescriptorProto* service);
- bool ParsePackage(FileDescriptorProto* file);
- bool ParseImport(string* import_filename);
- bool ParseOption(Message* options);
+ bool ParseMessageDefinition(DescriptorProto* message,
+ const LocationRecorder& message_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseEnumDefinition(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseServiceDefinition(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location,
+ const FileDescriptorProto* containing_file);
+ bool ParsePackage(FileDescriptorProto* file,
+ const LocationRecorder& root_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseImport(RepeatedPtrField<string>* dependency,
+ RepeatedField<int32>* public_dependency,
+ RepeatedField<int32>* weak_dependency,
+ const LocationRecorder& root_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseOption(Message* options,
+ const LocationRecorder& options_location,
+ const FileDescriptorProto* containing_file);
// These methods parse the contents of a message, enum, or service type and
// add them to the given object. They consume the entire block including
// the beginning and ending brace.
- bool ParseMessageBlock(DescriptorProto* message);
- bool ParseEnumBlock(EnumDescriptorProto* enum_type);
- bool ParseServiceBlock(ServiceDescriptorProto* service);
+ bool ParseMessageBlock(DescriptorProto* message,
+ const LocationRecorder& message_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseEnumBlock(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseServiceBlock(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location,
+ const FileDescriptorProto* containing_file);
// Parse one statement within a message, enum, or service block, inclunding
// final semicolon.
- bool ParseMessageStatement(DescriptorProto* message);
- bool ParseEnumStatement(EnumDescriptorProto* message);
- bool ParseServiceStatement(ServiceDescriptorProto* message);
+ bool ParseMessageStatement(DescriptorProto* message,
+ const LocationRecorder& message_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseEnumStatement(EnumDescriptorProto* message,
+ const LocationRecorder& enum_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseServiceStatement(ServiceDescriptorProto* message,
+ const LocationRecorder& service_location,
+ const FileDescriptorProto* containing_file);
// Parse a field of a message. If the field is a group, its type will be
// added to "messages".
+ //
+ // parent_location and location_field_number_for_nested_type are needed when
+ // parsing groups -- we need to generate a nested message type within the
+ // parent and record its location accordingly. Since the parent could be
+ // either a FileDescriptorProto or a DescriptorProto, we must pass in the
+ // correct field number to use.
bool ParseMessageField(FieldDescriptorProto* field,
- RepeatedPtrField<DescriptorProto>* messages);
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file);
+
+ // Like ParseMessageField() but expects the label has already been filled in
+ // by the caller.
+ bool ParseMessageFieldNoLabel(FieldDescriptorProto* field,
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file);
// Parse an "extensions" declaration.
- bool ParseExtensions(DescriptorProto* message);
+ bool ParseExtensions(DescriptorProto* message,
+ const LocationRecorder& extensions_location,
+ const FileDescriptorProto* containing_file);
- // Parse an "extend" declaration.
+ // Parse an "extend" declaration. (See also comments for
+ // ParseMessageField().)
bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
- RepeatedPtrField<DescriptorProto>* messages);
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& extend_location,
+ const FileDescriptorProto* containing_file);
+
+ // Parse a "oneof" declaration. The caller is responsible for setting
+ // oneof_decl->label() since it will have had to parse the label before it
+ // knew it was parsing a oneof.
+ bool ParseOneof(OneofDescriptorProto* oneof_decl,
+ DescriptorProto* containing_type,
+ int oneof_index,
+ const LocationRecorder& oneof_location,
+ const LocationRecorder& containing_type_location,
+ const FileDescriptorProto* containing_file);
// Parse a single enum value within an enum block.
- bool ParseEnumConstant(EnumValueDescriptorProto* enum_value);
+ bool ParseEnumConstant(EnumValueDescriptorProto* enum_value,
+ const LocationRecorder& enum_value_location,
+ const FileDescriptorProto* containing_file);
// Parse enum constant options, i.e. the list in square brackets at the end
// of the enum constant value definition.
- bool ParseEnumConstantOptions(EnumValueDescriptorProto* value);
+ bool ParseEnumConstantOptions(EnumValueDescriptorProto* value,
+ const LocationRecorder& enum_value_location,
+ const FileDescriptorProto* containing_file);
// Parse a single method within a service definition.
- bool ParseServiceMethod(MethodDescriptorProto* method);
+ bool ParseServiceMethod(MethodDescriptorProto* method,
+ const LocationRecorder& method_location,
+ const FileDescriptorProto* containing_file);
+
+
+ // Parse options of a single method or stream.
+ bool ParseOptions(const LocationRecorder& parent_location,
+ const FileDescriptorProto* containing_file,
+ const int optionsFieldNumber,
+ Message* mutable_options);
// Parse "required", "optional", or "repeated" and fill in "label"
// with the value.
- bool ParseLabel(FieldDescriptorProto::Label* label);
+ bool ParseLabel(FieldDescriptorProto::Label* label,
+ const FileDescriptorProto* containing_file);
// Parse a type name and fill in "type" (if it is a primitive) or
// "type_name" (if it is not) with the type parsed.
@@ -269,39 +417,75 @@ class LIBPROTOBUF_EXPORT Parser {
// Parses field options, i.e. the stuff in square brackets at the end
// of a field definition. Also parses default value.
- bool ParseFieldOptions(FieldDescriptorProto* field);
+ bool ParseFieldOptions(FieldDescriptorProto* field,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file);
// Parse the "default" option. This needs special handling because its
// type is the field's type.
- bool ParseDefaultAssignment(FieldDescriptorProto* field);
+ bool ParseDefaultAssignment(FieldDescriptorProto* field,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file);
+
+ enum OptionStyle {
+ OPTION_ASSIGNMENT, // just "name = value"
+ OPTION_STATEMENT // "option name = value;"
+ };
// Parse a single option name/value pair, e.g. "ctype = CORD". The name
// identifies a field of the given Message, and the value of that field
// is set to the parsed value.
- bool ParseOptionAssignment(Message* options);
+ bool ParseOption(Message* options,
+ const LocationRecorder& options_location,
+ const FileDescriptorProto* containing_file,
+ OptionStyle style);
// Parses a single part of a multipart option name. A multipart name consists
// of names separated by dots. Each name is either an identifier or a series
// of identifiers separated by dots and enclosed in parentheses. E.g.,
// "foo.(bar.baz).qux".
- bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option);
+ bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
+ const LocationRecorder& part_location,
+ const FileDescriptorProto* containing_file);
+
+ // Parses a string surrounded by balanced braces. Strips off the outer
+ // braces and stores the enclosed string in *value.
+ // E.g.,
+ // { foo } *value gets 'foo'
+ // { foo { bar: box } } *value gets 'foo { bar: box }'
+ // {} *value gets ''
+ //
+ // REQUIRES: LookingAt("{")
+ // When finished successfully, we are looking at the first token past
+ // the ending brace.
+ bool ParseUninterpretedBlock(string* value);
// =================================================================
io::Tokenizer* input_;
io::ErrorCollector* error_collector_;
- SourceLocationTable* source_location_table_;
+ SourceCodeInfo* source_code_info_;
+ SourceLocationTable* source_location_table_; // legacy
bool had_errors_;
bool require_syntax_identifier_;
bool stop_after_syntax_identifier_;
string syntax_identifier_;
+ // Leading doc comments for the next declaration. These are not complete
+ // yet; use ConsumeEndOfDeclaration() to get the complete comments.
+ string upcoming_doc_comments_;
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser);
};
// A table mapping (descriptor, ErrorLocation) pairs -- as reported by
// DescriptorPool when validating descriptors -- to line and column numbers
// within the original source code.
+//
+// This is semi-obsolete: FileDescriptorProto.source_code_info now contains
+// far more complete information about source locations. However, as of this
+// writing you still need to use SourceLocationTable when integrating with
+// DescriptorPool.
class LIBPROTOBUF_EXPORT SourceLocationTable {
public:
SourceLocationTable();
diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc
index e2262b8..9ec29a4 100644
--- a/src/google/protobuf/compiler/parser_unittest.cc
+++ b/src/google/protobuf/compiler/parser_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,8 +32,10 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#include <memory>
#include <vector>
#include <algorithm>
+#include <map>
#include <google/protobuf/compiler/parser.h>
@@ -43,8 +45,10 @@
#include <google/protobuf/wire_format.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_custom_options.pb.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/map_util.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -118,6 +122,9 @@ class ParserTest : public testing::Test {
EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
ASSERT_EQ("", error_collector_.text_);
+ // We don't cover SourceCodeInfo in these tests.
+ actual.clear_source_code_info();
+
// Parse the ASCII representation in order to canonicalize it. We could
// just compare directly to actual.DebugString(), but that would require
// that the caller precisely match the formatting that DebugString()
@@ -430,6 +437,69 @@ TEST_F(ParseMessageTest, FieldOptions) {
"}");
}
+TEST_F(ParseMessageTest, Oneof) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " oneof foo {\n"
+ " int32 a = 1;\n"
+ " string b = 2;\n"
+ " TestMessage c = 3;\n"
+ " group D = 4 { optional int32 i = 5; }\n"
+ " }\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"a\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
+ " oneof_index:0 }"
+ " field { name:\"b\" label:LABEL_OPTIONAL type:TYPE_STRING number:2 "
+ " oneof_index:0 }"
+ " field { name:\"c\" label:LABEL_OPTIONAL type_name:\"TestMessage\" "
+ " number:3 oneof_index:0 }"
+ " field { name:\"d\" label:LABEL_OPTIONAL type:TYPE_GROUP "
+ " type_name:\"D\" number:4 oneof_index:0 }"
+ " oneof_decl {"
+ " name: \"foo\""
+ " }"
+ " nested_type {"
+ " name: \"D\""
+ " field { name:\"i\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 }"
+ " }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, MultipleOneofs) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " oneof foo {\n"
+ " int32 a = 1;\n"
+ " string b = 2;\n"
+ " }\n"
+ " oneof bar {\n"
+ " int32 c = 3;\n"
+ " string d = 4;\n"
+ " }\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"a\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
+ " oneof_index:0 }"
+ " field { name:\"b\" label:LABEL_OPTIONAL type:TYPE_STRING number:2 "
+ " oneof_index:0 }"
+ " field { name:\"c\" label:LABEL_OPTIONAL type:TYPE_INT32 number:3 "
+ " oneof_index:1 }"
+ " field { name:\"d\" label:LABEL_OPTIONAL type:TYPE_STRING number:4 "
+ " oneof_index:1 }"
+ " oneof_decl {"
+ " name: \"foo\""
+ " }"
+ " oneof_decl {"
+ " name: \"bar\""
+ " }"
+ "}");
+}
+
TEST_F(ParseMessageTest, Group) {
ExpectParsesTo(
"message TestMessage {\n"
@@ -504,6 +574,31 @@ TEST_F(ParseMessageTest, CompoundExtensionRange) {
"}");
}
+TEST_F(ParseMessageTest, LargerMaxForMessageSetWireFormatMessages) {
+ // Messages using the message_set_wire_format option can accept larger
+ // extension numbers, as the numbers are not encoded as int32 field values
+ // rather than tags.
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " extensions 4 to max;\n"
+ " option message_set_wire_format = true;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " extension_range { start:4 end: 0x7fffffff }"
+ " options {\n"
+ " uninterpreted_option { \n"
+ " name {\n"
+ " name_part: \"message_set_wire_format\"\n"
+ " is_extension: false\n"
+ " }\n"
+ " identifier_value: \"true\"\n"
+ " }\n"
+ " }\n"
+ "}");
+}
+
TEST_F(ParseMessageTest, Extensions) {
ExpectParsesTo(
"extend Extendee1 { optional int32 foo = 12; }\n"
@@ -544,6 +639,7 @@ TEST_F(ParseMessageTest, MultipleExtensionsOneExtendee) {
" type_name:\"TestMessage\" extendee: \"Extendee1\" }");
}
+
// ===================================================================
typedef ParserTest ParseEnumTest;
@@ -566,6 +662,10 @@ TEST_F(ParseEnumTest, Values) {
" FOO = 13;\n"
" BAR = -10;\n"
" BAZ = 500;\n"
+ " HEX_MAX = 0x7FFFFFFF;\n"
+ " HEX_MIN = -0x80000000;\n"
+ " INT_MAX = 2147483647;\n"
+ " INT_MIN = -2147483648;\n"
"}\n",
"enum_type {"
@@ -573,6 +673,10 @@ TEST_F(ParseEnumTest, Values) {
" value { name:\"FOO\" number:13 }"
" value { name:\"BAR\" number:-10 }"
" value { name:\"BAZ\" number:500 }"
+ " value { name:\"HEX_MAX\" number:2147483647 }"
+ " value { name:\"HEX_MIN\" number:-2147483648 }"
+ " value { name:\"INT_MAX\" number:2147483647 }"
+ " value { name:\"INT_MIN\" number:-2147483648 }"
"}");
}
@@ -626,7 +730,7 @@ TEST_F(ParseServiceTest, SimpleService) {
"}");
}
-TEST_F(ParseServiceTest, Methods) {
+TEST_F(ParseServiceTest, MethodsAndStreams) {
ExpectParsesTo(
"service TestService {\n"
" rpc Foo(In1) returns (Out1);\n"
@@ -642,6 +746,8 @@ TEST_F(ParseServiceTest, Methods) {
"}");
}
+
+
// ===================================================================
// imports and packages
@@ -663,6 +769,20 @@ TEST_F(ParseMiscTest, ParseMultipleImports) {
"dependency: \"baz.proto\"");
}
+TEST_F(ParseMiscTest, ParsePublicImports) {
+ ExpectParsesTo(
+ "import \"foo.proto\";\n"
+ "import public \"bar.proto\";\n"
+ "import \"baz.proto\";\n"
+ "import public \"qux.proto\";\n",
+ "dependency: \"foo.proto\""
+ "dependency: \"bar.proto\""
+ "dependency: \"baz.proto\""
+ "dependency: \"qux.proto\""
+ "public_dependency: 1 "
+ "public_dependency: 3 ");
+}
+
TEST_F(ParseMiscTest, ParsePackage) {
ExpectParsesTo(
"package foo.bar.baz;\n",
@@ -817,7 +937,7 @@ TEST_F(ParseErrorTest, DefaultValueTypeMismatch) {
"message TestMessage {\n"
" optional uint32 foo = 1 [default=true];\n"
"}\n",
- "1:35: Expected integer.\n");
+ "1:35: Expected integer for field default value.\n");
}
TEST_F(ParseErrorTest, DefaultValueNotBoolean) {
@@ -833,7 +953,7 @@ TEST_F(ParseErrorTest, DefaultValueNotString) {
"message TestMessage {\n"
" optional string foo = 1 [default=1];\n"
"}\n",
- "1:35: Expected string.\n");
+ "1:35: Expected string for field default value.\n");
}
TEST_F(ParseErrorTest, DefaultValueUnsignedNegative) {
@@ -862,12 +982,26 @@ TEST_F(ParseErrorTest, DefaultValueTooLarge) {
"6:36: Integer out of range.\n");
}
+TEST_F(ParseErrorTest, EnumValueOutOfRange) {
+ ExpectHasErrors(
+ "enum TestEnum {\n"
+ " HEX_TOO_BIG = 0x80000000;\n"
+ " HEX_TOO_SMALL = -0x80000001;\n"
+ " INT_TOO_BIG = 2147483648;\n"
+ " INT_TOO_SMALL = -2147483649;\n"
+ "}\n",
+ "1:19: Integer out of range.\n"
+ "2:19: Integer out of range.\n"
+ "3:19: Integer out of range.\n"
+ "4:19: Integer out of range.\n");
+}
+
TEST_F(ParseErrorTest, DefaultValueMissing) {
ExpectHasErrors(
"message TestMessage {\n"
" optional uint32 foo = 1 [default=];\n"
"}\n",
- "1:35: Expected integer.\n");
+ "1:35: Expected integer for field default value.\n");
}
TEST_F(ParseErrorTest, DefaultValueForGroup) {
@@ -886,6 +1020,27 @@ TEST_F(ParseErrorTest, DuplicateDefaultValue) {
"1:37: Already set option \"default\".\n");
}
+TEST_F(ParseErrorTest, MissingOneofName) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " oneof {\n"
+ " int32 bar = 1;\n"
+ " }\n"
+ "}\n",
+ "1:8: Expected oneof name.\n");
+}
+
+TEST_F(ParseErrorTest, LabelInOneof) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " oneof foo {\n"
+ " optional int32 bar = 1;\n"
+ " }\n"
+ "}\n",
+ "2:4: Fields in oneofs must not have labels (required / optional "
+ "/ repeated).\n");
+}
+
TEST_F(ParseErrorTest, GroupNotCapitalized) {
ExpectHasErrors(
"message TestMessage {\n"
@@ -930,6 +1085,12 @@ TEST_F(ParseErrorTest, MultipleParseErrors) {
"3:25: Expected \";\".\n");
}
+TEST_F(ParseErrorTest, EofInAggregateValue) {
+ ExpectHasErrors(
+ "option (fileopt) = { i:100\n",
+ "1:0: Unexpected end of stream while parsing aggregate value.\n");
+}
+
// -------------------------------------------------------------------
// Enum errors
@@ -965,6 +1126,7 @@ TEST_F(ParseErrorTest, ServiceMethodPrimitiveParams) {
"1:26: Expected message type.\n");
}
+
TEST_F(ParseErrorTest, EofInMethodOptions) {
ExpectHasErrors(
"service TestService {\n"
@@ -973,6 +1135,7 @@ TEST_F(ParseErrorTest, EofInMethodOptions) {
"1:29: Reached end of input in service definition (missing '}').\n");
}
+
TEST_F(ParseErrorTest, PrimitiveMethodInput) {
ExpectHasErrors(
"service TestService {\n"
@@ -981,6 +1144,7 @@ TEST_F(ParseErrorTest, PrimitiveMethodInput) {
"1:10: Expected message type.\n");
}
+
TEST_F(ParseErrorTest, MethodOptionTypeError) {
// This used to cause an infinite loop.
ExpectHasErrors(
@@ -991,6 +1155,7 @@ TEST_F(ParseErrorTest, MethodOptionTypeError) {
"2:45: Expected \"=\".\n");
}
+
// -------------------------------------------------------------------
// Import and package errors
@@ -1146,6 +1311,7 @@ TEST_F(ParserValidationErrorTest, MethodNameError) {
"3:6: \"Bar\" is already defined in \"Foo\".\n");
}
+
TEST_F(ParserValidationErrorTest, MethodInputTypeError) {
ExpectHasValidationErrors(
"message Baz {}\n"
@@ -1155,6 +1321,7 @@ TEST_F(ParserValidationErrorTest, MethodInputTypeError) {
"2:10: \"Qux\" is not defined.\n");
}
+
TEST_F(ParserValidationErrorTest, MethodOutputTypeError) {
ExpectHasValidationErrors(
"message Baz {}\n"
@@ -1164,17 +1331,94 @@ TEST_F(ParserValidationErrorTest, MethodOutputTypeError) {
"2:23: \"Qux\" is not defined.\n");
}
+
+TEST_F(ParserValidationErrorTest, ResovledUndefinedError) {
+ // Create another file which defines symbol ".base.bar".
+ FileDescriptorProto other_file;
+ other_file.set_name("base.proto");
+ other_file.set_package("base");
+ other_file.add_message_type()->set_name("bar");
+ EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
+
+ // Define "foo.base" and try "base.bar".
+ // "base.bar" is resolved to "foo.base.bar" which is not defined.
+ ExpectHasValidationErrors(
+ "package foo.base;\n"
+ "import \"base.proto\";\n"
+ "message qux {\n"
+ " optional base.bar baz = 1;\n"
+ " optional .base.bar quz = 2;\n"
+ "}\n",
+ "3:11: \"base.bar\" is resolved to \"foo.base.bar\","
+ " which is not defined. The innermost scope is searched first "
+ "in name resolution. Consider using a leading '.'(i.e., \".base.bar\")"
+ " to start from the outermost scope.\n");
+}
+
+TEST_F(ParserValidationErrorTest, ResovledUndefinedOptionError) {
+ // Build descriptor message in test pool
+ FileDescriptorProto descriptor_proto;
+ DescriptorProto::descriptor()->file()->CopyTo(&descriptor_proto);
+ ASSERT_TRUE(pool_.BuildFile(descriptor_proto) != NULL);
+
+ // base2.proto:
+ // package baz
+ // import google/protobuf/descriptor.proto
+ // message Bar { optional int32 foo = 1; }
+ // extend FileOptions { optional Bar bar = 7672757; }
+ FileDescriptorProto other_file;
+ other_file.set_name("base2.proto");
+ other_file.set_package("baz");
+ other_file.add_dependency();
+ other_file.set_dependency(0, descriptor_proto.name());
+
+ DescriptorProto* message(other_file.add_message_type());
+ message->set_name("Bar");
+ FieldDescriptorProto* field(message->add_field());
+ field->set_name("foo");
+ field->set_number(1);
+ field->set_label(FieldDescriptorProto_Label_LABEL_OPTIONAL);
+ field->set_type(FieldDescriptorProto_Type_TYPE_INT32);
+
+ FieldDescriptorProto* extension(other_file.add_extension());
+ extension->set_name("bar");
+ extension->set_number(7672757);
+ extension->set_label(FieldDescriptorProto_Label_LABEL_OPTIONAL);
+ extension->set_type(FieldDescriptorProto_Type_TYPE_MESSAGE);
+ extension->set_type_name("Bar");
+ extension->set_extendee("google.protobuf.FileOptions");
+
+ EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
+
+ // qux.proto:
+ // package qux.baz
+ // option (baz.bar).foo = 1;
+ //
+ // Although "baz.bar" is already defined, the lookup code will try
+ // "qux.baz.bar", since it's the match from the innermost scope,
+ // which will cause a symbol not defined error.
+ ExpectHasValidationErrors(
+ "package qux.baz;\n"
+ "import \"base2.proto\";\n"
+ "option (baz.bar).foo = 1;\n",
+ "2:7: Option \"(baz.bar)\" is resolved to \"(qux.baz.bar)\","
+ " which is not defined. The innermost scope is searched first "
+ "in name resolution. Consider using a leading '.'(i.e., \"(.baz.bar)\")"
+ " to start from the outermost scope.\n");
+}
+
// ===================================================================
// Test that the output from FileDescriptor::DebugString() (and all other
// descriptor types) is parseable, and results in the same Descriptor
-// definitions again afoter parsing (not, however, that the order of messages
+// definitions again afoter parsing (note, however, that the order of messages
// cannot be guaranteed to be the same)
typedef ParserTest ParseDecriptorDebugTest;
class CompareDescriptorNames {
public:
- bool operator()(const DescriptorProto* left, const DescriptorProto* right) {
+ bool operator()(const DescriptorProto* left,
+ const DescriptorProto* right) const {
return left->name() < right->name();
}
};
@@ -1218,13 +1462,19 @@ TEST_F(ParseDecriptorDebugTest, TestAllDescriptorTypes) {
FileDescriptorProto parsed;
parser_->Parse(input_.get(), &parsed);
EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
- ASSERT_EQ("", error_collector_.text_);
+ ASSERT_EQ("", error_collector_.text_)
+ << "Failed to parse:\n" << debug_string;
// We now have a FileDescriptorProto, but to compare with the expected we
// need to link to a FileDecriptor, then output back to a proto. We'll
// also need to give it the same name as the original.
parsed.set_name("google/protobuf/unittest.proto");
// We need the imported dependency before we can build our parsed proto
+ const FileDescriptor* public_import =
+ protobuf_unittest_import::PublicImportMessage::descriptor()->file();
+ FileDescriptorProto public_import_proto;
+ public_import->CopyTo(&public_import_proto);
+ ASSERT_TRUE(pool_.BuildFile(public_import_proto) != NULL);
const FileDescriptor* import =
protobuf_unittest_import::ImportMessage::descriptor()->file();
FileDescriptorProto import_proto;
@@ -1232,6 +1482,8 @@ TEST_F(ParseDecriptorDebugTest, TestAllDescriptorTypes) {
ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
const FileDescriptor* actual = pool_.BuildFile(parsed);
parsed.Clear();
+ ASSERT_TRUE(actual != NULL)
+ << "Failed to validate:\n" << debug_string;
actual->CopyTo(&parsed);
ASSERT_TRUE(actual != NULL);
@@ -1247,6 +1499,1110 @@ TEST_F(ParseDecriptorDebugTest, TestAllDescriptorTypes) {
EXPECT_EQ(expected.DebugString(), parsed.DebugString());
}
+TEST_F(ParseDecriptorDebugTest, TestCustomOptions) {
+ const FileDescriptor* original_file =
+ protobuf_unittest::AggregateMessage::descriptor()->file();
+ FileDescriptorProto expected;
+ original_file->CopyTo(&expected);
+
+ string debug_string = original_file->DebugString();
+
+ // Parse the debug string
+ 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_);
+
+ // We now have a FileDescriptorProto, but to compare with the expected we
+ // need to link to a FileDecriptor, then output back to a proto. We'll
+ // also need to give it the same name as the original.
+ parsed.set_name(original_file->name());
+
+ // unittest_custom_options.proto depends on descriptor.proto.
+ const FileDescriptor* import = FileDescriptorProto::descriptor()->file();
+ FileDescriptorProto import_proto;
+ import->CopyTo(&import_proto);
+ ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
+ const FileDescriptor* actual = pool_.BuildFile(parsed);
+ ASSERT_TRUE(actual != NULL);
+ parsed.Clear();
+ actual->CopyTo(&parsed);
+
+ // The messages might be in different orders, making them hard to compare.
+ // So, sort the messages in the descriptor protos (including nested messages,
+ // recursively).
+ SortMessages(&expected);
+ SortMessages(&parsed);
+
+ EXPECT_EQ(expected.DebugString(), parsed.DebugString());
+}
+
+// ===================================================================
+// SourceCodeInfo tests.
+
+// Follows a path -- as defined by SourceCodeInfo.Location.path -- from a
+// message to a particular sub-field.
+// * If the target is itself a message, sets *output_message to point at it,
+// *output_field to NULL, and *output_index to -1.
+// * Otherwise, if the target is an element of a repeated field, sets
+// *output_message to the containing message, *output_field to the descriptor
+// of the field, and *output_index to the index of the element.
+// * Otherwise, the target is a field (possibly a repeated field, but not any
+// one element). Sets *output_message to the containing message,
+// *output_field to the descriptor of the field, and *output_index to -1.
+// Returns true if the path was valid, false otherwise. A gTest failure is
+// recorded before returning false.
+bool FollowPath(const Message& root,
+ const int* path_begin, const int* path_end,
+ const Message** output_message,
+ const FieldDescriptor** output_field,
+ int* output_index) {
+ if (path_begin == path_end) {
+ // Path refers to this whole message.
+ *output_message = &root;
+ *output_field = NULL;
+ *output_index = -1;
+ return true;
+ }
+
+ const Descriptor* descriptor = root.GetDescriptor();
+ const Reflection* reflection = root.GetReflection();
+
+ const FieldDescriptor* field = descriptor->FindFieldByNumber(*path_begin);
+
+ if (field == NULL) {
+ ADD_FAILURE() << descriptor->name() << " has no field number: "
+ << *path_begin;
+ return false;
+ }
+
+ ++path_begin;
+
+ if (field->is_repeated()) {
+ if (path_begin == path_end) {
+ // Path refers to the whole repeated field.
+ *output_message = &root;
+ *output_field = field;
+ *output_index = -1;
+ return true;
+ }
+
+ int index = *path_begin++;
+ int size = reflection->FieldSize(root, field);
+
+ if (index >= size) {
+ ADD_FAILURE() << descriptor->name() << "." << field->name()
+ << " has size " << size << ", but path contained index: "
+ << index;
+ return false;
+ }
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Descend into child message.
+ const Message& child = reflection->GetRepeatedMessage(root, field, index);
+ return FollowPath(child, path_begin, path_end,
+ output_message, output_field, output_index);
+ } else if (path_begin == path_end) {
+ // Path refers to this element.
+ *output_message = &root;
+ *output_field = field;
+ *output_index = index;
+ return true;
+ } else {
+ ADD_FAILURE() << descriptor->name() << "." << field->name()
+ << " is not a message; cannot descend into it.";
+ return false;
+ }
+ } else {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ const Message& child = reflection->GetMessage(root, field);
+ return FollowPath(child, path_begin, path_end,
+ output_message, output_field, output_index);
+ } else if (path_begin == path_end) {
+ // Path refers to this field.
+ *output_message = &root;
+ *output_field = field;
+ *output_index = -1;
+ return true;
+ } else {
+ ADD_FAILURE() << descriptor->name() << "." << field->name()
+ << " is not a message; cannot descend into it.";
+ return false;
+ }
+ }
+}
+
+// Check if two spans are equal.
+bool CompareSpans(const RepeatedField<int>& span1,
+ const RepeatedField<int>& span2) {
+ if (span1.size() != span2.size()) return false;
+ for (int i = 0; i < span1.size(); i++) {
+ if (span1.Get(i) != span2.Get(i)) return false;
+ }
+ return true;
+}
+
+// Test fixture for source info tests, which check that source locations are
+// recorded correctly in FileDescriptorProto.source_code_info.location.
+class SourceInfoTest : public ParserTest {
+ protected:
+ // The parsed file (initialized by Parse()).
+ FileDescriptorProto file_;
+
+ // Parse the given text as a .proto file and populate the spans_ map with
+ // all the source location spans in its SourceCodeInfo table.
+ bool Parse(const char* text) {
+ ExtractMarkers(text);
+ SetupParser(text_without_markers_.c_str());
+ if (!parser_->Parse(input_.get(), &file_)) {
+ return false;
+ }
+
+ const SourceCodeInfo& source_info = file_.source_code_info();
+ for (int i = 0; i < source_info.location_size(); i++) {
+ const SourceCodeInfo::Location& location = source_info.location(i);
+ const Message* descriptor_proto = NULL;
+ const FieldDescriptor* field = NULL;
+ int index = 0;
+ if (!FollowPath(file_, location.path().begin(), location.path().end(),
+ &descriptor_proto, &field, &index)) {
+ return false;
+ }
+
+ spans_.insert(make_pair(SpanKey(*descriptor_proto, field, index),
+ &location));
+ }
+
+ return true;
+ }
+
+ virtual void TearDown() {
+ EXPECT_TRUE(spans_.empty())
+ << "Forgot to call HasSpan() for:\n"
+ << spans_.begin()->second->DebugString();
+ }
+
+ // -----------------------------------------------------------------
+ // HasSpan() checks that the span of source code delimited by the given
+ // tags (comments) correspond via the SourceCodeInfo table to the given
+ // part of the FileDescriptorProto. (If unclear, look at the actual tests;
+ // it should quickly become obvious.)
+
+ bool HasSpan(char start_marker, char end_marker,
+ const Message& descriptor_proto) {
+ return HasSpanWithComment(
+ start_marker, end_marker, descriptor_proto, NULL, -1, NULL, NULL);
+ }
+
+ bool HasSpanWithComment(char start_marker, char end_marker,
+ const Message& descriptor_proto,
+ const char* expected_leading_comments,
+ const char* expected_trailing_comments) {
+ return HasSpanWithComment(
+ start_marker, end_marker, descriptor_proto, NULL, -1,
+ expected_leading_comments, expected_trailing_comments);
+ }
+
+ bool HasSpan(char start_marker, char end_marker,
+ const Message& descriptor_proto, const string& field_name) {
+ return HasSpan(start_marker, end_marker, descriptor_proto, field_name, -1);
+ }
+
+ bool HasSpan(char start_marker, char end_marker,
+ const Message& descriptor_proto, const string& field_name,
+ int index) {
+ return HasSpan(start_marker, end_marker, descriptor_proto,
+ field_name, index, NULL, NULL);
+ }
+
+ bool HasSpan(char start_marker, char end_marker,
+ const Message& descriptor_proto,
+ const string& field_name, int index,
+ const char* expected_leading_comments,
+ const char* expected_trailing_comments) {
+ const FieldDescriptor* field =
+ descriptor_proto.GetDescriptor()->FindFieldByName(field_name);
+ if (field == NULL) {
+ ADD_FAILURE() << descriptor_proto.GetDescriptor()->name()
+ << " has no such field: " << field_name;
+ return false;
+ }
+
+ return HasSpanWithComment(
+ start_marker, end_marker, descriptor_proto, field, index,
+ expected_leading_comments, expected_trailing_comments);
+ }
+
+ bool HasSpan(const Message& descriptor_proto) {
+ return HasSpanWithComment(
+ '\0', '\0', descriptor_proto, NULL, -1, NULL, NULL);
+ }
+
+ bool HasSpan(const Message& descriptor_proto, const string& field_name) {
+ return HasSpan('\0', '\0', descriptor_proto, field_name, -1);
+ }
+
+ bool HasSpan(const Message& descriptor_proto, const string& field_name,
+ int index) {
+ return HasSpan('\0', '\0', descriptor_proto, field_name, index);
+ }
+
+ bool HasSpanWithComment(char start_marker, char end_marker,
+ const Message& descriptor_proto,
+ const FieldDescriptor* field, int index,
+ const char* expected_leading_comments,
+ const char* expected_trailing_comments) {
+ pair<SpanMap::iterator, SpanMap::iterator> range =
+ spans_.equal_range(SpanKey(descriptor_proto, field, index));
+
+ if (start_marker == '\0') {
+ if (range.first == range.second) {
+ return false;
+ } else {
+ spans_.erase(range.first);
+ return true;
+ }
+ } else {
+ pair<int, int> start_pos = FindOrDie(markers_, start_marker);
+ pair<int, int> end_pos = FindOrDie(markers_, end_marker);
+
+ RepeatedField<int> expected_span;
+ expected_span.Add(start_pos.first);
+ expected_span.Add(start_pos.second);
+ if (end_pos.first != start_pos.first) {
+ expected_span.Add(end_pos.first);
+ }
+ expected_span.Add(end_pos.second);
+
+ for (SpanMap::iterator iter = range.first; iter != range.second; ++iter) {
+ if (CompareSpans(expected_span, iter->second->span())) {
+ if (expected_leading_comments == NULL) {
+ EXPECT_FALSE(iter->second->has_leading_comments());
+ } else {
+ EXPECT_TRUE(iter->second->has_leading_comments());
+ EXPECT_EQ(expected_leading_comments,
+ iter->second->leading_comments());
+ }
+ if (expected_trailing_comments == NULL) {
+ EXPECT_FALSE(iter->second->has_trailing_comments());
+ } else {
+ EXPECT_TRUE(iter->second->has_trailing_comments());
+ EXPECT_EQ(expected_trailing_comments,
+ iter->second->trailing_comments());
+ }
+
+ spans_.erase(iter);
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+
+ private:
+ struct SpanKey {
+ const Message* descriptor_proto;
+ const FieldDescriptor* field;
+ int index;
+
+ inline SpanKey() {}
+ inline SpanKey(const Message& descriptor_proto_param,
+ const FieldDescriptor* field_param,
+ int index_param)
+ : descriptor_proto(&descriptor_proto_param), field(field_param),
+ index(index_param) {}
+
+ inline bool operator<(const SpanKey& other) const {
+ if (descriptor_proto < other.descriptor_proto) return true;
+ if (descriptor_proto > other.descriptor_proto) return false;
+ if (field < other.field) return true;
+ if (field > other.field) return false;
+ return index < other.index;
+ }
+ };
+
+ typedef multimap<SpanKey, const SourceCodeInfo::Location*> SpanMap;
+ SpanMap spans_;
+ map<char, pair<int, int> > markers_;
+ string text_without_markers_;
+
+ void ExtractMarkers(const char* text) {
+ markers_.clear();
+ text_without_markers_.clear();
+ int line = 0;
+ int column = 0;
+ while (*text != '\0') {
+ if (*text == '$') {
+ ++text;
+ GOOGLE_CHECK_NE('\0', *text);
+ if (*text == '$') {
+ text_without_markers_ += '$';
+ ++column;
+ } else {
+ markers_[*text] = make_pair(line, column);
+ ++text;
+ GOOGLE_CHECK_EQ('$', *text);
+ }
+ } else if (*text == '\n') {
+ ++line;
+ column = 0;
+ text_without_markers_ += *text;
+ } else {
+ text_without_markers_ += *text;
+ ++column;
+ }
+ ++text;
+ }
+ }
+};
+
+TEST_F(SourceInfoTest, BasicFileDecls) {
+ EXPECT_TRUE(Parse(
+ "$a$syntax = \"proto2\";\n"
+ "package $b$foo.bar$c$;\n"
+ "import $d$\"baz.proto\"$e$;\n"
+ "import $f$\"qux.proto\"$g$;$h$\n"
+ "\n"
+ "// comment ignored\n"));
+
+ EXPECT_TRUE(HasSpan('a', 'h', file_));
+ EXPECT_TRUE(HasSpan('b', 'c', file_, "package"));
+ EXPECT_TRUE(HasSpan('d', 'e', file_, "dependency", 0));
+ EXPECT_TRUE(HasSpan('f', 'g', file_, "dependency", 1));
+}
+
+TEST_F(SourceInfoTest, Messages) {
+ EXPECT_TRUE(Parse(
+ "$a$message $b$Foo$c$ {}$d$\n"
+ "$e$message $f$Bar$g$ {}$h$\n"));
+
+ EXPECT_TRUE(HasSpan('a', 'd', file_.message_type(0)));
+ EXPECT_TRUE(HasSpan('b', 'c', file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan('e', 'h', file_.message_type(1)));
+ EXPECT_TRUE(HasSpan('f', 'g', file_.message_type(1), "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, Fields) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " $a$optional$b$ $c$int32$d$ $e$bar$f$ = $g$1$h$;$i$\n"
+ " $j$repeated$k$ $l$X.Y$m$ $n$baz$o$ = $p$2$q$;$r$\n"
+ "}\n"));
+
+ const FieldDescriptorProto& field1 = file_.message_type(0).field(0);
+ const FieldDescriptorProto& field2 = file_.message_type(0).field(1);
+
+ EXPECT_TRUE(HasSpan('a', 'i', field1));
+ EXPECT_TRUE(HasSpan('a', 'b', field1, "label"));
+ EXPECT_TRUE(HasSpan('c', 'd', field1, "type"));
+ EXPECT_TRUE(HasSpan('e', 'f', field1, "name"));
+ EXPECT_TRUE(HasSpan('g', 'h', field1, "number"));
+
+ EXPECT_TRUE(HasSpan('j', 'r', field2));
+ EXPECT_TRUE(HasSpan('j', 'k', field2, "label"));
+ EXPECT_TRUE(HasSpan('l', 'm', field2, "type_name"));
+ EXPECT_TRUE(HasSpan('n', 'o', field2, "name"));
+ EXPECT_TRUE(HasSpan('p', 'q', field2, "number"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Extensions) {
+ EXPECT_TRUE(Parse(
+ "$a$extend $b$Foo$c$ {\n"
+ " $d$optional$e$ int32 bar = 1;$f$\n"
+ " $g$repeated$h$ X.Y baz = 2;$i$\n"
+ "}$j$\n"
+ "$k$extend $l$Bar$m$ {\n"
+ " $n$optional int32 qux = 1;$o$\n"
+ "}$p$\n"));
+
+ const FieldDescriptorProto& field1 = file_.extension(0);
+ const FieldDescriptorProto& field2 = file_.extension(1);
+ const FieldDescriptorProto& field3 = file_.extension(2);
+
+ EXPECT_TRUE(HasSpan('a', 'j', file_, "extension"));
+ EXPECT_TRUE(HasSpan('k', 'p', file_, "extension"));
+
+ EXPECT_TRUE(HasSpan('d', 'f', field1));
+ EXPECT_TRUE(HasSpan('d', 'e', field1, "label"));
+ EXPECT_TRUE(HasSpan('b', 'c', field1, "extendee"));
+
+ EXPECT_TRUE(HasSpan('g', 'i', field2));
+ EXPECT_TRUE(HasSpan('g', 'h', field2, "label"));
+ EXPECT_TRUE(HasSpan('b', 'c', field2, "extendee"));
+
+ EXPECT_TRUE(HasSpan('n', 'o', field3));
+ EXPECT_TRUE(HasSpan('l', 'm', field3, "extendee"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(field1, "type"));
+ EXPECT_TRUE(HasSpan(field1, "name"));
+ EXPECT_TRUE(HasSpan(field1, "number"));
+ EXPECT_TRUE(HasSpan(field2, "type_name"));
+ EXPECT_TRUE(HasSpan(field2, "name"));
+ EXPECT_TRUE(HasSpan(field2, "number"));
+ EXPECT_TRUE(HasSpan(field3, "label"));
+ EXPECT_TRUE(HasSpan(field3, "type"));
+ EXPECT_TRUE(HasSpan(field3, "name"));
+ EXPECT_TRUE(HasSpan(field3, "number"));
+}
+
+TEST_F(SourceInfoTest, NestedExtensions) {
+ EXPECT_TRUE(Parse(
+ "message Message {\n"
+ " $a$extend $b$Foo$c$ {\n"
+ " $d$optional$e$ int32 bar = 1;$f$\n"
+ " $g$repeated$h$ X.Y baz = 2;$i$\n"
+ " }$j$\n"
+ " $k$extend $l$Bar$m$ {\n"
+ " $n$optional int32 qux = 1;$o$\n"
+ " }$p$\n"
+ "}\n"));
+
+ const FieldDescriptorProto& field1 = file_.message_type(0).extension(0);
+ const FieldDescriptorProto& field2 = file_.message_type(0).extension(1);
+ const FieldDescriptorProto& field3 = file_.message_type(0).extension(2);
+
+ EXPECT_TRUE(HasSpan('a', 'j', file_.message_type(0), "extension"));
+ EXPECT_TRUE(HasSpan('k', 'p', file_.message_type(0), "extension"));
+
+ EXPECT_TRUE(HasSpan('d', 'f', field1));
+ EXPECT_TRUE(HasSpan('d', 'e', field1, "label"));
+ EXPECT_TRUE(HasSpan('b', 'c', field1, "extendee"));
+
+ EXPECT_TRUE(HasSpan('g', 'i', field2));
+ EXPECT_TRUE(HasSpan('g', 'h', field2, "label"));
+ EXPECT_TRUE(HasSpan('b', 'c', field2, "extendee"));
+
+ EXPECT_TRUE(HasSpan('n', 'o', field3));
+ EXPECT_TRUE(HasSpan('l', 'm', field3, "extendee"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(field1, "type"));
+ EXPECT_TRUE(HasSpan(field1, "name"));
+ EXPECT_TRUE(HasSpan(field1, "number"));
+ EXPECT_TRUE(HasSpan(field2, "type_name"));
+ EXPECT_TRUE(HasSpan(field2, "name"));
+ EXPECT_TRUE(HasSpan(field2, "number"));
+ EXPECT_TRUE(HasSpan(field3, "label"));
+ EXPECT_TRUE(HasSpan(field3, "type"));
+ EXPECT_TRUE(HasSpan(field3, "name"));
+ EXPECT_TRUE(HasSpan(field3, "number"));
+}
+
+TEST_F(SourceInfoTest, ExtensionRanges) {
+ EXPECT_TRUE(Parse(
+ "message Message {\n"
+ " $a$extensions $b$1$c$ to $d$4$e$, $f$6$g$;$h$\n"
+ " $i$extensions $j$8$k$ to $l$max$m$;$n$\n"
+ "}\n"));
+
+ const DescriptorProto::ExtensionRange& range1 =
+ file_.message_type(0).extension_range(0);
+ const DescriptorProto::ExtensionRange& range2 =
+ file_.message_type(0).extension_range(1);
+ const DescriptorProto::ExtensionRange& range3 =
+ file_.message_type(0).extension_range(2);
+
+ EXPECT_TRUE(HasSpan('a', 'h', file_.message_type(0), "extension_range"));
+ EXPECT_TRUE(HasSpan('i', 'n', file_.message_type(0), "extension_range"));
+
+ EXPECT_TRUE(HasSpan('b', 'e', range1));
+ EXPECT_TRUE(HasSpan('b', 'c', range1, "start"));
+ EXPECT_TRUE(HasSpan('d', 'e', range1, "end"));
+
+ EXPECT_TRUE(HasSpan('f', 'g', range2));
+ EXPECT_TRUE(HasSpan('f', 'g', range2, "start"));
+ EXPECT_TRUE(HasSpan('f', 'g', range2, "end"));
+
+ EXPECT_TRUE(HasSpan('j', 'm', range3));
+ EXPECT_TRUE(HasSpan('j', 'k', range3, "start"));
+ EXPECT_TRUE(HasSpan('l', 'm', range3, "end"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Oneofs) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " $a$oneof $c$foo$d$ {\n"
+ " $e$int32$f$ $g$a$h$ = $i$1$j$;$k$\n"
+ " }$r$\n"
+ "}\n"));
+
+ const OneofDescriptorProto& oneof_decl = file_.message_type(0).oneof_decl(0);
+ const FieldDescriptorProto& field = file_.message_type(0).field(0);
+
+ EXPECT_TRUE(HasSpan('a', 'r', oneof_decl));
+ EXPECT_TRUE(HasSpan('c', 'd', oneof_decl, "name"));
+
+ EXPECT_TRUE(HasSpan('e', 'k', field));
+ EXPECT_TRUE(HasSpan('e', 'f', field, "type"));
+ EXPECT_TRUE(HasSpan('g', 'h', field, "name"));
+ EXPECT_TRUE(HasSpan('i', 'j', field, "number"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, NestedMessages) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " $a$message $b$Bar$c$ {\n"
+ " $d$message $e$Baz$f$ {}$g$\n"
+ " }$h$\n"
+ " $i$message $j$Qux$k$ {}$l$\n"
+ "}\n"));
+
+ const DescriptorProto& bar = file_.message_type(0).nested_type(0);
+ const DescriptorProto& baz = bar.nested_type(0);
+ const DescriptorProto& qux = file_.message_type(0).nested_type(1);
+
+ EXPECT_TRUE(HasSpan('a', 'h', bar));
+ EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
+ EXPECT_TRUE(HasSpan('d', 'g', baz));
+ EXPECT_TRUE(HasSpan('e', 'f', baz, "name"));
+ EXPECT_TRUE(HasSpan('i', 'l', qux));
+ EXPECT_TRUE(HasSpan('j', 'k', qux, "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Groups) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " message Bar {}\n"
+ " $a$optional$b$ $c$group$d$ $e$Baz$f$ = $g$1$h$ {\n"
+ " $i$message Qux {}$j$\n"
+ " }$k$\n"
+ "}\n"));
+
+ const DescriptorProto& bar = file_.message_type(0).nested_type(0);
+ const DescriptorProto& baz = file_.message_type(0).nested_type(1);
+ const DescriptorProto& qux = baz.nested_type(0);
+ const FieldDescriptorProto& field = file_.message_type(0).field(0);
+
+ EXPECT_TRUE(HasSpan('a', 'k', field));
+ EXPECT_TRUE(HasSpan('a', 'b', field, "label"));
+ EXPECT_TRUE(HasSpan('c', 'd', field, "type"));
+ EXPECT_TRUE(HasSpan('e', 'f', field, "name"));
+ EXPECT_TRUE(HasSpan('e', 'f', field, "type_name"));
+ EXPECT_TRUE(HasSpan('g', 'h', field, "number"));
+
+ EXPECT_TRUE(HasSpan('a', 'k', baz));
+ EXPECT_TRUE(HasSpan('e', 'f', baz, "name"));
+ EXPECT_TRUE(HasSpan('i', 'j', qux));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(bar));
+ EXPECT_TRUE(HasSpan(bar, "name"));
+ EXPECT_TRUE(HasSpan(qux, "name"));
+}
+
+TEST_F(SourceInfoTest, Enums) {
+ EXPECT_TRUE(Parse(
+ "$a$enum $b$Foo$c$ {}$d$\n"
+ "$e$enum $f$Bar$g$ {}$h$\n"));
+
+ EXPECT_TRUE(HasSpan('a', 'd', file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan('b', 'c', file_.enum_type(0), "name"));
+ EXPECT_TRUE(HasSpan('e', 'h', file_.enum_type(1)));
+ EXPECT_TRUE(HasSpan('f', 'g', file_.enum_type(1), "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, EnumValues) {
+ EXPECT_TRUE(Parse(
+ "enum Foo {\n"
+ " $a$BAR$b$ = $c$1$d$;$e$\n"
+ " $f$BAZ$g$ = $h$2$i$;$j$\n"
+ "}"));
+
+ const EnumValueDescriptorProto& bar = file_.enum_type(0).value(0);
+ const EnumValueDescriptorProto& baz = file_.enum_type(0).value(1);
+
+ EXPECT_TRUE(HasSpan('a', 'e', bar));
+ EXPECT_TRUE(HasSpan('a', 'b', bar, "name"));
+ EXPECT_TRUE(HasSpan('c', 'd', bar, "number"));
+ EXPECT_TRUE(HasSpan('f', 'j', baz));
+ EXPECT_TRUE(HasSpan('f', 'g', baz, "name"));
+ EXPECT_TRUE(HasSpan('h', 'i', baz, "number"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, NestedEnums) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " $a$enum $b$Bar$c$ {}$d$\n"
+ " $e$enum $f$Baz$g$ {}$h$\n"
+ "}\n"));
+
+ const EnumDescriptorProto& bar = file_.message_type(0).enum_type(0);
+ const EnumDescriptorProto& baz = file_.message_type(0).enum_type(1);
+
+ EXPECT_TRUE(HasSpan('a', 'd', bar));
+ EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
+ EXPECT_TRUE(HasSpan('e', 'h', baz));
+ EXPECT_TRUE(HasSpan('f', 'g', baz, "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Services) {
+ EXPECT_TRUE(Parse(
+ "$a$service $b$Foo$c$ {}$d$\n"
+ "$e$service $f$Bar$g$ {}$h$\n"));
+
+ EXPECT_TRUE(HasSpan('a', 'd', file_.service(0)));
+ EXPECT_TRUE(HasSpan('b', 'c', file_.service(0), "name"));
+ EXPECT_TRUE(HasSpan('e', 'h', file_.service(1)));
+ EXPECT_TRUE(HasSpan('f', 'g', file_.service(1), "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, MethodsAndStreams) {
+ EXPECT_TRUE(Parse(
+ "service Foo {\n"
+ " $a$rpc $b$Bar$c$($d$X$e$) returns($f$Y$g$);$h$"
+ " $i$rpc $j$Baz$k$($l$Z$m$) returns($n$W$o$);$p$"
+ "}"));
+
+ const MethodDescriptorProto& bar = file_.service(0).method(0);
+ const MethodDescriptorProto& baz = file_.service(0).method(1);
+
+ EXPECT_TRUE(HasSpan('a', 'h', bar));
+ EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
+ EXPECT_TRUE(HasSpan('d', 'e', bar, "input_type"));
+ EXPECT_TRUE(HasSpan('f', 'g', bar, "output_type"));
+
+ EXPECT_TRUE(HasSpan('i', 'p', baz));
+ EXPECT_TRUE(HasSpan('j', 'k', baz, "name"));
+ EXPECT_TRUE(HasSpan('l', 'm', baz, "input_type"));
+ EXPECT_TRUE(HasSpan('n', 'o', baz, "output_type"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.service(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0), "name"));
+}
+
+
+TEST_F(SourceInfoTest, Options) {
+ EXPECT_TRUE(Parse(
+ "$a$option $b$foo$c$.$d$($e$bar.baz$f$)$g$ = "
+ "$h$123$i$;$j$\n"
+ "$k$option qux = $l$-123$m$;$n$\n"
+ "$o$option corge = $p$abc$q$;$r$\n"
+ "$s$option grault = $t$'blah'$u$;$v$\n"
+ "$w$option garply = $x${ yadda yadda }$y$;$z$\n"
+ "$0$option waldo = $1$123.0$2$;$3$\n"
+ ));
+
+ const UninterpretedOption& option1 = file_.options().uninterpreted_option(0);
+ const UninterpretedOption& option2 = file_.options().uninterpreted_option(1);
+ const UninterpretedOption& option3 = file_.options().uninterpreted_option(2);
+ const UninterpretedOption& option4 = file_.options().uninterpreted_option(3);
+ const UninterpretedOption& option5 = file_.options().uninterpreted_option(4);
+ const UninterpretedOption& option6 = file_.options().uninterpreted_option(5);
+
+ EXPECT_TRUE(HasSpan('a', 'j', file_.options()));
+ EXPECT_TRUE(HasSpan('a', 'j', option1));
+ EXPECT_TRUE(HasSpan('b', 'g', option1, "name"));
+ EXPECT_TRUE(HasSpan('b', 'c', option1.name(0)));
+ EXPECT_TRUE(HasSpan('b', 'c', option1.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan('d', 'g', option1.name(1)));
+ EXPECT_TRUE(HasSpan('e', 'f', option1.name(1), "name_part"));
+ EXPECT_TRUE(HasSpan('h', 'i', option1, "positive_int_value"));
+
+ EXPECT_TRUE(HasSpan('k', 'n', file_.options()));
+ EXPECT_TRUE(HasSpan('l', 'm', option2, "negative_int_value"));
+
+ EXPECT_TRUE(HasSpan('o', 'r', file_.options()));
+ EXPECT_TRUE(HasSpan('p', 'q', option3, "identifier_value"));
+
+ EXPECT_TRUE(HasSpan('s', 'v', file_.options()));
+ EXPECT_TRUE(HasSpan('t', 'u', option4, "string_value"));
+
+ EXPECT_TRUE(HasSpan('w', 'z', file_.options()));
+ EXPECT_TRUE(HasSpan('x', 'y', option5, "aggregate_value"));
+
+ EXPECT_TRUE(HasSpan('0', '3', file_.options()));
+ EXPECT_TRUE(HasSpan('1', '2', option6, "double_value"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(option2));
+ EXPECT_TRUE(HasSpan(option3));
+ EXPECT_TRUE(HasSpan(option4));
+ EXPECT_TRUE(HasSpan(option5));
+ EXPECT_TRUE(HasSpan(option6));
+ EXPECT_TRUE(HasSpan(option2, "name"));
+ EXPECT_TRUE(HasSpan(option3, "name"));
+ EXPECT_TRUE(HasSpan(option4, "name"));
+ EXPECT_TRUE(HasSpan(option5, "name"));
+ EXPECT_TRUE(HasSpan(option6, "name"));
+ EXPECT_TRUE(HasSpan(option2.name(0)));
+ EXPECT_TRUE(HasSpan(option3.name(0)));
+ EXPECT_TRUE(HasSpan(option4.name(0)));
+ EXPECT_TRUE(HasSpan(option5.name(0)));
+ EXPECT_TRUE(HasSpan(option6.name(0)));
+ EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option3.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option4.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option5.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option6.name(0), "name_part"));
+}
+
+TEST_F(SourceInfoTest, ScopedOptions) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " $a$option mopt = 1;$b$\n"
+ "}\n"
+ "enum Bar {\n"
+ " $c$option eopt = 1;$d$\n"
+ "}\n"
+ "service Baz {\n"
+ " $e$option sopt = 1;$f$\n"
+ " rpc M(X) returns(Y) {\n"
+ " $g$option mopt = 1;$h$\n"
+ " }\n"
+ "}\n"));
+
+ EXPECT_TRUE(HasSpan('a', 'b', file_.message_type(0).options()));
+ EXPECT_TRUE(HasSpan('c', 'd', file_.enum_type(0).options()));
+ EXPECT_TRUE(HasSpan('e', 'f', file_.service(0).options()));
+ EXPECT_TRUE(HasSpan('g', 'h', file_.service(0).method(0).options()));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0), "positive_int_value"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0), "positive_int_value"));
+ EXPECT_TRUE(HasSpan(file_.service(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0), "positive_int_value"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0), "input_type"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0), "output_type"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0), "positive_int_value"));
+}
+
+TEST_F(SourceInfoTest, FieldOptions) {
+ // The actual "name = value" pairs are parsed by the same code as for
+ // top-level options so we won't re-test that -- just make sure that the
+ // syntax used for field options is understood.
+ EXPECT_TRUE(Parse(
+ "message Foo {"
+ " optional int32 bar = 1 "
+ "$a$[default=$b$123$c$,$d$opt1=123$e$,"
+ "$f$opt2='hi'$g$]$h$;"
+ "}\n"
+ ));
+
+ const FieldDescriptorProto& field = file_.message_type(0).field(0);
+ const UninterpretedOption& option1 = field.options().uninterpreted_option(0);
+ const UninterpretedOption& option2 = field.options().uninterpreted_option(1);
+
+ EXPECT_TRUE(HasSpan('a', 'h', field.options()));
+ EXPECT_TRUE(HasSpan('b', 'c', field, "default_value"));
+ EXPECT_TRUE(HasSpan('d', 'e', option1));
+ EXPECT_TRUE(HasSpan('f', 'g', option2));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(field));
+ EXPECT_TRUE(HasSpan(field, "label"));
+ EXPECT_TRUE(HasSpan(field, "type"));
+ EXPECT_TRUE(HasSpan(field, "name"));
+ EXPECT_TRUE(HasSpan(field, "number"));
+ EXPECT_TRUE(HasSpan(option1, "name"));
+ EXPECT_TRUE(HasSpan(option2, "name"));
+ EXPECT_TRUE(HasSpan(option1.name(0)));
+ EXPECT_TRUE(HasSpan(option2.name(0)));
+ EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
+ EXPECT_TRUE(HasSpan(option2, "string_value"));
+}
+
+TEST_F(SourceInfoTest, EnumValueOptions) {
+ // The actual "name = value" pairs are parsed by the same code as for
+ // top-level options so we won't re-test that -- just make sure that the
+ // syntax used for enum options is understood.
+ EXPECT_TRUE(Parse(
+ "enum Foo {"
+ " BAR = 1 $a$[$b$opt1=123$c$,$d$opt2='hi'$e$]$f$;"
+ "}\n"
+ ));
+
+ const EnumValueDescriptorProto& value = file_.enum_type(0).value(0);
+ const UninterpretedOption& option1 = value.options().uninterpreted_option(0);
+ const UninterpretedOption& option2 = value.options().uninterpreted_option(1);
+
+ EXPECT_TRUE(HasSpan('a', 'f', value.options()));
+ EXPECT_TRUE(HasSpan('b', 'c', option1));
+ EXPECT_TRUE(HasSpan('d', 'e', option2));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+ EXPECT_TRUE(HasSpan(value));
+ EXPECT_TRUE(HasSpan(value, "name"));
+ EXPECT_TRUE(HasSpan(value, "number"));
+ EXPECT_TRUE(HasSpan(option1, "name"));
+ EXPECT_TRUE(HasSpan(option2, "name"));
+ EXPECT_TRUE(HasSpan(option1.name(0)));
+ EXPECT_TRUE(HasSpan(option2.name(0)));
+ EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
+ EXPECT_TRUE(HasSpan(option2, "string_value"));
+}
+
+TEST_F(SourceInfoTest, DocComments) {
+ EXPECT_TRUE(Parse(
+ "// Foo leading\n"
+ "// line 2\n"
+ "$a$message Foo {\n"
+ " // Foo trailing\n"
+ " // line 2\n"
+ "\n"
+ " // ignored\n"
+ "\n"
+ " // bar leading\n"
+ " $b$optional int32 bar = 1;$c$\n"
+ " // bar trailing\n"
+ "}$d$\n"
+ "// ignored\n"
+ ));
+
+ const DescriptorProto& foo = file_.message_type(0);
+ const FieldDescriptorProto& bar = foo.field(0);
+
+ EXPECT_TRUE(HasSpanWithComment('a', 'd', foo,
+ " Foo leading\n line 2\n",
+ " Foo trailing\n line 2\n"));
+ EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
+ " bar leading\n",
+ " bar trailing\n"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(foo, "name"));
+ EXPECT_TRUE(HasSpan(bar, "label"));
+ EXPECT_TRUE(HasSpan(bar, "type"));
+ EXPECT_TRUE(HasSpan(bar, "name"));
+ EXPECT_TRUE(HasSpan(bar, "number"));
+}
+
+TEST_F(SourceInfoTest, DocComments2) {
+ EXPECT_TRUE(Parse(
+ "// ignored\n"
+ "syntax = \"proto2\";\n"
+ "// Foo leading\n"
+ "// line 2\n"
+ "$a$message Foo {\n"
+ " /* Foo trailing\n"
+ " * line 2 */\n"
+ " // ignored\n"
+ " /* bar leading\n"
+ " */"
+ " $b$optional int32 bar = 1;$c$ // bar trailing\n"
+ " // ignored\n"
+ "}$d$\n"
+ "// ignored\n"
+ "\n"
+ "// option leading\n"
+ "$e$option baz = 123;$f$\n"
+ "// option trailing\n"
+ ));
+
+ const DescriptorProto& foo = file_.message_type(0);
+ const FieldDescriptorProto& bar = foo.field(0);
+ const UninterpretedOption& baz = file_.options().uninterpreted_option(0);
+
+ EXPECT_TRUE(HasSpanWithComment('a', 'd', foo,
+ " Foo leading\n line 2\n",
+ " Foo trailing\n line 2 "));
+ EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
+ " bar leading\n",
+ " bar trailing\n"));
+ EXPECT_TRUE(HasSpanWithComment('e', 'f', baz,
+ " option leading\n",
+ " option trailing\n"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(foo, "name"));
+ EXPECT_TRUE(HasSpan(bar, "label"));
+ EXPECT_TRUE(HasSpan(bar, "type"));
+ EXPECT_TRUE(HasSpan(bar, "name"));
+ EXPECT_TRUE(HasSpan(bar, "number"));
+ EXPECT_TRUE(HasSpan(file_.options()));
+ EXPECT_TRUE(HasSpan(baz, "name"));
+ EXPECT_TRUE(HasSpan(baz.name(0)));
+ EXPECT_TRUE(HasSpan(baz.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(baz, "positive_int_value"));
+}
+
+TEST_F(SourceInfoTest, DocComments3) {
+ EXPECT_TRUE(Parse(
+ "$a$message Foo {\n"
+ " // bar leading\n"
+ " $b$optional int32 bar = 1 [(baz.qux) = {}];$c$\n"
+ " // bar trailing\n"
+ "}$d$\n"
+ "// ignored\n"
+ ));
+
+ const DescriptorProto& foo = file_.message_type(0);
+ const FieldDescriptorProto& bar = foo.field(0);
+
+ EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
+ " bar leading\n",
+ " bar trailing\n"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(foo));
+ EXPECT_TRUE(HasSpan(foo, "name"));
+ EXPECT_TRUE(HasSpan(bar, "label"));
+ EXPECT_TRUE(HasSpan(bar, "type"));
+ EXPECT_TRUE(HasSpan(bar, "name"));
+ EXPECT_TRUE(HasSpan(bar, "number"));
+ EXPECT_TRUE(HasSpan(bar.options()));
+ EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(
+ bar.options().uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(
+ bar.options().uninterpreted_option(0), "aggregate_value"));
+}
+
+TEST_F(SourceInfoTest, DocCommentsOneof) {
+ EXPECT_TRUE(Parse(
+ "// ignored\n"
+ "syntax = \"proto2\";\n"
+ "// Foo leading\n"
+ "$a$message Foo {\n"
+ " /* Foo trailing\n"
+ " */\n"
+ " // ignored\n"
+ " /* bar leading\n"
+ " * line 2 */\n"
+ " $b$oneof bar {\n"
+ " /* bar trailing\n"
+ " * line 2 */\n"
+ " // ignored\n"
+ " /* bar_int leading\n"
+ " */\n"
+ " $c$int32 bar_int = 1;$d$ // bar_int trailing\n"
+ " // ignored\n"
+ " }$e$\n"
+ "}$f$\n"));
+
+ const DescriptorProto& foo = file_.message_type(0);
+ const OneofDescriptorProto& bar = foo.oneof_decl(0);
+ const FieldDescriptorProto& bar_int = foo.field(0);
+
+ EXPECT_TRUE(HasSpanWithComment('a', 'f', foo,
+ " Foo leading\n",
+ " Foo trailing\n"));
+ EXPECT_TRUE(HasSpanWithComment('b', 'e', bar,
+ " bar leading\n line 2 ",
+ " bar trailing\n line 2 "));
+ EXPECT_TRUE(HasSpanWithComment('c', 'd', bar_int,
+ " bar_int leading\n",
+ " bar_int trailing\n"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(foo, "name"));
+ EXPECT_TRUE(HasSpan(bar, "name"));
+ EXPECT_TRUE(HasSpan(bar_int, "type"));
+ EXPECT_TRUE(HasSpan(bar_int, "name"));
+ EXPECT_TRUE(HasSpan(bar_int, "number"));
+}
+
// ===================================================================
} // anonymous namespace
diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc
index a4aedaf..9011a6b 100644
--- a/src/google/protobuf/compiler/plugin.cc
+++ b/src/google/protobuf/compiler/plugin.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -59,13 +59,15 @@ namespace google {
namespace protobuf {
namespace compiler {
-class GeneratorResponseOutputDirectory : public OutputDirectory {
+class GeneratorResponseContext : public GeneratorContext {
public:
- GeneratorResponseOutputDirectory(CodeGeneratorResponse* response)
- : response_(response) {}
- virtual ~GeneratorResponseOutputDirectory() {}
+ GeneratorResponseContext(CodeGeneratorResponse* response,
+ const vector<const FileDescriptor*>& parsed_files)
+ : response_(response),
+ parsed_files_(parsed_files) {}
+ virtual ~GeneratorResponseContext() {}
- // implements OutputDirectory --------------------------------------
+ // implements GeneratorContext --------------------------------------
virtual io::ZeroCopyOutputStream* Open(const string& filename) {
CodeGeneratorResponse::File* file = response_->add_file();
@@ -81,8 +83,13 @@ class GeneratorResponseOutputDirectory : public OutputDirectory {
return new io::StringOutputStream(file->mutable_content());
}
+ void ListParsedFiles(vector<const FileDescriptor*>* output) {
+ *output = parsed_files_;
+ }
+
private:
CodeGeneratorResponse* response_;
+ const vector<const FileDescriptor*>& parsed_files_;
};
int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
@@ -112,22 +119,26 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
}
}
- CodeGeneratorResponse response;
- GeneratorResponseOutputDirectory output_directory(&response);
-
+ vector<const FileDescriptor*> parsed_files;
for (int i = 0; i < request.file_to_generate_size(); i++) {
- const FileDescriptor* file =
- pool.FindFileByName(request.file_to_generate(i));
- if (file == NULL) {
+ parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i)));
+ if (parsed_files.back() == NULL) {
cerr << argv[0] << ": protoc asked plugin to generate a file but "
"did not provide a descriptor for the file: "
<< request.file_to_generate(i) << endl;
return 1;
}
+ }
+
+ CodeGeneratorResponse response;
+ GeneratorResponseContext context(&response, parsed_files);
+
+ for (int i = 0; i < parsed_files.size(); i++) {
+ const FileDescriptor* file = parsed_files[i];
string error;
bool succeeded = generator->Generate(
- file, request.parameter(), &output_directory, &error);
+ file, request.parameter(), &context, &error);
if (!succeeded && error.empty()) {
error = "Code generator returned false but provided no error "
diff --git a/src/google/protobuf/compiler/plugin.h b/src/google/protobuf/compiler/plugin.h
index 7c40333..679f9bd 100644
--- a/src/google/protobuf/compiler/plugin.h
+++ b/src/google/protobuf/compiler/plugin.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -56,7 +56,6 @@
#define GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
#include <google/protobuf/stubs/common.h>
-
namespace google {
namespace protobuf {
namespace compiler {
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index 6b0dd55..b5cd01b 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -1,11 +1,17 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/compiler/plugin.proto
#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
#include "google/protobuf/compiler/plugin.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// @@protoc_insertion_point(includes)
@@ -133,7 +139,9 @@ void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
"atorResponse\022\r\n\005error\030\001 \001(\t\022B\n\004file\030\017 \003("
"\01324.google.protobuf.compiler.CodeGenerat"
"orResponse.File\032>\n\004File\022\014\n\004name\030\001 \001(\t\022\027\n"
- "\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(\t", 399);
+ "\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(\tB"
+ ",\n\034com.google.protobuf.compilerB\014PluginP"
+ "rotos", 445);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/compiler/plugin.proto", &protobuf_RegisterTypes);
CodeGeneratorRequest::default_instance_ = new CodeGeneratorRequest();
@@ -152,10 +160,8 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto
}
} static_descriptor_initializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto_;
-
// ===================================================================
-const ::std::string CodeGeneratorRequest::_default_parameter_;
#ifndef _MSC_VER
const int CodeGeneratorRequest::kFileToGenerateFieldNumber;
const int CodeGeneratorRequest::kParameterFieldNumber;
@@ -165,6 +171,7 @@ const int CodeGeneratorRequest::kProtoFileFieldNumber;
CodeGeneratorRequest::CodeGeneratorRequest()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorRequest)
}
void CodeGeneratorRequest::InitAsDefaultInstance() {
@@ -174,20 +181,23 @@ CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorRequest)
}
void CodeGeneratorRequest::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
- parameter_ = const_cast< ::std::string*>(&_default_parameter_);
+ parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
CodeGeneratorRequest::~CodeGeneratorRequest() {
+ // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorRequest)
SharedDtor();
}
void CodeGeneratorRequest::SharedDtor() {
- if (parameter_ != &_default_parameter_) {
+ if (parameter_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete parameter_;
}
if (this != default_instance_) {
@@ -205,7 +215,8 @@ const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() {
}
const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ return *default_instance_;
}
CodeGeneratorRequest* CodeGeneratorRequest::default_instance_ = NULL;
@@ -215,11 +226,9 @@ CodeGeneratorRequest* CodeGeneratorRequest::New() const {
}
void CodeGeneratorRequest::Clear() {
- if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
- if (_has_bit(1)) {
- if (parameter_ != &_default_parameter_) {
- parameter_->clear();
- }
+ if (has_parameter()) {
+ if (parameter_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ parameter_->clear();
}
}
file_to_generate_.Clear();
@@ -230,65 +239,70 @@ void CodeGeneratorRequest::Clear() {
bool CodeGeneratorRequest::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorRequest)
+ 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 string file_to_generate = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 10) {
parse_file_to_generate:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->add_file_to_generate()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
- this->file_to_generate(0).data(), this->file_to_generate(0).length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->file_to_generate(this->file_to_generate_size() - 1).data(),
+ this->file_to_generate(this->file_to_generate_size() - 1).length(),
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "file_to_generate");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(10)) goto parse_file_to_generate;
if (input->ExpectTag(18)) goto parse_parameter;
break;
}
-
+
// optional string parameter = 2;
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 18) {
parse_parameter:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_parameter()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->parameter().data(), this->parameter().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "parameter");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(122)) goto parse_proto_file;
break;
}
-
+
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
case 15: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 122) {
parse_proto_file:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_proto_file()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(122)) goto parse_proto_file;
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -296,80 +310,93 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.compiler.CodeGeneratorRequest)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.CodeGeneratorRequest)
+ return false;
#undef DO_
}
void CodeGeneratorRequest::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.CodeGeneratorRequest)
// repeated string file_to_generate = 1;
for (int i = 0; i < this->file_to_generate_size(); i++) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->file_to_generate(i).data(), this->file_to_generate(i).length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "file_to_generate");
::google::protobuf::internal::WireFormatLite::WriteString(
1, this->file_to_generate(i), output);
}
-
+
// optional string parameter = 2;
- if (_has_bit(1)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_parameter()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->parameter().data(), this->parameter().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "parameter");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
2, this->parameter(), output);
}
-
+
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
for (int i = 0; i < this->proto_file_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
15, this->proto_file(i), output);
}
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorRequest)
}
::google::protobuf::uint8* CodeGeneratorRequest::SerializeWithCachedSizesToArray(
::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++) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->file_to_generate(i).data(), this->file_to_generate(i).length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "file_to_generate");
target = ::google::protobuf::internal::WireFormatLite::
WriteStringToArray(1, this->file_to_generate(i), target);
}
-
+
// optional string parameter = 2;
- if (_has_bit(1)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_parameter()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->parameter().data(), this->parameter().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "parameter");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
2, this->parameter(), target);
}
-
+
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
for (int i = 0; i < this->proto_file_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
15, this->proto_file(i), target);
}
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorRequest)
return target;
}
int CodeGeneratorRequest::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
// optional string parameter = 2;
if (has_parameter()) {
@@ -377,7 +404,7 @@ int CodeGeneratorRequest::ByteSize() const {
::google::protobuf::internal::WireFormatLite::StringSize(
this->parameter());
}
-
+
}
// repeated string file_to_generate = 1;
total_size += 1 * this->file_to_generate_size();
@@ -385,7 +412,7 @@ int CodeGeneratorRequest::ByteSize() const {
total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
this->file_to_generate(i));
}
-
+
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
total_size += 1 * this->proto_file_size();
for (int i = 0; i < this->proto_file_size(); i++) {
@@ -393,7 +420,7 @@ int CodeGeneratorRequest::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->proto_file(i));
}
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -422,7 +449,7 @@ void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) {
file_to_generate_.MergeFrom(from.file_to_generate_);
proto_file_.MergeFrom(from.proto_file_);
if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
- if (from._has_bit(1)) {
+ if (from.has_parameter()) {
set_parameter(from.parameter());
}
}
@@ -442,10 +469,8 @@ void CodeGeneratorRequest::CopyFrom(const CodeGeneratorRequest& from) {
}
bool CodeGeneratorRequest::IsInitialized() const {
-
- for (int i = 0; i < proto_file_size(); i++) {
- if (!this->proto_file(i).IsInitialized()) return false;
- }
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->proto_file())) return false;
return true;
}
@@ -471,9 +496,6 @@ void CodeGeneratorRequest::Swap(CodeGeneratorRequest* other) {
// ===================================================================
-const ::std::string CodeGeneratorResponse_File::_default_name_;
-const ::std::string CodeGeneratorResponse_File::_default_insertion_point_;
-const ::std::string CodeGeneratorResponse_File::_default_content_;
#ifndef _MSC_VER
const int CodeGeneratorResponse_File::kNameFieldNumber;
const int CodeGeneratorResponse_File::kInsertionPointFieldNumber;
@@ -483,6 +505,7 @@ const int CodeGeneratorResponse_File::kContentFieldNumber;
CodeGeneratorResponse_File::CodeGeneratorResponse_File()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
}
void CodeGeneratorResponse_File::InitAsDefaultInstance() {
@@ -492,28 +515,31 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorRespon
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
}
void CodeGeneratorResponse_File::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
- insertion_point_ = const_cast< ::std::string*>(&_default_insertion_point_);
- content_ = const_cast< ::std::string*>(&_default_content_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ content_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
CodeGeneratorResponse_File::~CodeGeneratorResponse_File() {
+ // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse.File)
SharedDtor();
}
void CodeGeneratorResponse_File::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete name_;
}
- if (insertion_point_ != &_default_insertion_point_) {
+ if (insertion_point_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete insertion_point_;
}
- if (content_ != &_default_content_) {
+ if (content_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete content_;
}
if (this != default_instance_) {
@@ -531,7 +557,8 @@ const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() {
}
const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ return *default_instance_;
}
CodeGeneratorResponse_File* CodeGeneratorResponse_File::default_instance_ = NULL;
@@ -541,19 +568,19 @@ CodeGeneratorResponse_File* CodeGeneratorResponse_File::New() const {
}
void CodeGeneratorResponse_File::Clear() {
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (_has_bits_[0 / 32] & 7) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
}
- if (_has_bit(1)) {
- if (insertion_point_ != &_default_insertion_point_) {
+ if (has_insertion_point()) {
+ if (insertion_point_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
insertion_point_->clear();
}
}
- if (_has_bit(2)) {
- if (content_ != &_default_content_) {
+ if (has_content()) {
+ if (content_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
content_->clear();
}
}
@@ -564,65 +591,70 @@ void CodeGeneratorResponse_File::Clear() {
bool CodeGeneratorResponse_File::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorResponse.File)
+ 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)) {
// optional string name = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "name");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(18)) goto parse_insertion_point;
break;
}
-
+
// optional string insertion_point = 2;
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 18) {
parse_insertion_point:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_insertion_point()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->insertion_point().data(), this->insertion_point().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "insertion_point");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(122)) goto parse_content;
break;
}
-
+
// optional string content = 15;
case 15: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 122) {
parse_content:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_content()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->content().data(), this->content().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "content");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -630,87 +662,102 @@ bool CodeGeneratorResponse_File::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.compiler.CodeGeneratorResponse.File)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.CodeGeneratorResponse.File)
+ return false;
#undef DO_
}
void CodeGeneratorResponse_File::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.CodeGeneratorResponse.File)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
}
-
+
// optional string insertion_point = 2;
- if (_has_bit(1)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_insertion_point()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->insertion_point().data(), this->insertion_point().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "insertion_point");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
2, this->insertion_point(), output);
}
-
+
// optional string content = 15;
- if (_has_bit(2)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_content()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->content().data(), this->content().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "content");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
15, this->content(), output);
}
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorResponse.File)
}
::google::protobuf::uint8* CodeGeneratorResponse_File::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse.File)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
1, this->name(), target);
}
-
+
// optional string insertion_point = 2;
- if (_has_bit(1)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_insertion_point()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->insertion_point().data(), this->insertion_point().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "insertion_point");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
2, this->insertion_point(), target);
}
-
+
// optional string content = 15;
- if (_has_bit(2)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_content()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->content().data(), this->content().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "content");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
15, this->content(), target);
}
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse.File)
return target;
}
int CodeGeneratorResponse_File::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// optional string name = 1;
if (has_name()) {
@@ -718,21 +765,21 @@ int CodeGeneratorResponse_File::ByteSize() const {
::google::protobuf::internal::WireFormatLite::StringSize(
this->name());
}
-
+
// optional string insertion_point = 2;
if (has_insertion_point()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->insertion_point());
}
-
+
// optional string content = 15;
if (has_content()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->content());
}
-
+
}
if (!unknown_fields().empty()) {
total_size +=
@@ -760,13 +807,13 @@ void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& fr
void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(1)) {
+ if (from.has_insertion_point()) {
set_insertion_point(from.insertion_point());
}
- if (from._has_bit(2)) {
+ if (from.has_content()) {
set_content(from.content());
}
}
@@ -786,7 +833,7 @@ void CodeGeneratorResponse_File::CopyFrom(const CodeGeneratorResponse_File& from
}
bool CodeGeneratorResponse_File::IsInitialized() const {
-
+
return true;
}
@@ -812,7 +859,6 @@ void CodeGeneratorResponse_File::Swap(CodeGeneratorResponse_File* other) {
// -------------------------------------------------------------------
-const ::std::string CodeGeneratorResponse::_default_error_;
#ifndef _MSC_VER
const int CodeGeneratorResponse::kErrorFieldNumber;
const int CodeGeneratorResponse::kFileFieldNumber;
@@ -821,6 +867,7 @@ const int CodeGeneratorResponse::kFileFieldNumber;
CodeGeneratorResponse::CodeGeneratorResponse()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse)
}
void CodeGeneratorResponse::InitAsDefaultInstance() {
@@ -830,20 +877,23 @@ CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse)
}
void CodeGeneratorResponse::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
- error_ = const_cast< ::std::string*>(&_default_error_);
+ error_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
CodeGeneratorResponse::~CodeGeneratorResponse() {
+ // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse)
SharedDtor();
}
void CodeGeneratorResponse::SharedDtor() {
- if (error_ != &_default_error_) {
+ if (error_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete error_;
}
if (this != default_instance_) {
@@ -861,7 +911,8 @@ const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() {
}
const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ return *default_instance_;
}
CodeGeneratorResponse* CodeGeneratorResponse::default_instance_ = NULL;
@@ -871,11 +922,9 @@ CodeGeneratorResponse* CodeGeneratorResponse::New() const {
}
void CodeGeneratorResponse::Clear() {
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (error_ != &_default_error_) {
- error_->clear();
- }
+ if (has_error()) {
+ if (error_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ error_->clear();
}
}
file_.Clear();
@@ -885,46 +934,50 @@ void CodeGeneratorResponse::Clear() {
bool CodeGeneratorResponse::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorResponse)
+ 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)) {
// optional string error = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_error()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->error().data(), this->error().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "error");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(122)) goto parse_file;
break;
}
-
+
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
case 15: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 122) {
parse_file:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_file()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(122)) goto parse_file;
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -932,62 +985,73 @@ bool CodeGeneratorResponse::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.compiler.CodeGeneratorResponse)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.CodeGeneratorResponse)
+ return false;
#undef DO_
}
void CodeGeneratorResponse::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.CodeGeneratorResponse)
// optional string error = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_error()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->error().data(), this->error().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "error");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->error(), output);
}
-
+
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
for (int i = 0; i < this->file_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
15, this->file(i), output);
}
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorResponse)
}
::google::protobuf::uint8* CodeGeneratorResponse::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse)
// optional string error = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_error()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->error().data(), this->error().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "error");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
1, this->error(), target);
}
-
+
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
for (int i = 0; i < this->file_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
15, this->file(i), target);
}
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse)
return target;
}
int CodeGeneratorResponse::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// optional string error = 1;
if (has_error()) {
@@ -995,7 +1059,7 @@ int CodeGeneratorResponse::ByteSize() const {
::google::protobuf::internal::WireFormatLite::StringSize(
this->error());
}
-
+
}
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
total_size += 1 * this->file_size();
@@ -1004,7 +1068,7 @@ int CodeGeneratorResponse::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->file(i));
}
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -1032,7 +1096,7 @@ void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) {
GOOGLE_CHECK_NE(&from, this);
file_.MergeFrom(from.file_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_error()) {
set_error(from.error());
}
}
@@ -1052,7 +1116,7 @@ void CodeGeneratorResponse::CopyFrom(const CodeGeneratorResponse& from) {
}
bool CodeGeneratorResponse::IsInitialized() const {
-
+
return true;
}
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index f8f8053..65634da 100644
--- a/src/google/protobuf/compiler/plugin.pb.h
+++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -8,21 +8,22 @@
#include <google/protobuf/stubs/common.h>
-#if GOOGLE_PROTOBUF_VERSION < 2003000
+#if GOOGLE_PROTOBUF_VERSION < 2006000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
-#if 2003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
-#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/unknown_field_set.h>
#include "google/protobuf/descriptor.pb.h"
// @@protoc_insertion_point(includes)
@@ -45,29 +46,29 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
public:
CodeGeneratorRequest();
virtual ~CodeGeneratorRequest();
-
+
CodeGeneratorRequest(const CodeGeneratorRequest& from);
-
+
inline CodeGeneratorRequest& operator=(const CodeGeneratorRequest& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const CodeGeneratorRequest& default_instance();
-
+
void Swap(CodeGeneratorRequest* other);
-
+
// implements Message ----------------------------------------------
-
+
CodeGeneratorRequest* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -75,7 +76,7 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
void MergeFrom(const CodeGeneratorRequest& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -88,13 +89,12 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
// repeated string file_to_generate = 1;
inline int file_to_generate_size() const;
inline void clear_file_to_generate();
@@ -110,7 +110,7 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
inline void add_file_to_generate(const char* value, size_t size);
inline const ::google::protobuf::RepeatedPtrField< ::std::string>& file_to_generate() const;
inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_to_generate();
-
+
// optional string parameter = 2;
inline bool has_parameter() const;
inline void clear_parameter();
@@ -120,7 +120,9 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
inline void set_parameter(const char* value);
inline void set_parameter(const char* value, size_t size);
inline ::std::string* mutable_parameter();
-
+ inline ::std::string* release_parameter();
+ inline void set_allocated_parameter(::std::string* parameter);
+
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
inline int proto_file_size() const;
inline void clear_proto_file();
@@ -132,33 +134,23 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
proto_file() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
mutable_proto_file();
-
+
// @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
private:
+ inline void set_has_parameter();
+ inline void clear_has_parameter();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::google::protobuf::RepeatedPtrField< ::std::string> file_to_generate_;
::std::string* parameter_;
- static const ::std::string _default_parameter_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_;
friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
-
- ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static CodeGeneratorRequest* default_instance_;
};
@@ -168,29 +160,29 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
public:
CodeGeneratorResponse_File();
virtual ~CodeGeneratorResponse_File();
-
+
CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from);
-
+
inline CodeGeneratorResponse_File& operator=(const CodeGeneratorResponse_File& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const CodeGeneratorResponse_File& default_instance();
-
+
void Swap(CodeGeneratorResponse_File* other);
-
+
// implements Message ----------------------------------------------
-
+
CodeGeneratorResponse_File* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -198,7 +190,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
void MergeFrom(const CodeGeneratorResponse_File& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -211,13 +203,12 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
// optional string name = 1;
inline bool has_name() const;
inline void clear_name();
@@ -227,7 +218,9 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
-
+ inline ::std::string* release_name();
+ inline void set_allocated_name(::std::string* name);
+
// optional string insertion_point = 2;
inline bool has_insertion_point() const;
inline void clear_insertion_point();
@@ -237,7 +230,9 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
inline void set_insertion_point(const char* value);
inline void set_insertion_point(const char* value, size_t size);
inline ::std::string* mutable_insertion_point();
-
+ inline ::std::string* release_insertion_point();
+ inline void set_allocated_insertion_point(::std::string* insertion_point);
+
// optional string content = 15;
inline bool has_content() const;
inline void clear_content();
@@ -247,35 +242,29 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
inline void set_content(const char* value);
inline void set_content(const char* value, size_t size);
inline ::std::string* mutable_content();
-
+ inline ::std::string* release_content();
+ inline void set_allocated_content(::std::string* content);
+
// @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_insertion_point();
+ inline void clear_has_insertion_point();
+ inline void set_has_content();
+ inline void clear_has_content();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::std::string* name_;
- static const ::std::string _default_name_;
::std::string* insertion_point_;
- static const ::std::string _default_insertion_point_;
::std::string* content_;
- static const ::std::string _default_content_;
friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
-
- ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static CodeGeneratorResponse_File* default_instance_;
};
@@ -285,29 +274,29 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
public:
CodeGeneratorResponse();
virtual ~CodeGeneratorResponse();
-
+
CodeGeneratorResponse(const CodeGeneratorResponse& from);
-
+
inline CodeGeneratorResponse& operator=(const CodeGeneratorResponse& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const CodeGeneratorResponse& default_instance();
-
+
void Swap(CodeGeneratorResponse* other);
-
+
// implements Message ----------------------------------------------
-
+
CodeGeneratorResponse* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -315,7 +304,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
void MergeFrom(const CodeGeneratorResponse& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -328,15 +317,14 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
typedef CodeGeneratorResponse_File File;
-
+
// accessors -------------------------------------------------------
-
+
// optional string error = 1;
inline bool has_error() const;
inline void clear_error();
@@ -346,7 +334,9 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
inline void set_error(const char* value);
inline void set_error(const char* value, size_t size);
inline ::std::string* mutable_error();
-
+ inline ::std::string* release_error();
+ inline void set_allocated_error(::std::string* error);
+
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
inline int file_size() const;
inline void clear_file();
@@ -358,32 +348,22 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
file() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
mutable_file();
-
+
// @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
private:
+ inline void set_has_error();
+ inline void clear_has_error();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::std::string* error_;
- static const ::std::string _default_error_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_;
friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
-
- ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static CodeGeneratorResponse* default_instance_;
};
@@ -402,83 +382,127 @@ inline void CodeGeneratorRequest::clear_file_to_generate() {
file_to_generate_.Clear();
}
inline const ::std::string& CodeGeneratorRequest::file_to_generate(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
return file_to_generate_.Get(index);
}
inline ::std::string* CodeGeneratorRequest::mutable_file_to_generate(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
return file_to_generate_.Mutable(index);
}
inline void CodeGeneratorRequest::set_file_to_generate(int index, const ::std::string& value) {
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
file_to_generate_.Mutable(index)->assign(value);
}
inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) {
file_to_generate_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value, size_t size) {
file_to_generate_.Mutable(index)->assign(
reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline ::std::string* CodeGeneratorRequest::add_file_to_generate() {
return file_to_generate_.Add();
}
inline void CodeGeneratorRequest::add_file_to_generate(const ::std::string& value) {
file_to_generate_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline void CodeGeneratorRequest::add_file_to_generate(const char* value) {
file_to_generate_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline void CodeGeneratorRequest::add_file_to_generate(const char* value, size_t size) {
file_to_generate_.Add()->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_add_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
CodeGeneratorRequest::file_to_generate() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
return file_to_generate_;
}
inline ::google::protobuf::RepeatedPtrField< ::std::string>*
CodeGeneratorRequest::mutable_file_to_generate() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
return &file_to_generate_;
}
// optional string parameter = 2;
inline bool CodeGeneratorRequest::has_parameter() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void CodeGeneratorRequest::set_has_parameter() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void CodeGeneratorRequest::clear_has_parameter() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void CodeGeneratorRequest::clear_parameter() {
- if (parameter_ != &_default_parameter_) {
+ if (parameter_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
parameter_->clear();
}
- _clear_bit(1);
+ clear_has_parameter();
}
inline const ::std::string& CodeGeneratorRequest::parameter() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.parameter)
return *parameter_;
}
inline void CodeGeneratorRequest::set_parameter(const ::std::string& value) {
- _set_bit(1);
- if (parameter_ == &_default_parameter_) {
+ set_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
parameter_ = new ::std::string;
}
parameter_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter)
}
inline void CodeGeneratorRequest::set_parameter(const char* value) {
- _set_bit(1);
- if (parameter_ == &_default_parameter_) {
+ set_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
parameter_ = new ::std::string;
}
parameter_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.parameter)
}
inline void CodeGeneratorRequest::set_parameter(const char* value, size_t size) {
- _set_bit(1);
- if (parameter_ == &_default_parameter_) {
+ set_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
parameter_ = new ::std::string;
}
parameter_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.parameter)
}
inline ::std::string* CodeGeneratorRequest::mutable_parameter() {
- _set_bit(1);
- if (parameter_ == &_default_parameter_) {
+ set_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
parameter_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.parameter)
return parameter_;
}
+inline ::std::string* CodeGeneratorRequest::release_parameter() {
+ clear_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = parameter_;
+ parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void CodeGeneratorRequest::set_allocated_parameter(::std::string* parameter) {
+ if (parameter_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete parameter_;
+ }
+ if (parameter) {
+ set_has_parameter();
+ parameter_ = parameter;
+ } else {
+ clear_has_parameter();
+ parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+}
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
inline int CodeGeneratorRequest::proto_file_size() const {
@@ -488,20 +512,25 @@ inline void CodeGeneratorRequest::clear_proto_file() {
proto_file_.Clear();
}
inline const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return proto_file_.Get(index);
}
inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return proto_file_.Mutable(index);
}
inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() {
+ // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return proto_file_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
CodeGeneratorRequest::proto_file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return proto_file_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
CodeGeneratorRequest::mutable_proto_file() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return &proto_file_;
}
@@ -511,129 +540,231 @@ CodeGeneratorRequest::mutable_proto_file() {
// optional string name = 1;
inline bool CodeGeneratorResponse_File::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void CodeGeneratorResponse_File::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void CodeGeneratorResponse_File::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void CodeGeneratorResponse_File::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& CodeGeneratorResponse_File::name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.name)
return *name_;
}
inline void CodeGeneratorResponse_File::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name)
}
inline void CodeGeneratorResponse_File::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.name)
}
inline void CodeGeneratorResponse_File::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.name)
}
inline ::std::string* CodeGeneratorResponse_File::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.name)
return name_;
}
+inline ::std::string* CodeGeneratorResponse_File::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void CodeGeneratorResponse_File::set_allocated_name(::std::string* name) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete name_;
+ }
+ if (name) {
+ set_has_name();
+ name_ = name;
+ } else {
+ clear_has_name();
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+}
// optional string insertion_point = 2;
inline bool CodeGeneratorResponse_File::has_insertion_point() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void CodeGeneratorResponse_File::set_has_insertion_point() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void CodeGeneratorResponse_File::clear_has_insertion_point() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void CodeGeneratorResponse_File::clear_insertion_point() {
- if (insertion_point_ != &_default_insertion_point_) {
+ if (insertion_point_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
insertion_point_->clear();
}
- _clear_bit(1);
+ clear_has_insertion_point();
}
inline const ::std::string& CodeGeneratorResponse_File::insertion_point() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
return *insertion_point_;
}
inline void CodeGeneratorResponse_File::set_insertion_point(const ::std::string& value) {
- _set_bit(1);
- if (insertion_point_ == &_default_insertion_point_) {
+ set_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
insertion_point_ = new ::std::string;
}
insertion_point_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
}
inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) {
- _set_bit(1);
- if (insertion_point_ == &_default_insertion_point_) {
+ set_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
insertion_point_ = new ::std::string;
}
insertion_point_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
}
inline void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) {
- _set_bit(1);
- if (insertion_point_ == &_default_insertion_point_) {
+ set_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
insertion_point_ = new ::std::string;
}
insertion_point_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
}
inline ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() {
- _set_bit(1);
- if (insertion_point_ == &_default_insertion_point_) {
+ set_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
insertion_point_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
return insertion_point_;
}
+inline ::std::string* CodeGeneratorResponse_File::release_insertion_point() {
+ clear_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = insertion_point_;
+ insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void CodeGeneratorResponse_File::set_allocated_insertion_point(::std::string* insertion_point) {
+ if (insertion_point_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete insertion_point_;
+ }
+ if (insertion_point) {
+ set_has_insertion_point();
+ insertion_point_ = insertion_point;
+ } else {
+ clear_has_insertion_point();
+ insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+}
// optional string content = 15;
inline bool CodeGeneratorResponse_File::has_content() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void CodeGeneratorResponse_File::set_has_content() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void CodeGeneratorResponse_File::clear_has_content() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void CodeGeneratorResponse_File::clear_content() {
- if (content_ != &_default_content_) {
+ if (content_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
content_->clear();
}
- _clear_bit(2);
+ clear_has_content();
}
inline const ::std::string& CodeGeneratorResponse_File::content() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.content)
return *content_;
}
inline void CodeGeneratorResponse_File::set_content(const ::std::string& value) {
- _set_bit(2);
- if (content_ == &_default_content_) {
+ set_has_content();
+ if (content_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
content_ = new ::std::string;
}
content_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content)
}
inline void CodeGeneratorResponse_File::set_content(const char* value) {
- _set_bit(2);
- if (content_ == &_default_content_) {
+ set_has_content();
+ if (content_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
content_ = new ::std::string;
}
content_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.content)
}
inline void CodeGeneratorResponse_File::set_content(const char* value, size_t size) {
- _set_bit(2);
- if (content_ == &_default_content_) {
+ set_has_content();
+ if (content_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
content_ = new ::std::string;
}
content_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.content)
}
inline ::std::string* CodeGeneratorResponse_File::mutable_content() {
- _set_bit(2);
- if (content_ == &_default_content_) {
+ set_has_content();
+ if (content_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
content_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.content)
return content_;
}
+inline ::std::string* CodeGeneratorResponse_File::release_content() {
+ clear_has_content();
+ if (content_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = content_;
+ content_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void CodeGeneratorResponse_File::set_allocated_content(::std::string* content) {
+ if (content_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete content_;
+ }
+ if (content) {
+ set_has_content();
+ content_ = content;
+ } else {
+ clear_has_content();
+ content_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+}
// -------------------------------------------------------------------
@@ -641,45 +772,79 @@ inline ::std::string* CodeGeneratorResponse_File::mutable_content() {
// optional string error = 1;
inline bool CodeGeneratorResponse::has_error() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void CodeGeneratorResponse::set_has_error() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void CodeGeneratorResponse::clear_has_error() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void CodeGeneratorResponse::clear_error() {
- if (error_ != &_default_error_) {
+ if (error_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
error_->clear();
}
- _clear_bit(0);
+ clear_has_error();
}
inline const ::std::string& CodeGeneratorResponse::error() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.error)
return *error_;
}
inline void CodeGeneratorResponse::set_error(const ::std::string& value) {
- _set_bit(0);
- if (error_ == &_default_error_) {
+ set_has_error();
+ if (error_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
error_ = new ::std::string;
}
error_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error)
}
inline void CodeGeneratorResponse::set_error(const char* value) {
- _set_bit(0);
- if (error_ == &_default_error_) {
+ set_has_error();
+ if (error_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
error_ = new ::std::string;
}
error_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.error)
}
inline void CodeGeneratorResponse::set_error(const char* value, size_t size) {
- _set_bit(0);
- if (error_ == &_default_error_) {
+ set_has_error();
+ if (error_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
error_ = new ::std::string;
}
error_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.error)
}
inline ::std::string* CodeGeneratorResponse::mutable_error() {
- _set_bit(0);
- if (error_ == &_default_error_) {
+ set_has_error();
+ if (error_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
error_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.error)
return error_;
}
+inline ::std::string* CodeGeneratorResponse::release_error() {
+ clear_has_error();
+ if (error_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = error_;
+ error_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void CodeGeneratorResponse::set_allocated_error(::std::string* error) {
+ if (error_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete error_;
+ }
+ if (error) {
+ set_has_error();
+ error_ = error;
+ } else {
+ clear_has_error();
+ error_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error)
+}
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
inline int CodeGeneratorResponse::file_size() const {
@@ -689,20 +854,25 @@ inline void CodeGeneratorResponse::clear_file() {
file_.Clear();
}
inline const ::google::protobuf::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.file)
return file_.Get(index);
}
inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.file)
return file_.Mutable(index);
}
inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() {
+ // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file)
return file_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
CodeGeneratorResponse::file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file)
return file_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
CodeGeneratorResponse::mutable_file() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file)
return &file_;
}
diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto
index 4e928b0..b65379d 100644
--- a/src/google/protobuf/compiler/plugin.proto
+++ b/src/google/protobuf/compiler/plugin.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -45,6 +45,8 @@
// flag "--${NAME}_out" is passed to protoc.
package google.protobuf.compiler;
+option java_package = "com.google.protobuf.compiler";
+option java_outer_classname = "PluginProtos";
import "google/protobuf/descriptor.proto";
@@ -131,7 +133,7 @@ message CodeGeneratorResponse {
// in order to work correctly in that context.
//
// The code generator that generates the initial file and the one which
- // inserts into it must both run as part of a single invocatino of protoc.
+ // inserts into it must both run as part of a single invocation of protoc.
// Code generators are executed in the order in which they appear on the
// command line.
//
diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc
index fae83a3..15e05da 100644
--- a/src/google/protobuf/compiler/python/python_generator.cc
+++ b/src/google/protobuf/compiler/python/python_generator.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -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.
+//#PY25 compatible generated code for GAE.
+// Copyright 2007 Google Inc. All Rights Reserved.
// Author: robinson@google.com (Will Robinson)
//
// This module outputs pure-Python protocol message classes that will
@@ -45,6 +47,7 @@
#include <limits>
#include <map>
#include <utility>
+#include <memory>
#include <string>
#include <vector>
@@ -52,6 +55,7 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/zero_copy_stream.h>
@@ -106,6 +110,12 @@ string NamePrefixedWithNestedTypes(const DescriptorT& descriptor,
const char kDescriptorKey[] = "DESCRIPTOR";
+// Does the file have top-level enums?
+inline bool HasTopLevelEnums(const FileDescriptor *file) {
+ return file->enum_type_count() > 0;
+}
+
+
// Should we generate generic services for this file?
inline bool HasGenericServices(const FileDescriptor *file) {
return file->service_count() > 0 &&
@@ -120,13 +130,23 @@ void PrintTopBoilerplate(
// TODO(robinson): Allow parameterization of Python version?
printer->Print(
"# Generated by the protocol buffer compiler. DO NOT EDIT!\n"
- "\n"
- "from google.protobuf import descriptor\n"
- "from google.protobuf import message\n"
- "from google.protobuf import reflection\n");
+ "# source: $filename$\n"
+ "\nimport sys\n_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))" //##PY25
+ "\n",
+ "filename", file->name());
+ if (HasTopLevelEnums(file)) {
+ printer->Print(
+ "from google.protobuf.internal import enum_type_wrapper\n");
+ }
+ printer->Print(
+ "from google.protobuf import descriptor as _descriptor\n"
+ "from google.protobuf import message as _message\n"
+ "from google.protobuf import reflection as _reflection\n"
+ "from google.protobuf import symbol_database as "
+ "_symbol_database\n");
if (HasGenericServices(file)) {
printer->Print(
- "from google.protobuf import service\n"
+ "from google.protobuf import service as _service\n"
"from google.protobuf import service_reflection\n");
}
@@ -136,7 +156,8 @@ void PrintTopBoilerplate(
"from google.protobuf import descriptor_pb2\n");
}
printer->Print(
- "# @@protoc_insertion_point(imports)\n");
+ "# @@protoc_insertion_point(imports)\n\n"
+ "_sym_db = _symbol_database.Default()\n");
printer->Print("\n\n");
}
@@ -202,12 +223,12 @@ string StringifyDefaultValue(const FieldDescriptor& field) {
case FieldDescriptor::CPPTYPE_ENUM:
return SimpleItoa(field.default_value_enum()->number());
case FieldDescriptor::CPPTYPE_STRING:
- if (field.type() == FieldDescriptor::TYPE_STRING) {
- return "unicode(\"" + CEscape(field.default_value_string()) +
- "\", \"utf-8\")";
- } else {
- return "\"" + CEscape(field.default_value_string()) + "\"";
- }
+//##!PY25 return "b\"" + CEscape(field.default_value_string()) +
+//##!PY25 (field.type() != FieldDescriptor::TYPE_STRING ? "\"" :
+//##!PY25 "\".decode('utf-8')");
+ return "_b(\"" + CEscape(field.default_value_string()) + //##PY25
+ (field.type() != FieldDescriptor::TYPE_STRING ? "\")" : //##PY25
+ "\").decode('utf-8')"); //##PY25
case FieldDescriptor::CPPTYPE_MESSAGE:
return "None";
}
@@ -230,7 +251,7 @@ Generator::~Generator() {
bool Generator::Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
// Completely serialize all Generate() calls on this instance. The
@@ -252,26 +273,29 @@ bool Generator::Generate(const FileDescriptor* file,
fdp.SerializeToString(&file_descriptor_serialized_);
- scoped_ptr<io::ZeroCopyOutputStream> output(output_directory->Open(filename));
+ scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
GOOGLE_CHECK(output.get());
io::Printer printer(output.get(), '$');
printer_ = &printer;
PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto());
+ PrintImports();
PrintFileDescriptor();
PrintTopLevelEnums();
PrintTopLevelExtensions();
PrintAllNestedEnumsInFile();
PrintMessageDescriptors();
- // We have to print the imports after the descriptors, so that mutually
- // recursive protos in separate files can successfully reference each other.
- PrintImports();
FixForeignFieldsInDescriptors();
PrintMessages();
// We have to fix up the extensions after the message classes themselves,
// since they need to call static RegisterExtension() methods on these
// classes.
FixForeignFieldsInExtensions();
+ // Descriptor options may have custom extensions. These custom options
+ // can only be successfully parsed after we register corresponding
+ // extensions. Therefore we parse all options again here to recognize
+ // custom options that may be unknown when we define the descriptors.
+ FixAllDescriptorOptions();
if (HasGenericServices(file)) {
PrintServices();
}
@@ -290,6 +314,13 @@ void Generator::PrintImports() const {
module_name);
}
printer_->Print("\n");
+
+ // Print public imports.
+ for (int i = 0; i < file_->public_dependency_count(); ++i) {
+ string module_name = ModuleName(file_->public_dependency(i)->name());
+ printer_->Print("from $module$ import *\n", "module", module_name);
+ }
+ printer_->Print("\n");
}
// Prints the single file descriptor for this file.
@@ -299,20 +330,31 @@ void Generator::PrintFileDescriptor() const {
m["name"] = file_->name();
m["package"] = file_->package();
const char file_descriptor_template[] =
- "$descriptor_name$ = descriptor.FileDescriptor(\n"
+ "$descriptor_name$ = _descriptor.FileDescriptor(\n"
" name='$name$',\n"
" package='$package$',\n";
printer_->Print(m, file_descriptor_template);
printer_->Indent();
printer_->Print(
- "serialized_pb='$value$'",
+//##!PY25 "serialized_pb=b'$value$'\n",
+ "serialized_pb=_b('$value$')\n", //##PY25
"value", strings::CHexEscape(file_descriptor_serialized_));
+ if (file_->dependency_count() != 0) {
+ printer_->Print(",\ndependencies=[");
+ for (int i = 0; i < file_->dependency_count(); ++i) {
+ string module_name = ModuleName(file_->dependency(i)->name());
+ printer_->Print("$module_name$.DESCRIPTOR,", "module_name", module_name);
+ }
+ printer_->Print("]");
+ }
// TODO(falk): Also print options and fix the message_type, enum_type,
// service and extension later in the generation.
printer_->Outdent();
printer_->Print(")\n");
+ printer_->Print("_sym_db.RegisterFileDescriptor($name$)\n", "name",
+ kDescriptorKey);
printer_->Print("\n");
}
@@ -323,6 +365,11 @@ void Generator::PrintTopLevelEnums() const {
for (int i = 0; i < file_->enum_type_count(); ++i) {
const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
PrintEnum(enum_descriptor);
+ printer_->Print("$name$ = "
+ "enum_type_wrapper.EnumTypeWrapper($descriptor_name$)",
+ "name", enum_descriptor.name(),
+ "descriptor_name",
+ ModuleLevelDescriptorName(enum_descriptor));
printer_->Print("\n");
for (int j = 0; j < enum_descriptor.value_count(); ++j) {
@@ -352,12 +399,14 @@ void Generator::PrintAllNestedEnumsInFile() const {
// enum_descriptor.
void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
map<string, string> m;
- m["descriptor_name"] = ModuleLevelDescriptorName(enum_descriptor);
+ string module_level_descriptor_name =
+ ModuleLevelDescriptorName(enum_descriptor);
+ m["descriptor_name"] = module_level_descriptor_name;
m["name"] = enum_descriptor.name();
m["full_name"] = enum_descriptor.full_name();
m["file"] = kDescriptorKey;
const char enum_descriptor_template[] =
- "$descriptor_name$ = descriptor.EnumDescriptor(\n"
+ "$descriptor_name$ = _descriptor.EnumDescriptor(\n"
" name='$name$',\n"
" full_name='$full_name$',\n"
" filename=None,\n"
@@ -377,11 +426,13 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
printer_->Print("containing_type=None,\n");
printer_->Print("options=$options_value$,\n",
"options_value",
- OptionsValue("EnumOptions", CEscape(options_string)));
+ OptionsValue("EnumOptions", options_string));
EnumDescriptorProto edp;
PrintSerializedPbInterval(enum_descriptor, edp);
printer_->Outdent();
printer_->Print(")\n");
+ printer_->Print("_sym_db.RegisterEnumDescriptor($name$)\n", "name",
+ module_level_descriptor_name);
printer_->Print("\n");
}
@@ -438,7 +489,7 @@ void Generator::PrintServiceDescriptor(
descriptor.options().SerializeToString(&options_string);
printer_->Print(
- "$service_name$ = descriptor.ServiceDescriptor(\n",
+ "$service_name$ = _descriptor.ServiceDescriptor(\n",
"service_name", service_name);
printer_->Indent();
map<string, string> m;
@@ -461,7 +512,6 @@ void Generator::PrintServiceDescriptor(
printer_->Print("methods=[\n");
for (int i = 0; i < descriptor.method_count(); ++i) {
const MethodDescriptor* method = descriptor.method(i);
- string options_string;
method->options().SerializeToString(&options_string);
m.clear();
@@ -472,7 +522,7 @@ void Generator::PrintServiceDescriptor(
m["input_type"] = ModuleLevelDescriptorName(*(method->input_type()));
m["output_type"] = ModuleLevelDescriptorName(*(method->output_type()));
m["options_value"] = OptionsValue("MethodOptions", options_string);
- printer_->Print("descriptor.MethodDescriptor(\n");
+ printer_->Print("_descriptor.MethodDescriptor(\n");
printer_->Indent();
printer_->Print(
m,
@@ -493,27 +543,36 @@ void Generator::PrintServiceDescriptor(
void Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const {
// Print the service.
- printer_->Print("class $class_name$(service.Service):\n",
+ printer_->Print("$class_name$ = service_reflection.GeneratedServiceType("
+ "'$class_name$', (_service.Service,), dict(\n",
"class_name", descriptor.name());
printer_->Indent();
printer_->Print(
- "__metaclass__ = service_reflection.GeneratedServiceType\n"
- "$descriptor_key$ = $descriptor_name$\n",
+ "$descriptor_key$ = $descriptor_name$,\n",
"descriptor_key", kDescriptorKey,
"descriptor_name", ModuleLevelServiceDescriptorName(descriptor));
+ printer_->Print(
+ "__module__ = '$module_name$'\n",
+ "module_name", ModuleName(file_->name()));
+ printer_->Print("))\n\n");
printer_->Outdent();
}
void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const {
// Print the service stub.
- printer_->Print("class $class_name$_Stub($class_name$):\n",
+ printer_->Print("$class_name$_Stub = "
+ "service_reflection.GeneratedServiceStubType("
+ "'$class_name$_Stub', ($class_name$,), dict(\n",
"class_name", descriptor.name());
printer_->Indent();
printer_->Print(
- "__metaclass__ = service_reflection.GeneratedServiceStubType\n"
- "$descriptor_key$ = $descriptor_name$\n",
+ "$descriptor_key$ = $descriptor_name$,\n",
"descriptor_key", kDescriptorKey,
"descriptor_name", ModuleLevelServiceDescriptorName(descriptor));
+ printer_->Print(
+ "__module__ = '$module_name$'\n",
+ "module_name", ModuleName(file_->name()));
+ printer_->Print("))\n\n");
printer_->Outdent();
}
@@ -525,7 +584,7 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
PrintNestedDescriptors(message_descriptor);
printer_->Print("\n");
- printer_->Print("$descriptor_name$ = descriptor.Descriptor(\n",
+ printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n",
"descriptor_name",
ModuleLevelDescriptorName(message_descriptor));
printer_->Indent();
@@ -583,7 +642,22 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
"end", SimpleItoa(range->end));
}
printer_->Print("],\n");
-
+ printer_->Print("oneofs=[\n");
+ printer_->Indent();
+ for (int i = 0; i < message_descriptor.oneof_decl_count(); ++i) {
+ const OneofDescriptor* desc = message_descriptor.oneof_decl(i);
+ map<string, string> m;
+ m["name"] = desc->name();
+ m["full_name"] = desc->full_name();
+ m["index"] = SimpleItoa(desc->index());
+ printer_->Print(
+ m,
+ "_descriptor.OneofDescriptor(\n"
+ " name='$name$', full_name='$full_name$',\n"
+ " index=$index$, containing_type=None, fields=[]),\n");
+ }
+ printer_->Outdent();
+ printer_->Print("],\n");
// Serialization of proto
DescriptorProto edp;
PrintSerializedPbInterval(message_descriptor, edp);
@@ -606,7 +680,12 @@ void Generator::PrintNestedDescriptors(
// Prints all messages in |file|.
void Generator::PrintMessages() const {
for (int i = 0; i < file_->message_type_count(); ++i) {
- PrintMessage(*file_->message_type(i));
+ vector<string> to_register;
+ PrintMessage(*file_->message_type(i), "", &to_register);
+ for (int j = 0; j < to_register.size(); ++j) {
+ printer_->Print("_sym_db.RegisterMessage($name$)\n", "name",
+ to_register[j]);
+ }
printer_->Print("\n");
}
}
@@ -618,33 +697,40 @@ void Generator::PrintMessages() const {
// reflection.py will use to construct the meat of the class itself.
//
// Mutually recursive with PrintNestedMessages().
-void Generator::PrintMessage(
- const Descriptor& message_descriptor) const {
- printer_->Print("class $name$(message.Message):\n", "name",
- message_descriptor.name());
+// Collect nested message names to_register for the symbol_database.
+void Generator::PrintMessage(const Descriptor& message_descriptor,
+ const string& prefix,
+ vector<string>* to_register) const {
+ string qualified_name(prefix + message_descriptor.name());
+ to_register->push_back(qualified_name);
+ printer_->Print(
+ "$name$ = _reflection.GeneratedProtocolMessageType('$name$', "
+ "(_message.Message,), dict(\n",
+ "name", message_descriptor.name());
printer_->Indent();
- printer_->Print("__metaclass__ = reflection.GeneratedProtocolMessageType\n");
- PrintNestedMessages(message_descriptor);
+
+ PrintNestedMessages(message_descriptor, qualified_name + ".", to_register);
map<string, string> m;
m["descriptor_key"] = kDescriptorKey;
m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
- printer_->Print(m, "$descriptor_key$ = $descriptor_name$\n");
-
- printer_->Print(
- "\n"
- "# @@protoc_insertion_point(class_scope:$full_name$)\n",
- "full_name", message_descriptor.full_name());
-
+ printer_->Print(m, "$descriptor_key$ = $descriptor_name$,\n");
+ printer_->Print("__module__ = '$module_name$'\n",
+ "module_name", ModuleName(file_->name()));
+ printer_->Print("# @@protoc_insertion_point(class_scope:$full_name$)\n",
+ "full_name", message_descriptor.full_name());
+ printer_->Print("))\n");
printer_->Outdent();
}
// Prints all nested messages within |containing_descriptor|.
// Mutually recursive with PrintMessage().
-void Generator::PrintNestedMessages(
- const Descriptor& containing_descriptor) const {
+void Generator::PrintNestedMessages(const Descriptor& containing_descriptor,
+ const string& prefix,
+ vector<string>* to_register) const {
for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
printer_->Print("\n");
- PrintMessage(*containing_descriptor.nested_type(i));
+ PrintMessage(*containing_descriptor.nested_type(i), prefix, to_register);
+ printer_->Print(",\n");
}
}
@@ -672,6 +758,57 @@ void Generator::FixForeignFieldsInDescriptor(
const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i);
FixContainingTypeInDescriptor(enum_descriptor, &descriptor);
}
+ for (int i = 0; i < descriptor.oneof_decl_count(); ++i) {
+ map<string, string> m;
+ const OneofDescriptor* oneof = descriptor.oneof_decl(i);
+ m["descriptor_name"] = ModuleLevelDescriptorName(descriptor);
+ m["oneof_name"] = oneof->name();
+ for (int j = 0; j < oneof->field_count(); ++j) {
+ m["field_name"] = oneof->field(j)->name();
+ printer_->Print(
+ m,
+ "$descriptor_name$.oneofs_by_name['$oneof_name$'].fields.append(\n"
+ " $descriptor_name$.fields_by_name['$field_name$'])\n");
+ printer_->Print(
+ m,
+ "$descriptor_name$.fields_by_name['$field_name$'].containing_oneof = "
+ "$descriptor_name$.oneofs_by_name['$oneof_name$']\n");
+ }
+ }
+}
+
+void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const {
+ map<string, string> m;
+ m["descriptor_name"] = kDescriptorKey;
+ m["message_name"] = descriptor.name();
+ m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
+ const char file_descriptor_template[] =
+ "$descriptor_name$.message_types_by_name['$message_name$'] = "
+ "$message_descriptor_name$\n";
+ printer_->Print(m, file_descriptor_template);
+}
+
+void Generator::AddEnumToFileDescriptor(
+ const EnumDescriptor& descriptor) const {
+ map<string, string> m;
+ m["descriptor_name"] = kDescriptorKey;
+ m["enum_name"] = descriptor.name();
+ m["enum_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
+ const char file_descriptor_template[] =
+ "$descriptor_name$.enum_types_by_name['$enum_name$'] = "
+ "$enum_descriptor_name$\n";
+ printer_->Print(m, file_descriptor_template);
+}
+
+void Generator::AddExtensionToFileDescriptor(
+ const FieldDescriptor& descriptor) const {
+ map<string, string> m;
+ m["descriptor_name"] = kDescriptorKey;
+ m["field_name"] = descriptor.name();
+ const char file_descriptor_template[] =
+ "$descriptor_name$.extensions_by_name['$field_name$'] = "
+ "$field_name$\n";
+ printer_->Print(m, file_descriptor_template);
}
// Sets any necessary message_type and enum_type attributes
@@ -738,7 +875,7 @@ void Generator::FixContainingTypeInDescriptor(
const string parent_name = ModuleLevelDescriptorName(
*containing_descriptor);
printer_->Print(
- "$nested_name$.containing_type = $parent_name$;\n",
+ "$nested_name$.containing_type = $parent_name$\n",
"nested_name", nested_name,
"parent_name", parent_name);
}
@@ -752,6 +889,15 @@ void Generator::FixForeignFieldsInDescriptors() const {
for (int i = 0; i < file_->message_type_count(); ++i) {
FixForeignFieldsInDescriptor(*file_->message_type(i), NULL);
}
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ AddMessageToFileDescriptor(*file_->message_type(i));
+ }
+ for (int i = 0; i < file_->enum_type_count(); ++i) {
+ AddEnumToFileDescriptor(*file_->enum_type(i));
+ }
+ for (int i = 0; i < file_->extension_count(); ++i) {
+ AddExtensionToFileDescriptor(*file_->extension(i));
+ }
printer_->Print("\n");
}
@@ -767,6 +913,7 @@ void Generator::FixForeignFieldsInExtensions() const {
for (int i = 0; i < file_->message_type_count(); ++i) {
FixForeignFieldsInNestedExtensions(*file_->message_type(i));
}
+ printer_->Print("\n");
}
void Generator::FixForeignFieldsInExtension(
@@ -817,20 +964,24 @@ void Generator::PrintEnumValueDescriptor(
m["options"] = OptionsValue("EnumValueOptions", options_string);
printer_->Print(
m,
- "descriptor.EnumValueDescriptor(\n"
+ "_descriptor.EnumValueDescriptor(\n"
" name='$name$', index=$index$, number=$number$,\n"
" options=$options$,\n"
" type=None)");
}
+// Returns a Python expression that calls descriptor._ParseOptions using
+// the given descriptor class name and serialized options protobuf string.
string Generator::OptionsValue(
const string& class_name, const string& serialized_options) const {
if (serialized_options.length() == 0 || GeneratingDescriptorProto()) {
return "None";
} else {
string full_class_name = "descriptor_pb2." + class_name;
- return "descriptor._ParseOptions(" + full_class_name + "(), '"
- + CEscape(serialized_options)+ "')";
+//##!PY25 return "_descriptor._ParseOptions(" + full_class_name + "(), b'"
+//##!PY25 + CEscape(serialized_options)+ "')";
+ return "_descriptor._ParseOptions(" + full_class_name + "(), _b('" //##PY25
+ + CEscape(serialized_options)+ "'))"; //##PY25
}
}
@@ -855,7 +1006,7 @@ void Generator::PrintFieldDescriptor(
// these fields in correctly after all referenced descriptors have been
// defined and/or imported (see FixForeignFieldsInDescriptors()).
const char field_descriptor_decl[] =
- "descriptor.FieldDescriptor(\n"
+ "_descriptor.FieldDescriptor(\n"
" name='$name$', full_name='$full_name$', index=$index$,\n"
" number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n"
" has_default_value=$has_default_value$, default_value=$default_value$,\n"
@@ -986,6 +1137,125 @@ void Generator::PrintSerializedPbInterval(
"serialized_end", SimpleItoa(offset + sp.size()));
}
+namespace {
+void PrintDescriptorOptionsFixingCode(const string& descriptor,
+ const string& options,
+ io::Printer* printer) {
+ // TODO(xiaofeng): I have added a method _SetOptions() to DescriptorBase
+ // in proto2 python runtime but it couldn't be used here because appengine
+ // uses a snapshot version of the library in which the new method is not
+ // yet present. After appengine has synced their runtime library, the code
+ // below should be cleaned up to use _SetOptions().
+ printer->Print(
+ "$descriptor$.has_options = True\n"
+ "$descriptor$._options = $options$\n",
+ "descriptor", descriptor, "options", options);
+}
+} // namespace
+
+// Prints expressions that set the options field of all descriptors.
+void Generator::FixAllDescriptorOptions() const {
+ // Prints an expression that sets the file descriptor's options.
+ string file_options = OptionsValue(
+ "FileOptions", file_->options().SerializeAsString());
+ if (file_options != "None") {
+ PrintDescriptorOptionsFixingCode(kDescriptorKey, file_options, printer_);
+ }
+ // Prints expressions that set the options for all top level enums.
+ for (int i = 0; i < file_->enum_type_count(); ++i) {
+ const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
+ FixOptionsForEnum(enum_descriptor);
+ }
+ // Prints expressions that set the options for all top level extensions.
+ for (int i = 0; i < file_->extension_count(); ++i) {
+ const FieldDescriptor& field = *file_->extension(i);
+ FixOptionsForField(field);
+ }
+ // Prints expressions that set the options for all messages, nested enums,
+ // nested extensions and message fields.
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ FixOptionsForMessage(*file_->message_type(i));
+ }
+}
+
+// Prints expressions that set the options for an enum descriptor and its
+// value descriptors.
+void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const {
+ string descriptor_name = ModuleLevelDescriptorName(enum_descriptor);
+ string enum_options = OptionsValue(
+ "EnumOptions", enum_descriptor.options().SerializeAsString());
+ if (enum_options != "None") {
+ PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_);
+ }
+ for (int i = 0; i < enum_descriptor.value_count(); ++i) {
+ const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(i);
+ string value_options = OptionsValue(
+ "EnumValueOptions", value_descriptor.options().SerializeAsString());
+ if (value_options != "None") {
+ PrintDescriptorOptionsFixingCode(
+ StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(),
+ value_descriptor.name().c_str()),
+ value_options, printer_);
+ }
+ }
+}
+
+// Prints expressions that set the options for field descriptors (including
+// extensions).
+void Generator::FixOptionsForField(
+ const FieldDescriptor& field) const {
+ string field_options = OptionsValue(
+ "FieldOptions", field.options().SerializeAsString());
+ if (field_options != "None") {
+ string field_name;
+ if (field.is_extension()) {
+ if (field.extension_scope() == NULL) {
+ // Top level extensions.
+ field_name = field.name();
+ } else {
+ field_name = FieldReferencingExpression(
+ field.extension_scope(), field, "extensions_by_name");
+ }
+ } else {
+ field_name = FieldReferencingExpression(
+ field.containing_type(), field, "fields_by_name");
+ }
+ PrintDescriptorOptionsFixingCode(field_name, field_options, printer_);
+ }
+}
+
+// Prints expressions that set the options for a message and all its inner
+// types (nested messages, nested enums, extensions, fields).
+void Generator::FixOptionsForMessage(const Descriptor& descriptor) const {
+ // Nested messages.
+ for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+ FixOptionsForMessage(*descriptor.nested_type(i));
+ }
+ // Enums.
+ for (int i = 0; i < descriptor.enum_type_count(); ++i) {
+ FixOptionsForEnum(*descriptor.enum_type(i));
+ }
+ // Fields.
+ for (int i = 0; i < descriptor.field_count(); ++i) {
+ const FieldDescriptor& field = *descriptor.field(i);
+ FixOptionsForField(field);
+ }
+ // Extensions.
+ for (int i = 0; i < descriptor.extension_count(); ++i) {
+ const FieldDescriptor& field = *descriptor.extension(i);
+ FixOptionsForField(field);
+ }
+ // Message option for this message.
+ string message_options = OptionsValue(
+ "MessageOptions", descriptor.options().SerializeAsString());
+ if (message_options != "None") {
+ string descriptor_name = ModuleLevelDescriptorName(descriptor);
+ PrintDescriptorOptionsFixingCode(descriptor_name,
+ message_options,
+ printer_);
+ }
+}
+
} // namespace python
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h
index 43c2087..f86e9ea 100644
--- a/src/google/protobuf/compiler/python/python_generator.h
+++ b/src/google/protobuf/compiler/python/python_generator.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -66,7 +66,7 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator {
// CodeGenerator methods.
virtual bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
string* error) const;
private:
@@ -94,8 +94,11 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator {
void PrintNestedDescriptors(const Descriptor& containing_descriptor) const;
void PrintMessages() const;
- void PrintMessage(const Descriptor& message_descriptor) const;
- void PrintNestedMessages(const Descriptor& containing_descriptor) const;
+ void PrintMessage(const Descriptor& message_descriptor, const string& prefix,
+ vector<string>* to_register) const;
+ void PrintNestedMessages(const Descriptor& containing_descriptor,
+ const string& prefix,
+ vector<string>* to_register) const;
void FixForeignFieldsInDescriptors() const;
void FixForeignFieldsInDescriptor(
@@ -104,6 +107,9 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator {
void FixForeignFieldsInField(const Descriptor* containing_type,
const FieldDescriptor& field,
const string& python_dict_name) const;
+ void AddMessageToFileDescriptor(const Descriptor& descriptor) const;
+ void AddEnumToFileDescriptor(const EnumDescriptor& descriptor) const;
+ void AddExtensionToFileDescriptor(const FieldDescriptor& descriptor) const;
string FieldReferencingExpression(const Descriptor* containing_type,
const FieldDescriptor& field,
const string& python_dict_name) const;
@@ -137,6 +143,11 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator {
void PrintSerializedPbInterval(
const DescriptorT& descriptor, DescriptorProtoT& proto) const;
+ void FixAllDescriptorOptions() const;
+ void FixOptionsForField(const FieldDescriptor& field) const;
+ void FixOptionsForEnum(const EnumDescriptor& descriptor) const;
+ void FixOptionsForMessage(const Descriptor& descriptor) const;
+
// Very coarse-grained lock to ensure that Generate() is reentrant.
// Guards file_, printer_ and file_descriptor_serialized_.
mutable Mutex mutex_;
diff --git a/src/google/protobuf/compiler/python/python_plugin_unittest.cc b/src/google/protobuf/compiler/python/python_plugin_unittest.cc
index fde8876..09dbc65 100644
--- a/src/google/protobuf/compiler/python/python_plugin_unittest.cc
+++ b/src/google/protobuf/compiler/python/python_plugin_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -34,6 +34,8 @@
// It seemed like parameterizing it would add more complexity than it is
// worth.
+#include <memory>
+
#include <google/protobuf/compiler/python/python_generator.h>
#include <google/protobuf/compiler/command_line_interface.h>
#include <google/protobuf/io/zero_copy_stream.h>
@@ -56,19 +58,19 @@ class TestGenerator : public CodeGenerator {
virtual bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
- TryInsert("test_pb2.py", "imports", output_directory);
- TryInsert("test_pb2.py", "module_scope", output_directory);
- TryInsert("test_pb2.py", "class_scope:foo.Bar", output_directory);
- TryInsert("test_pb2.py", "class_scope:foo.Bar.Baz", output_directory);
+ TryInsert("test_pb2.py", "imports", context);
+ TryInsert("test_pb2.py", "module_scope", context);
+ TryInsert("test_pb2.py", "class_scope:foo.Bar", context);
+ TryInsert("test_pb2.py", "class_scope:foo.Bar.Baz", context);
return true;
}
void TryInsert(const string& filename, const string& insertion_point,
- OutputDirectory* output_directory) const {
+ GeneratorContext* context) const {
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->OpenForInsert(filename, insertion_point));
+ context->OpenForInsert(filename, insertion_point));
io::Printer printer(output.get(), '$');
printer.Print("// inserted $name$\n", "name", insertion_point);
}
@@ -78,13 +80,13 @@ class TestGenerator : public CodeGenerator {
// not verify that they are correctly-placed; that would require actually
// compiling the output which is a bit more than I care to do for this test.
TEST(PythonPluginTest, PluginTest) {
- File::WriteStringToFileOrDie(
- "syntax = \"proto2\";\n"
- "package foo;\n"
- "message Bar {\n"
- " message Baz {}\n"
- "}\n",
- TestTempDir() + "/test.proto");
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto",
+ "syntax = \"proto2\";\n"
+ "package foo;\n"
+ "message Bar {\n"
+ " message Baz {}\n"
+ "}\n",
+ true));
google::protobuf::compiler::CommandLineInterface cli;
cli.SetInputsAreProtoPathRelative(true);
diff --git a/src/google/protobuf/compiler/subprocess.cc b/src/google/protobuf/compiler/subprocess.cc
index de46a3e..61ae438 100644
--- a/src/google/protobuf/compiler/subprocess.cc
+++ b/src/google/protobuf/compiler/subprocess.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,13 +32,16 @@
#include <google/protobuf/compiler/subprocess.h>
+#include <algorithm>
+#include <iostream>
+
#ifndef _WIN32
#include <errno.h>
+#include <sys/select.h>
#include <sys/wait.h>
#include <signal.h>
#endif
-#include <algorithm>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message.h>
#include <google/protobuf/stubs/substitute.h>
@@ -96,7 +99,7 @@ void Subprocess::Start(const string& program, SearchMode search_mode) {
}
// Setup STARTUPINFO to redirect handles.
- STARTUPINFO startup_info;
+ STARTUPINFOA startup_info;
ZeroMemory(&startup_info, sizeof(startup_info));
startup_info.cb = sizeof(startup_info);
startup_info.dwFlags = STARTF_USESTDHANDLES;
@@ -115,16 +118,16 @@ void Subprocess::Start(const string& program, SearchMode search_mode) {
// Create the process.
PROCESS_INFORMATION process_info;
- if (CreateProcess((search_mode == SEARCH_PATH) ? NULL : program.c_str(),
- (search_mode == SEARCH_PATH) ? name_copy : NULL,
- NULL, // process security attributes
- NULL, // thread security attributes
- TRUE, // inherit handles?
- 0, // obscure creation flags
- NULL, // environment (inherit from parent)
- NULL, // current directory (inherit from parent)
- &startup_info,
- &process_info)) {
+ if (CreateProcessA((search_mode == SEARCH_PATH) ? NULL : program.c_str(),
+ (search_mode == SEARCH_PATH) ? name_copy : NULL,
+ NULL, // process security attributes
+ NULL, // thread security attributes
+ TRUE, // inherit handles?
+ 0, // obscure creation flags
+ NULL, // environment (inherit from parent)
+ NULL, // current directory (inherit from parent)
+ &startup_info,
+ &process_info)) {
child_handle_ = process_info.hProcess;
CloseHandleOrDie(process_info.hThread);
child_stdin_ = stdin_pipe_write;
@@ -292,8 +295,8 @@ void Subprocess::Start(const string& program, SearchMode search_mode) {
int stdin_pipe[2];
int stdout_pipe[2];
- pipe(stdin_pipe);
- pipe(stdout_pipe);
+ GOOGLE_CHECK(pipe(stdin_pipe) != -1);
+ GOOGLE_CHECK(pipe(stdout_pipe) != -1);
char* argv[2] = { strdup(program.c_str()), NULL };
@@ -321,9 +324,11 @@ void Subprocess::Start(const string& program, SearchMode search_mode) {
// Write directly to STDERR_FILENO to avoid stdio code paths that may do
// stuff that is unsafe here.
- write(STDERR_FILENO, argv[0], strlen(argv[0]));
+ int ignored;
+ ignored = write(STDERR_FILENO, argv[0], strlen(argv[0]));
const char* message = ": program not found or is not executable\n";
- write(STDERR_FILENO, message, strlen(message));
+ ignored = write(STDERR_FILENO, message, strlen(message));
+ (void) ignored;
// Must use _exit() rather than exit() to avoid flushing output buffers
// that will also be flushed by the parent.
@@ -444,7 +449,7 @@ bool Subprocess::Communicate(const Message& input, Message* output,
}
if (!output->ParseFromString(output_data)) {
- *error = "Plugin output is unparseable.";
+ *error = "Plugin output is unparseable: " + CEscape(output_data);
return false;
}
diff --git a/src/google/protobuf/compiler/subprocess.h b/src/google/protobuf/compiler/subprocess.h
index 7a6fa70..2513863 100644
--- a/src/google/protobuf/compiler/subprocess.h
+++ b/src/google/protobuf/compiler/subprocess.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -40,9 +40,10 @@
#include <sys/types.h>
#include <unistd.h>
#endif // !_WIN32
+#include <google/protobuf/stubs/common.h>
#include <string>
-#include <google/protobuf/stubs/common.h>
+
namespace google {
namespace protobuf {
@@ -52,7 +53,7 @@ class Message;
namespace compiler {
// Utility class for launching sub-processes.
-class Subprocess {
+class LIBPROTOC_EXPORT Subprocess {
public:
Subprocess();
~Subprocess();
diff --git a/src/google/protobuf/compiler/test_plugin.cc b/src/google/protobuf/compiler/test_plugin.cc
index 5cbbf3d..4830fd7 100644
--- a/src/google/protobuf/compiler/test_plugin.cc
+++ b/src/google/protobuf/compiler/test_plugin.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/compiler/zip_output_unittest.sh b/src/google/protobuf/compiler/zip_output_unittest.sh
index 259d5d2..6fc7136 100755
--- a/src/google/protobuf/compiler/zip_output_unittest.sh
+++ b/src/google/protobuf/compiler/zip_output_unittest.sh
@@ -2,7 +2,7 @@
#
# Protocol Buffers - Google's data interchange format
# Copyright 2009 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -39,45 +39,51 @@ fail() {
exit 1
}
+TEST_TMPDIR=.
+PROTOC=./protoc
+
echo '
+ syntax = "proto2";
option java_multiple_files = true;
option java_package = "test.jar";
option java_outer_classname = "Outer";
message Foo {}
message Bar {}
-' > testzip.proto
+' > $TEST_TMPDIR/testzip.proto
-./protoc --cpp_out=testzip.zip --python_out=testzip.zip --java_out=testzip.jar \
- testzip.proto || fail 'protoc failed.'
+$PROTOC \
+ --cpp_out=$TEST_TMPDIR/testzip.zip --python_out=$TEST_TMPDIR/testzip.zip \
+ --java_out=$TEST_TMPDIR/testzip.jar -I$TEST_TMPDIR testzip.proto \
+ || fail 'protoc failed.'
echo "Testing output to zip..."
if unzip -h > /dev/null; then
- unzip -t testzip.zip > testzip.list || fail 'unzip failed.'
+ unzip -t $TEST_TMPDIR/testzip.zip > $TEST_TMPDIR/testzip.list || fail 'unzip failed.'
- grep 'testing: testzip\.pb\.cc *OK$' testzip.list > /dev/null \
+ grep 'testing: testzip\.pb\.cc *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
|| fail 'testzip.pb.cc not found in output zip.'
- grep 'testing: testzip\.pb\.h *OK$' testzip.list > /dev/null \
+ grep 'testing: testzip\.pb\.h *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
|| fail 'testzip.pb.h not found in output zip.'
- grep 'testing: testzip_pb2\.py *OK$' testzip.list > /dev/null \
+ grep 'testing: testzip_pb2\.py *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
|| fail 'testzip_pb2.py not found in output zip.'
- grep -i 'manifest' testzip.list > /dev/null \
+ grep -i 'manifest' $TEST_TMPDIR/testzip.list > /dev/null \
&& fail 'Zip file contained manifest.'
else
echo "Warning: 'unzip' command not available. Skipping test."
fi
echo "Testing output to jar..."
-if jar c testzip.proto > /dev/null; then
- jar tf testzip.jar > testzip.list || fail 'jar failed.'
+if jar c $TEST_TMPDIR/testzip.proto > /dev/null; then
+ jar tf $TEST_TMPDIR/testzip.jar > $TEST_TMPDIR/testzip.list || fail 'jar failed.'
- grep '^test/jar/Foo\.java$' testzip.list > /dev/null \
+ grep '^test/jar/Foo\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
|| fail 'Foo.java not found in output jar.'
- grep '^test/jar/Bar\.java$' testzip.list > /dev/null \
+ grep '^test/jar/Bar\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
|| fail 'Bar.java not found in output jar.'
- grep '^test/jar/Outer\.java$' testzip.list > /dev/null \
+ grep '^test/jar/Outer\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
|| fail 'Outer.java not found in output jar.'
- grep '^META-INF/MANIFEST\.MF$' testzip.list > /dev/null \
- || fail 'Manifest not ofund in output jar.'
+ grep '^META-INF/MANIFEST\.MF$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'Manifest not found in output jar.'
else
echo "Warning: 'jar' command not available. Skipping test."
fi
diff --git a/src/google/protobuf/compiler/zip_writer.cc b/src/google/protobuf/compiler/zip_writer.cc
index 53c1877..458cced 100644
--- a/src/google/protobuf/compiler/zip_writer.cc
+++ b/src/google/protobuf/compiler/zip_writer.cc
@@ -1,6 +1,36 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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.
+
+// 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
@@ -183,6 +213,6 @@ bool ZipWriter::WriteDirectory() {
return output.HadError();
}
-} // namespace google
-} // namespace protobuf
} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/zip_writer.h b/src/google/protobuf/compiler/zip_writer.h
index 4289553..602e508 100644
--- a/src/google/protobuf/compiler/zip_writer.h
+++ b/src/google/protobuf/compiler/zip_writer.h
@@ -1,6 +1,36 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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.
+
+// 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
@@ -58,6 +88,6 @@ class ZipWriter {
vector<FileInfo> files_;
};
-} // namespace google
-} // namespace protobuf
} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index 81c4ac0..21dda59 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,6 +35,7 @@
#include <google/protobuf/stubs/hash.h>
#include <map>
#include <set>
+#include <string>
#include <vector>
#include <algorithm>
#include <limits>
@@ -42,17 +43,21 @@
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor_database.h>
#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/wire_format.h>
+#include <google/protobuf/io/strtod.h>
#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/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
-#include <google/protobuf/stubs/map-util.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/stl_util.h>
#undef PACKAGE // autoheader #defines this. :(
@@ -106,6 +111,21 @@ const char * const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = {
"sint64", // TYPE_SINT64
};
+const char * const FieldDescriptor::kCppTypeToName[MAX_CPPTYPE + 1] = {
+ "ERROR", // 0 is reserved for errors
+
+ "int32", // CPPTYPE_INT32
+ "int64", // CPPTYPE_INT64
+ "uint32", // CPPTYPE_UINT32
+ "uint64", // CPPTYPE_UINT64
+ "double", // CPPTYPE_DOUBLE
+ "float", // CPPTYPE_FLOAT
+ "bool", // CPPTYPE_BOOL
+ "enum", // CPPTYPE_ENUM
+ "string", // CPPTYPE_STRING
+ "message", // CPPTYPE_MESSAGE
+};
+
const char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = {
"ERROR", // 0 is reserved for errors
@@ -114,6 +134,8 @@ const char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = {
"repeated", // LABEL_REPEATED
};
+static const char * const kNonLinkedWeakMessageReplacementName = "google.protobuf.Empty";
+
#ifndef _MSC_VER // MSVC doesn't need these and won't even accept them.
const int FieldDescriptor::kMaxNumber;
const int FieldDescriptor::kFirstReservedNumber;
@@ -122,8 +144,6 @@ const int FieldDescriptor::kLastReservedNumber;
namespace {
-const string kEmptyString;
-
string ToCamelCase(const string& input) {
bool capitalize_next = false;
string result;
@@ -184,9 +204,11 @@ struct PointerIntegerPairHash {
return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second;
}
+#ifdef _MSC_VER
// Used only by MSVC and platforms where hash_map is not available.
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
+#endif
inline bool operator()(const PairType& a, const PairType& b) const {
return a.first < b.first ||
(a.first == b.first && a.second < b.second);
@@ -205,9 +227,11 @@ struct PointerStringPairHash {
cstring_hash(p.second);
}
+#ifdef _MSC_VER
// Used only by MSVC and platforms where hash_map is not available.
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
+#endif
inline bool operator()(const PointerStringPair& a,
const PointerStringPair& b) const {
if (a.first < b.first) return true;
@@ -219,12 +243,14 @@ struct PointerStringPairHash {
struct Symbol {
enum Type {
- NULL_SYMBOL, MESSAGE, FIELD, ENUM, ENUM_VALUE, SERVICE, METHOD, PACKAGE
+ NULL_SYMBOL, MESSAGE, FIELD, ONEOF, ENUM, ENUM_VALUE, SERVICE, METHOD,
+ PACKAGE
};
Type type;
union {
const Descriptor* descriptor;
const FieldDescriptor* field_descriptor;
+ const OneofDescriptor* oneof_descriptor;
const EnumDescriptor* enum_descriptor;
const EnumValueDescriptor* enum_value_descriptor;
const ServiceDescriptor* service_descriptor;
@@ -250,6 +276,7 @@ struct Symbol {
CONSTRUCTOR(Descriptor , MESSAGE , descriptor )
CONSTRUCTOR(FieldDescriptor , FIELD , field_descriptor )
+ CONSTRUCTOR(OneofDescriptor , ONEOF , oneof_descriptor )
CONSTRUCTOR(EnumDescriptor , ENUM , enum_descriptor )
CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor )
CONSTRUCTOR(ServiceDescriptor , SERVICE , service_descriptor )
@@ -262,6 +289,7 @@ struct Symbol {
case NULL_SYMBOL: return NULL;
case MESSAGE : return descriptor ->file();
case FIELD : return field_descriptor ->file();
+ case ONEOF : return oneof_descriptor ->containing_type()->file();
case ENUM : return enum_descriptor ->file();
case ENUM_VALUE : return enum_value_descriptor->type()->file();
case SERVICE : return service_descriptor ->file();
@@ -298,7 +326,7 @@ typedef hash_map<EnumIntPair, const EnumValueDescriptor*,
// for that.
typedef map<DescriptorIntPair, const FieldDescriptor*>
ExtensionsGroupedByDescriptorMap;
-
+typedef hash_map<string, const SourceCodeInfo_Location*> LocationsByPathMap;
} // anonymous namespace
// ===================================================================
@@ -309,17 +337,42 @@ class DescriptorPool::Tables {
Tables();
~Tables();
- // Checkpoint the state of the tables. Future calls to Rollback() will
- // return the Tables to this state. This is used when building files, since
- // some kinds of validation errors cannot be detected until the file's
- // descriptors have already been added to the tables. BuildFile() calls
- // Checkpoint() before it starts building and Rollback() if it encounters
- // an error.
- void Checkpoint();
+ // Record the current state of the tables to the stack of checkpoints.
+ // Each call to AddCheckpoint() must be paired with exactly one call to either
+ // ClearLastCheckpoint() or RollbackToLastCheckpoint().
+ //
+ // This is used when building files, since some kinds of validation errors
+ // cannot be detected until the file's descriptors have already been added to
+ // the tables.
+ //
+ // This supports recursive checkpoints, since building a file may trigger
+ // recursive building of other files. Note that recursive checkpoints are not
+ // normally necessary; explicit dependencies are built prior to checkpointing.
+ // So although we recursively build transitive imports, there is at most one
+ // checkpoint in the stack during dependency building.
+ //
+ // Recursive checkpoints only arise during cross-linking of the descriptors.
+ // Symbol references must be resolved, via DescriptorBuilder::FindSymbol and
+ // friends. If the pending file references an unknown symbol
+ // (e.g., it is not defined in the pending file's explicit dependencies), and
+ // the pool is using a fallback database, and that database contains a file
+ // defining that symbol, and that file has not yet been built by the pool,
+ // the pool builds the file during cross-linking, leading to another
+ // checkpoint.
+ void AddCheckpoint();
+
+ // Mark the last checkpoint as having cleared successfully, removing it from
+ // the stack. If the stack is empty, all pending symbols will be committed.
+ //
+ // Note that this does not guarantee that the symbols added since the last
+ // checkpoint won't be rolled back: if a checkpoint gets rolled back,
+ // everything past that point gets rolled back, including symbols added after
+ // checkpoints that were pushed onto the stack after it and marked as cleared.
+ void ClearLastCheckpoint();
- // Roll back the Tables to the state of the last Checkpoint(), removing
- // everything that was added after that point.
- void Rollback();
+ // Roll back the Tables to the state of the checkpoint at the top of the
+ // stack, removing everything that was added after that point.
+ void RollbackToLastCheckpoint();
// The stack of files which are currently being built. Used to detect
// cyclic dependencies when loading files from a DescriptorDatabase. Not
@@ -327,10 +380,18 @@ class DescriptorPool::Tables {
vector<string> pending_files_;
// A set of files which we have tried to load from the fallback database
- // and encountered errors. We will not attempt to load them again.
+ // and encountered errors. We will not attempt to load them again during
+ // execution of the current public API call, but for compatibility with
+ // legacy clients, this is cleared at the beginning of each public API call.
// Not used when fallback_database_ == NULL.
hash_set<string> known_bad_files_;
+ // A set of symbols which we have tried to load from the fallback database
+ // and encountered errors. We will not attempt to load them again during
+ // execution of the current public API call, but for compatibility with
+ // legacy clients, this is cleared at the beginning of each public API call.
+ hash_set<string> known_bad_symbols_;
+
// The set of descriptors for which we've already loaded the full
// set of extensions numbers from fallback_database_.
hash_set<const Descriptor*> extensions_loaded_from_db_;
@@ -347,7 +408,7 @@ class DescriptorPool::Tables {
// declaring Symbol in descriptor.h, which would drag all kinds of other
// stuff into the header. Yay C++.
Symbol FindByNameHelper(
- const DescriptorPool* pool, const string& name) const;
+ const DescriptorPool* pool, const string& name);
// These return NULL if not found.
inline const FileDescriptor* FindFile(const string& key) const;
@@ -403,10 +464,28 @@ class DescriptorPool::Tables {
FilesByNameMap files_by_name_;
ExtensionsGroupedByDescriptorMap extensions_;
- int strings_before_checkpoint_;
- int messages_before_checkpoint_;
- int file_tables_before_checkpoint_;
- int allocations_before_checkpoint_;
+ struct CheckPoint {
+ explicit CheckPoint(const Tables* tables)
+ : strings_before_checkpoint(tables->strings_.size()),
+ messages_before_checkpoint(tables->messages_.size()),
+ file_tables_before_checkpoint(tables->file_tables_.size()),
+ allocations_before_checkpoint(tables->allocations_.size()),
+ pending_symbols_before_checkpoint(
+ tables->symbols_after_checkpoint_.size()),
+ pending_files_before_checkpoint(
+ tables->files_after_checkpoint_.size()),
+ pending_extensions_before_checkpoint(
+ tables->extensions_after_checkpoint_.size()) {
+ }
+ int strings_before_checkpoint;
+ int messages_before_checkpoint;
+ int file_tables_before_checkpoint;
+ int allocations_before_checkpoint;
+ int pending_symbols_before_checkpoint;
+ int pending_files_before_checkpoint;
+ int pending_extensions_before_checkpoint;
+ };
+ vector<CheckPoint> checkpoints_;
vector<const char* > symbols_after_checkpoint_;
vector<const char* > files_after_checkpoint_;
vector<DescriptorIntPair> extensions_after_checkpoint_;
@@ -470,20 +549,41 @@ class FileDescriptorTables {
// fails because we allow duplicates; the first field by the name wins.
void AddFieldByStylizedNames(const FieldDescriptor* field);
+ // Populates p->first->locations_by_path_ from p->second.
+ // Unusual signature dictated by GoogleOnceDynamic.
+ static void BuildLocationsByPath(
+ pair<const FileDescriptorTables*, const SourceCodeInfo*>* p);
+
+ // Returns the location denoted by the specified path through info,
+ // or NULL if not found.
+ // The value of info must be that of the corresponding FileDescriptor.
+ // (Conceptually a pure function, but stateful as an optimisation.)
+ const SourceCodeInfo_Location* GetSourceLocation(
+ const vector<int>& path, const SourceCodeInfo* info) const;
+
private:
SymbolsByParentMap symbols_by_parent_;
FieldsByNameMap fields_by_lowercase_name_;
FieldsByNameMap fields_by_camelcase_name_;
FieldsByNumberMap fields_by_number_; // Not including extensions.
EnumValuesByNumberMap enum_values_by_number_;
+
+ // Populated on first request to save space, hence constness games.
+ mutable GoogleOnceDynamic locations_by_path_once_;
+ mutable LocationsByPathMap locations_by_path_;
};
DescriptorPool::Tables::Tables()
- : strings_before_checkpoint_(0),
- messages_before_checkpoint_(0),
- allocations_before_checkpoint_(0) {}
+ // Start some hash_map and hash_set objects with a small # of buckets
+ : known_bad_files_(3),
+ known_bad_symbols_(3),
+ extensions_loaded_from_db_(3),
+ symbols_by_name_(3),
+ files_by_name_(3) {}
+
DescriptorPool::Tables::~Tables() {
+ GOOGLE_DCHECK(checkpoints_.empty());
// Note that the deletion order is important, since the destructors of some
// messages may refer to objects in allocations_.
STLDeleteElements(&messages_);
@@ -494,51 +594,80 @@ DescriptorPool::Tables::~Tables() {
STLDeleteElements(&file_tables_);
}
-FileDescriptorTables::FileDescriptorTables() {}
+FileDescriptorTables::FileDescriptorTables()
+ // Initialize all the hash tables to start out with a small # of buckets
+ : symbols_by_parent_(3),
+ fields_by_lowercase_name_(3),
+ fields_by_camelcase_name_(3),
+ fields_by_number_(3),
+ enum_values_by_number_(3) {
+}
+
FileDescriptorTables::~FileDescriptorTables() {}
const FileDescriptorTables FileDescriptorTables::kEmpty;
-void DescriptorPool::Tables::Checkpoint() {
- strings_before_checkpoint_ = strings_.size();
- messages_before_checkpoint_ = messages_.size();
- file_tables_before_checkpoint_ = file_tables_.size();
- allocations_before_checkpoint_ = allocations_.size();
+void DescriptorPool::Tables::AddCheckpoint() {
+ checkpoints_.push_back(CheckPoint(this));
+}
- symbols_after_checkpoint_.clear();
- files_after_checkpoint_.clear();
- extensions_after_checkpoint_.clear();
+void DescriptorPool::Tables::ClearLastCheckpoint() {
+ GOOGLE_DCHECK(!checkpoints_.empty());
+ checkpoints_.pop_back();
+ if (checkpoints_.empty()) {
+ // All checkpoints have been cleared: we can now commit all of the pending
+ // data.
+ symbols_after_checkpoint_.clear();
+ files_after_checkpoint_.clear();
+ extensions_after_checkpoint_.clear();
+ }
}
-void DescriptorPool::Tables::Rollback() {
- for (int i = 0; i < symbols_after_checkpoint_.size(); i++) {
+void DescriptorPool::Tables::RollbackToLastCheckpoint() {
+ GOOGLE_DCHECK(!checkpoints_.empty());
+ const CheckPoint& checkpoint = checkpoints_.back();
+
+ for (int i = checkpoint.pending_symbols_before_checkpoint;
+ i < symbols_after_checkpoint_.size();
+ i++) {
symbols_by_name_.erase(symbols_after_checkpoint_[i]);
}
- for (int i = 0; i < files_after_checkpoint_.size(); i++) {
+ for (int i = checkpoint.pending_files_before_checkpoint;
+ i < files_after_checkpoint_.size();
+ i++) {
files_by_name_.erase(files_after_checkpoint_[i]);
}
- for (int i = 0; i < extensions_after_checkpoint_.size(); i++) {
+ for (int i = checkpoint.pending_extensions_before_checkpoint;
+ i < extensions_after_checkpoint_.size();
+ i++) {
extensions_.erase(extensions_after_checkpoint_[i]);
}
- symbols_after_checkpoint_.clear();
- files_after_checkpoint_.clear();
- extensions_after_checkpoint_.clear();
+ symbols_after_checkpoint_.resize(
+ checkpoint.pending_symbols_before_checkpoint);
+ files_after_checkpoint_.resize(checkpoint.pending_files_before_checkpoint);
+ extensions_after_checkpoint_.resize(
+ checkpoint.pending_extensions_before_checkpoint);
STLDeleteContainerPointers(
- strings_.begin() + strings_before_checkpoint_, strings_.end());
+ strings_.begin() + checkpoint.strings_before_checkpoint, strings_.end());
STLDeleteContainerPointers(
- messages_.begin() + messages_before_checkpoint_, messages_.end());
+ messages_.begin() + checkpoint.messages_before_checkpoint,
+ messages_.end());
STLDeleteContainerPointers(
- file_tables_.begin() + file_tables_before_checkpoint_, file_tables_.end());
- for (int i = allocations_before_checkpoint_; i < allocations_.size(); i++) {
+ file_tables_.begin() + checkpoint.file_tables_before_checkpoint,
+ file_tables_.end());
+ for (int i = checkpoint.allocations_before_checkpoint;
+ i < allocations_.size();
+ i++) {
operator delete(allocations_[i]);
}
- strings_.resize(strings_before_checkpoint_);
- messages_.resize(messages_before_checkpoint_);
- file_tables_.resize(file_tables_before_checkpoint_);
- allocations_.resize(allocations_before_checkpoint_);
+ strings_.resize(checkpoint.strings_before_checkpoint);
+ messages_.resize(checkpoint.messages_before_checkpoint);
+ file_tables_.resize(checkpoint.file_tables_before_checkpoint);
+ allocations_.resize(checkpoint.allocations_before_checkpoint);
+ checkpoints_.pop_back();
}
// -------------------------------------------------------------------
@@ -571,8 +700,10 @@ inline Symbol FileDescriptorTables::FindNestedSymbolOfType(
}
Symbol DescriptorPool::Tables::FindByNameHelper(
- const DescriptorPool* pool, const string& name) const {
+ const DescriptorPool* pool, const string& name) {
MutexLockMaybe lock(pool->mutex_);
+ known_bad_symbols_.clear();
+ known_bad_files_.clear();
Symbol result = FindSymbol(name);
if (result.IsNull() && pool->underlay_ != NULL) {
@@ -719,7 +850,7 @@ string* DescriptorPool::Tables::AllocateString(const string& value) {
}
template<typename Type>
-Type* DescriptorPool::Tables::AllocateMessage(Type* dummy) {
+Type* DescriptorPool::Tables::AllocateMessage(Type* /* dummy */) {
Type* result = new Type;
messages_.push_back(result);
return result;
@@ -743,6 +874,22 @@ void* DescriptorPool::Tables::AllocateBytes(int size) {
return result;
}
+void FileDescriptorTables::BuildLocationsByPath(
+ pair<const FileDescriptorTables*, const SourceCodeInfo*>* p) {
+ for (int i = 0, len = p->second->location_size(); i < len; ++i) {
+ const SourceCodeInfo_Location* loc = &p->second->location().Get(i);
+ p->first->locations_by_path_[Join(loc->path(), ",")] = loc;
+ }
+}
+
+const SourceCodeInfo_Location* FileDescriptorTables::GetSourceLocation(
+ const vector<int>& path, const SourceCodeInfo* info) const {
+ pair<const FileDescriptorTables*, const SourceCodeInfo*> p(
+ make_pair(this, info));
+ locations_by_path_once_.Init(&FileDescriptorTables::BuildLocationsByPath, &p);
+ return FindPtrOrNull(locations_by_path_, Join(path, ","));
+}
+
// ===================================================================
// DescriptorPool
@@ -755,7 +902,8 @@ DescriptorPool::DescriptorPool()
underlay_(NULL),
tables_(new Tables),
enforce_dependencies_(true),
- allow_unknown_(false) {}
+ allow_unknown_(false),
+ enforce_weak_(false) {}
DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database,
ErrorCollector* error_collector)
@@ -765,7 +913,8 @@ DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database,
underlay_(NULL),
tables_(new Tables),
enforce_dependencies_(true),
- allow_unknown_(false) {
+ allow_unknown_(false),
+ enforce_weak_(false) {
}
DescriptorPool::DescriptorPool(const DescriptorPool* underlay)
@@ -775,7 +924,8 @@ DescriptorPool::DescriptorPool(const DescriptorPool* underlay)
underlay_(underlay),
tables_(new Tables),
enforce_dependencies_(true),
- allow_unknown_(false) {}
+ allow_unknown_(false),
+ enforce_weak_(false) {}
DescriptorPool::~DescriptorPool() {
if (mutex_ != NULL) delete mutex_;
@@ -788,6 +938,14 @@ void DescriptorPool::InternalDontEnforceDependencies() {
enforce_dependencies_ = false;
}
+void DescriptorPool::AddUnusedImportTrackFile(const string& file_name) {
+ unused_import_track_files_.insert(file_name);
+}
+
+void DescriptorPool::ClearUnusedImportTrackFiles() {
+ unused_import_track_files_.clear();
+}
+
bool DescriptorPool::InternalIsFileLoaded(const string& filename) const {
MutexLockMaybe lock(mutex_);
return tables_->FindFile(filename) != NULL;
@@ -809,7 +967,7 @@ void DeleteGeneratedPool() {
generated_pool_ = NULL;
}
-void InitGeneratedPool() {
+static void InitGeneratedPool() {
generated_database_ = new EncodedDescriptorDatabase;
generated_pool_ = new DescriptorPool(generated_database_);
@@ -869,14 +1027,16 @@ void DescriptorPool::InternalAddGeneratedFile(
const FileDescriptor* DescriptorPool::FindFileByName(const string& name) const {
MutexLockMaybe lock(mutex_);
+ tables_->known_bad_symbols_.clear();
+ tables_->known_bad_files_.clear();
const FileDescriptor* result = tables_->FindFile(name);
if (result != NULL) return result;
if (underlay_ != NULL) {
- const FileDescriptor* result = underlay_->FindFileByName(name);
+ result = underlay_->FindFileByName(name);
if (result != NULL) return result;
}
if (TryFindFileInFallbackDatabase(name)) {
- const FileDescriptor* result = tables_->FindFile(name);
+ result = tables_->FindFile(name);
if (result != NULL) return result;
}
return NULL;
@@ -885,15 +1045,17 @@ const FileDescriptor* DescriptorPool::FindFileByName(const string& name) const {
const FileDescriptor* DescriptorPool::FindFileContainingSymbol(
const string& symbol_name) const {
MutexLockMaybe lock(mutex_);
+ tables_->known_bad_symbols_.clear();
+ tables_->known_bad_files_.clear();
Symbol result = tables_->FindSymbol(symbol_name);
if (!result.IsNull()) return result.GetFile();
if (underlay_ != NULL) {
- const FileDescriptor* result =
+ const FileDescriptor* file_result =
underlay_->FindFileContainingSymbol(symbol_name);
- if (result != NULL) return result;
+ if (file_result != NULL) return file_result;
}
if (TryFindSymbolInFallbackDatabase(symbol_name)) {
- Symbol result = tables_->FindSymbol(symbol_name);
+ result = tables_->FindSymbol(symbol_name);
if (!result.IsNull()) return result.GetFile();
}
return NULL;
@@ -927,6 +1089,12 @@ const FieldDescriptor* DescriptorPool::FindExtensionByName(
}
}
+const OneofDescriptor* DescriptorPool::FindOneofByName(
+ const string& name) const {
+ Symbol result = tables_->FindByNameHelper(this, name);
+ return (result.type == Symbol::ONEOF) ? result.oneof_descriptor : NULL;
+}
+
const EnumDescriptor* DescriptorPool::FindEnumTypeByName(
const string& name) const {
Symbol result = tables_->FindByNameHelper(this, name);
@@ -955,17 +1123,18 @@ const MethodDescriptor* DescriptorPool::FindMethodByName(
const FieldDescriptor* DescriptorPool::FindExtensionByNumber(
const Descriptor* extendee, int number) const {
MutexLockMaybe lock(mutex_);
+ tables_->known_bad_symbols_.clear();
+ tables_->known_bad_files_.clear();
const FieldDescriptor* result = tables_->FindExtension(extendee, number);
if (result != NULL) {
return result;
}
if (underlay_ != NULL) {
- const FieldDescriptor* result =
- underlay_->FindExtensionByNumber(extendee, number);
+ result = underlay_->FindExtensionByNumber(extendee, number);
if (result != NULL) return result;
}
if (TryFindExtensionInFallbackDatabase(extendee, number)) {
- const FieldDescriptor* result = tables_->FindExtension(extendee, number);
+ result = tables_->FindExtension(extendee, number);
if (result != NULL) {
return result;
}
@@ -976,6 +1145,8 @@ const FieldDescriptor* DescriptorPool::FindExtensionByNumber(
void DescriptorPool::FindAllExtensions(
const Descriptor* extendee, vector<const FieldDescriptor*>* out) const {
MutexLockMaybe lock(mutex_);
+ tables_->known_bad_symbols_.clear();
+ tables_->known_bad_files_.clear();
// Initialize tables_->extensions_ from the fallback database first
// (but do this only once per descriptor).
@@ -1000,6 +1171,7 @@ void DescriptorPool::FindAllExtensions(
}
}
+
// -------------------------------------------------------------------
const FieldDescriptor*
@@ -1046,6 +1218,17 @@ Descriptor::FindFieldByName(const string& key) const {
}
}
+const OneofDescriptor*
+Descriptor::FindOneofByName(const string& key) const {
+ Symbol result =
+ file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ONEOF);
+ if (!result.IsNull()) {
+ return result.oneof_descriptor;
+ } else {
+ return NULL;
+ }
+}
+
const FieldDescriptor*
Descriptor::FindExtensionByName(const string& key) const {
Symbol result =
@@ -1210,16 +1393,17 @@ FileDescriptor::FindExtensionByCamelcaseName(const string& key) const {
}
}
-bool Descriptor::IsExtensionNumber(int number) const {
+const Descriptor::ExtensionRange*
+Descriptor::FindExtensionRangeContainingNumber(int number) const {
// Linear search should be fine because we don't expect a message to have
// more than a couple extension ranges.
for (int i = 0; i < extension_range_count(); i++) {
if (number >= extension_range(i)->start &&
number < extension_range(i)->end) {
- return true;
+ return extension_range(i);
}
}
- return false;
+ return NULL;
}
// -------------------------------------------------------------------
@@ -1235,26 +1419,66 @@ bool DescriptorPool::TryFindFileInFallbackDatabase(const string& name) const {
tables_->known_bad_files_.insert(name);
return false;
}
-
return true;
}
+bool DescriptorPool::IsSubSymbolOfBuiltType(const string& name) const {
+ string prefix = name;
+ for (;;) {
+ string::size_type dot_pos = prefix.find_last_of('.');
+ if (dot_pos == string::npos) {
+ break;
+ }
+ prefix = prefix.substr(0, dot_pos);
+ Symbol symbol = tables_->FindSymbol(prefix);
+ // If the symbol type is anything other than PACKAGE, then its complete
+ // definition is already known.
+ if (!symbol.IsNull() && symbol.type != Symbol::PACKAGE) {
+ return true;
+ }
+ }
+ if (underlay_ != NULL) {
+ // Check to see if any prefix of this symbol exists in the underlay.
+ return underlay_->IsSubSymbolOfBuiltType(name);
+ }
+ return false;
+}
+
bool DescriptorPool::TryFindSymbolInFallbackDatabase(const string& name) const {
if (fallback_database_ == NULL) return false;
- FileDescriptorProto file_proto;
- if (!fallback_database_->FindFileContainingSymbol(name, &file_proto)) {
- return false;
- }
-
- if (tables_->FindFile(file_proto.name()) != NULL) {
- // We've already loaded this file, and it apparently doesn't contain the
- // symbol we're looking for. Some DescriptorDatabases return false
- // positives.
- return false;
- }
+ if (tables_->known_bad_symbols_.count(name) > 0) return false;
- if (BuildFileFromDatabase(file_proto) == NULL) {
+ FileDescriptorProto file_proto;
+ if (// We skip looking in the fallback database if the name is a sub-symbol
+ // of any descriptor that already exists in the descriptor pool (except
+ // for package descriptors). This is valid because all symbols except
+ // for packages are defined in a single file, so if the symbol exists
+ // then we should already have its definition.
+ //
+ // The other reason to do this is to support "overriding" type
+ // definitions by merging two databases that define the same type. (Yes,
+ // people do this.) The main difficulty with making this work is that
+ // FindFileContainingSymbol() is allowed to return both false positives
+ // (e.g., SimpleDescriptorDatabase, UpgradedDescriptorDatabase) and false
+ // negatives (e.g. ProtoFileParser, SourceTreeDescriptorDatabase).
+ // When two such databases are merged, looking up a non-existent
+ // sub-symbol of a type that already exists in the descriptor pool can
+ // result in an attempt to load multiple definitions of the same type.
+ // The check below avoids this.
+ IsSubSymbolOfBuiltType(name)
+
+ // Look up file containing this symbol in fallback database.
+ || !fallback_database_->FindFileContainingSymbol(name, &file_proto)
+
+ // Check if we've already built this file. If so, it apparently doesn't
+ // contain the symbol we're looking for. Some DescriptorDatabases
+ // return false positives.
+ || tables_->FindFile(file_proto.name()) != NULL
+
+ // Build the file.
+ || BuildFileFromDatabase(file_proto) == NULL) {
+ tables_->known_bad_symbols_.insert(name);
return false;
}
@@ -1343,6 +1567,14 @@ void FileDescriptor::CopyTo(FileDescriptorProto* proto) const {
proto->add_dependency(dependency(i)->name());
}
+ for (int i = 0; i < public_dependency_count(); i++) {
+ proto->add_public_dependency(public_dependencies_[i]);
+ }
+
+ for (int i = 0; i < weak_dependency_count(); i++) {
+ proto->add_weak_dependency(weak_dependencies_[i]);
+ }
+
for (int i = 0; i < message_type_count(); i++) {
message_type(i)->CopyTo(proto->add_message_type());
}
@@ -1361,12 +1593,21 @@ void FileDescriptor::CopyTo(FileDescriptorProto* proto) const {
}
}
+void FileDescriptor::CopySourceCodeInfoTo(FileDescriptorProto* proto) const {
+ if (source_code_info_ != &SourceCodeInfo::default_instance()) {
+ proto->mutable_source_code_info()->CopyFrom(*source_code_info_);
+ }
+}
+
void Descriptor::CopyTo(DescriptorProto* proto) const {
proto->set_name(name());
for (int i = 0; i < field_count(); i++) {
field(i)->CopyTo(proto->add_field());
}
+ for (int i = 0; i < oneof_decl_count(); i++) {
+ oneof_decl(i)->CopyTo(proto->add_oneof_decl());
+ }
for (int i = 0; i < nested_type_count(); i++) {
nested_type(i)->CopyTo(proto->add_nested_type());
}
@@ -1427,11 +1668,19 @@ void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const {
proto->set_default_value(DefaultValueAsString(false));
}
+ if (containing_oneof() != NULL && !is_extension()) {
+ proto->set_oneof_index(containing_oneof()->index());
+ }
+
if (&options() != &FieldOptions::default_instance()) {
proto->mutable_options()->CopyFrom(options());
}
}
+void OneofDescriptor::CopyTo(OneofDescriptorProto* proto) const {
+ proto->set_name(name());
+}
+
void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const {
proto->set_name(name());
@@ -1488,16 +1737,14 @@ void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const {
namespace {
// Used by each of the option formatters.
-bool RetrieveOptions(const Message &options, vector<string> *option_entries) {
+bool RetrieveOptions(int depth,
+ const Message &options,
+ vector<string> *option_entries) {
option_entries->clear();
const Reflection* reflection = options.GetReflection();
vector<const FieldDescriptor*> fields;
reflection->ListFields(options, &fields);
for (int i = 0; i < fields.size(); i++) {
- // Doesn't make sense to have message type fields here
- if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- continue;
- }
int count = 1;
bool repeated = false;
if (fields[i]->is_repeated()) {
@@ -1506,9 +1753,27 @@ bool RetrieveOptions(const Message &options, vector<string> *option_entries) {
}
for (int j = 0; j < count; j++) {
string fieldval;
- TextFormat::PrintFieldValueToString(options, fields[i],
- repeated ? count : -1, &fieldval);
- option_entries->push_back(fields[i]->name() + " = " + fieldval);
+ if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ string tmp;
+ TextFormat::Printer printer;
+ printer.SetInitialIndentLevel(depth + 1);
+ printer.PrintFieldValueToString(options, fields[i],
+ repeated ? j : -1, &tmp);
+ fieldval.append("{\n");
+ fieldval.append(tmp);
+ fieldval.append(depth * 2, ' ');
+ fieldval.append("}");
+ } else {
+ TextFormat::PrintFieldValueToString(options, fields[i],
+ repeated ? j : -1, &fieldval);
+ }
+ string name;
+ if (fields[i]->is_extension()) {
+ name = "(." + fields[i]->full_name() + ")";
+ } else {
+ name = fields[i]->name();
+ }
+ option_entries->push_back(name + " = " + fieldval);
}
}
return !option_entries->empty();
@@ -1516,10 +1781,10 @@ bool RetrieveOptions(const Message &options, vector<string> *option_entries) {
// Formats options that all appear together in brackets. Does not include
// brackets.
-bool FormatBracketedOptions(const Message &options, string *output) {
+bool FormatBracketedOptions(int depth, const Message &options, string *output) {
vector<string> all_options;
- if (RetrieveOptions(options, &all_options)) {
- output->append(JoinStrings(all_options, ", "));
+ if (RetrieveOptions(depth, options, &all_options)) {
+ output->append(Join(all_options, ", "));
}
return !all_options.empty();
}
@@ -1528,7 +1793,7 @@ bool FormatBracketedOptions(const Message &options, string *output) {
bool FormatLineOptions(int depth, const Message &options, string *output) {
string prefix(depth * 2, ' ');
vector<string> all_options;
- if (RetrieveOptions(options, &all_options)) {
+ if (RetrieveOptions(depth, options, &all_options)) {
for (int i = 0; i < all_options.size(); i++) {
strings::SubstituteAndAppend(output, "$0option $1;\n",
prefix, all_options[i]);
@@ -1542,9 +1807,24 @@ bool FormatLineOptions(int depth, const Message &options, string *output) {
string FileDescriptor::DebugString() const {
string contents = "syntax = \"proto2\";\n\n";
+ set<int> public_dependencies;
+ set<int> weak_dependencies;
+ public_dependencies.insert(public_dependencies_,
+ public_dependencies_ + public_dependency_count_);
+ weak_dependencies.insert(weak_dependencies_,
+ weak_dependencies_ + weak_dependency_count_);
+
for (int i = 0; i < dependency_count(); i++) {
- strings::SubstituteAndAppend(&contents, "import \"$0\";\n",
- dependency(i)->name());
+ if (public_dependencies.count(i) > 0) {
+ strings::SubstituteAndAppend(&contents, "import public \"$0\";\n",
+ dependency(i)->name());
+ } else if (weak_dependencies.count(i) > 0) {
+ strings::SubstituteAndAppend(&contents, "import weak \"$0\";\n",
+ dependency(i)->name());
+ } else {
+ strings::SubstituteAndAppend(&contents, "import \"$0\";\n",
+ dependency(i)->name());
+ }
}
if (!package().empty()) {
@@ -1591,7 +1871,7 @@ string FileDescriptor::DebugString() const {
strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
containing_type->full_name());
}
- extension(i)->DebugString(1, &contents);
+ extension(i)->DebugString(1, FieldDescriptor::PRINT_LABEL, &contents);
}
if (extension_count() > 0) contents.append("}\n\n");
@@ -1638,7 +1918,12 @@ void Descriptor::DebugString(int depth, string *contents) const {
enum_type(i)->DebugString(depth, contents);
}
for (int i = 0; i < field_count(); i++) {
- field(i)->DebugString(depth, contents);
+ if (field(i)->containing_oneof() == NULL) {
+ field(i)->DebugString(depth, FieldDescriptor::PRINT_LABEL, contents);
+ } else if (field(i)->containing_oneof()->field(0) == field(i)) {
+ // This is the first field in this oneof, so print the whole oneof.
+ field(i)->containing_oneof()->DebugString(depth, contents);
+ }
}
for (int i = 0; i < extension_range_count(); i++) {
@@ -1657,7 +1942,8 @@ void Descriptor::DebugString(int depth, string *contents) const {
strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n",
prefix, containing_type->full_name());
}
- extension(i)->DebugString(depth + 1, contents);
+ extension(i)->DebugString(
+ depth + 1, FieldDescriptor::PRINT_LABEL, contents);
}
if (extension_count() > 0)
strings::SubstituteAndAppend(contents, "$0 }\n", prefix);
@@ -1673,14 +1959,16 @@ string FieldDescriptor::DebugString() const {
containing_type()->full_name());
depth = 1;
}
- DebugString(depth, &contents);
+ DebugString(depth, PRINT_LABEL, &contents);
if (is_extension()) {
- contents.append("}\n");
+ contents.append("}\n");
}
return contents;
}
-void FieldDescriptor::DebugString(int depth, string *contents) const {
+void FieldDescriptor::DebugString(int depth,
+ PrintLabelFlag print_label_flag,
+ string *contents) const {
string prefix(depth * 2, ' ');
string field_type;
switch (type()) {
@@ -1694,9 +1982,15 @@ void FieldDescriptor::DebugString(int depth, string *contents) const {
field_type = kTypeToName[type()];
}
- strings::SubstituteAndAppend(contents, "$0$1 $2 $3 = $4",
+ string label;
+ if (print_label_flag == PRINT_LABEL) {
+ label = kLabelToName[this->label()];
+ label.push_back(' ');
+ }
+
+ strings::SubstituteAndAppend(contents, "$0$1$2 $3 = $4",
prefix,
- kLabelToName[label()],
+ label,
field_type,
type() == TYPE_GROUP ? message_type()->name() :
name(),
@@ -1710,7 +2004,7 @@ void FieldDescriptor::DebugString(int depth, string *contents) const {
}
string formatted_options;
- if (FormatBracketedOptions(options(), &formatted_options)) {
+ if (FormatBracketedOptions(depth, options(), &formatted_options)) {
contents->append(bracketed ? ", " : " [");
bracketed = true;
contents->append(formatted_options);
@@ -1727,6 +2021,23 @@ void FieldDescriptor::DebugString(int depth, string *contents) const {
}
}
+string OneofDescriptor::DebugString() const {
+ string contents;
+ DebugString(0, &contents);
+ return contents;
+}
+
+void OneofDescriptor::DebugString(int depth, string* contents) const {
+ string prefix(depth * 2, ' ');
+ ++depth;
+ strings::SubstituteAndAppend(
+ contents, "$0 oneof $1 {\n", prefix, name());
+ for (int i = 0; i < field_count(); i++) {
+ field(i)->DebugString(depth, FieldDescriptor::OMIT_LABEL, contents);
+ }
+ strings::SubstituteAndAppend(contents, "$0}\n", prefix);
+}
+
string EnumDescriptor::DebugString() const {
string contents;
DebugString(0, &contents);
@@ -1759,7 +2070,7 @@ void EnumValueDescriptor::DebugString(int depth, string *contents) const {
prefix, name(), number());
string formatted_options;
- if (FormatBracketedOptions(options(), &formatted_options)) {
+ if (FormatBracketedOptions(depth, options(), &formatted_options)) {
strings::SubstituteAndAppend(contents, " [$0]", formatted_options);
}
contents->append(";\n");
@@ -1805,6 +2116,141 @@ void MethodDescriptor::DebugString(int depth, string *contents) const {
contents->append(";\n");
}
}
+
+
+// Location methods ===============================================
+
+bool FileDescriptor::GetSourceLocation(const vector<int>& path,
+ SourceLocation* out_location) const {
+ GOOGLE_CHECK_NOTNULL(out_location);
+ if (source_code_info_) {
+ if (const SourceCodeInfo_Location* loc =
+ tables_->GetSourceLocation(path, source_code_info_)) {
+ const RepeatedField<int32>& span = loc->span();
+ if (span.size() == 3 || span.size() == 4) {
+ out_location->start_line = span.Get(0);
+ out_location->start_column = span.Get(1);
+ out_location->end_line = span.Get(span.size() == 3 ? 0 : 2);
+ out_location->end_column = span.Get(span.size() - 1);
+
+ out_location->leading_comments = loc->leading_comments();
+ out_location->trailing_comments = loc->trailing_comments();
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool FieldDescriptor::is_packed() const {
+ return is_packable() && (options_ != NULL) && options_->packed();
+}
+
+bool Descriptor::GetSourceLocation(SourceLocation* out_location) const {
+ vector<int> path;
+ GetLocationPath(&path);
+ return file()->GetSourceLocation(path, out_location);
+}
+
+bool FieldDescriptor::GetSourceLocation(SourceLocation* out_location) const {
+ vector<int> path;
+ GetLocationPath(&path);
+ return file()->GetSourceLocation(path, out_location);
+}
+
+bool OneofDescriptor::GetSourceLocation(SourceLocation* out_location) const {
+ vector<int> path;
+ GetLocationPath(&path);
+ return containing_type()->file()->GetSourceLocation(path, out_location);
+}
+
+bool EnumDescriptor::GetSourceLocation(SourceLocation* out_location) const {
+ vector<int> path;
+ GetLocationPath(&path);
+ return file()->GetSourceLocation(path, out_location);
+}
+
+bool MethodDescriptor::GetSourceLocation(SourceLocation* out_location) const {
+ vector<int> path;
+ GetLocationPath(&path);
+ return service()->file()->GetSourceLocation(path, out_location);
+}
+
+bool ServiceDescriptor::GetSourceLocation(SourceLocation* out_location) const {
+ vector<int> path;
+ GetLocationPath(&path);
+ return file()->GetSourceLocation(path, out_location);
+}
+
+bool EnumValueDescriptor::GetSourceLocation(
+ SourceLocation* out_location) const {
+ vector<int> path;
+ GetLocationPath(&path);
+ return type()->file()->GetSourceLocation(path, out_location);
+}
+
+void Descriptor::GetLocationPath(vector<int>* output) const {
+ if (containing_type()) {
+ containing_type()->GetLocationPath(output);
+ output->push_back(DescriptorProto::kNestedTypeFieldNumber);
+ output->push_back(index());
+ } else {
+ output->push_back(FileDescriptorProto::kMessageTypeFieldNumber);
+ output->push_back(index());
+ }
+}
+
+void FieldDescriptor::GetLocationPath(vector<int>* output) const {
+ if (is_extension()) {
+ if (extension_scope() == NULL) {
+ output->push_back(FileDescriptorProto::kExtensionFieldNumber);
+ output->push_back(index());
+ } else {
+ extension_scope()->GetLocationPath(output);
+ output->push_back(DescriptorProto::kExtensionFieldNumber);
+ output->push_back(index());
+ }
+ } else {
+ containing_type()->GetLocationPath(output);
+ output->push_back(DescriptorProto::kFieldFieldNumber);
+ output->push_back(index());
+ }
+}
+
+void OneofDescriptor::GetLocationPath(vector<int>* output) const {
+ containing_type()->GetLocationPath(output);
+ output->push_back(DescriptorProto::kOneofDeclFieldNumber);
+ output->push_back(index());
+}
+
+void EnumDescriptor::GetLocationPath(vector<int>* output) const {
+ if (containing_type()) {
+ containing_type()->GetLocationPath(output);
+ output->push_back(DescriptorProto::kEnumTypeFieldNumber);
+ output->push_back(index());
+ } else {
+ output->push_back(FileDescriptorProto::kEnumTypeFieldNumber);
+ output->push_back(index());
+ }
+}
+
+void EnumValueDescriptor::GetLocationPath(vector<int>* output) const {
+ type()->GetLocationPath(output);
+ output->push_back(EnumDescriptorProto::kValueFieldNumber);
+ output->push_back(index());
+}
+
+void ServiceDescriptor::GetLocationPath(vector<int>* output) const {
+ output->push_back(FileDescriptorProto::kServiceFieldNumber);
+ output->push_back(index());
+}
+
+void MethodDescriptor::GetLocationPath(vector<int>* output) const {
+ service()->GetLocationPath(output);
+ output->push_back(ServiceDescriptorProto::kMethodFieldNumber);
+ output->push_back(index());
+}
+
// ===================================================================
namespace {
@@ -1857,6 +2303,11 @@ class DescriptorBuilder {
string filename_;
FileDescriptor* file_;
FileDescriptorTables* file_tables_;
+ set<const FileDescriptor*> dependencies_;
+
+ // unused_dependency_ is used to record the unused imported files.
+ // Note: public import is not considered.
+ set<const FileDescriptor*> unused_dependency_;
// If LookupSymbol() finds a symbol that is in a file which is not a declared
// dependency of this file, it will fail, but will set
@@ -1868,10 +2319,22 @@ class DescriptorBuilder {
const FileDescriptor* possible_undeclared_dependency_;
string possible_undeclared_dependency_name_;
+ // If LookupSymbol() could resolve a symbol which is not defined,
+ // record the resolved name. This is only used by AddNotDefinedError()
+ // to report a more useful error message.
+ string undefine_resolved_name_;
+
void AddError(const string& element_name,
const Message& descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location,
const string& error);
+ void AddError(const string& element_name,
+ const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const char* error);
+ void AddRecursiveImportError(const FileDescriptorProto& proto, int from_here);
+ void AddTwiceListedError(const FileDescriptorProto& proto, int index);
+ void AddImportError(const FileDescriptorProto& proto, int index);
// Adds an error indicating that undefined_symbol was not defined. Must
// only be called after LookupSymbol() fails.
@@ -1881,11 +2344,19 @@ class DescriptorBuilder {
DescriptorPool::ErrorCollector::ErrorLocation location,
const string& undefined_symbol);
+ void AddWarning(const string& element_name, const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const string& error);
+
// Silly helper which determines if the given file is in the given package.
// I.e., either file->package() == package_name or file->package() is a
// nested package within package_name.
bool IsInPackage(const FileDescriptor* file, const string& package_name);
+ // Helper function which finds all public dependencies of the given file, and
+ // stores the them in the dependencies_ set in the builder.
+ void RecordPublicDependencies(const FileDescriptor* file);
+
// Like tables_->FindSymbol(), but additionally:
// - Search the pool's underlay if not found in tables_.
// - Insure that the resulting Symbol is from one of the file's declared
@@ -1896,6 +2367,10 @@ class DescriptorBuilder {
// file's declared dependencies.
Symbol FindSymbolNotEnforcingDeps(const string& name);
+ // This implements the body of FindSymbolNotEnforcingDeps().
+ Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool,
+ const string& name);
+
// Like FindSymbol(), but looks up the name relative to some other symbol
// name. This first searches siblings of relative_to, then siblings of its
// parents, etc. For example, LookupSymbol("foo.bar", "baz.qux.corge") makes
@@ -2007,6 +2482,9 @@ class DescriptorBuilder {
void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto,
const Descriptor* parent,
Descriptor::ExtensionRange* result);
+ void BuildOneof(const OneofDescriptorProto& proto,
+ Descriptor* parent,
+ OneofDescriptor* result);
void BuildEnum(const EnumDescriptorProto& proto,
const Descriptor* parent,
EnumDescriptor* result);
@@ -2020,6 +2498,8 @@ class DescriptorBuilder {
const ServiceDescriptor* parent,
MethodDescriptor* result);
+ void LogUnusedDependency(const FileDescriptor* result);
+
// Must be run only after building.
//
// NOTE: Options will not be available during cross-linking, as they
@@ -2056,6 +2536,8 @@ class DescriptorBuilder {
// Otherwise returns true.
bool InterpretOptions(OptionsToInterpret* options_to_interpret);
+ class AggregateOptionFinder;
+
private:
// Interprets uninterpreted_option_ on the specified message, which
// must be the mutable copy of the original options message to which
@@ -2082,6 +2564,11 @@ class DescriptorBuilder {
bool SetOptionValue(const FieldDescriptor* option_field,
UnknownFieldSet* unknown_fields);
+ // Parses an aggregate value for a CPPTYPE_MESSAGE option and
+ // saves it into *unknown_fields.
+ bool SetAggregateOption(const FieldDescriptor* option_field,
+ UnknownFieldSet* unknown_fields);
+
// Convenience functions to set an int field the right way, depending on
// its wire type (a single int CppType can represent multiple wire types).
void SetInt32(int number, int32 value, FieldDescriptor::Type type,
@@ -2128,6 +2615,10 @@ class DescriptorBuilder {
// can use it to find locations recorded by the parser.
const UninterpretedOption* uninterpreted_option_;
+ // Factory used to create the dynamic messages we need to parse
+ // any aggregate option values we encounter.
+ DynamicMessageFactory dynamic_factory_;
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OptionInterpreter);
};
@@ -2139,12 +2630,22 @@ class DescriptorBuilder {
// redundantly declare OptionInterpreter a friend just to make things extra
// clear for these bad compilers.
friend class OptionInterpreter;
+ friend class OptionInterpreter::AggregateOptionFinder;
+
static inline bool get_allow_unknown(const DescriptorPool* pool) {
return pool->allow_unknown_;
}
+ static inline bool get_enforce_weak(const DescriptorPool* pool) {
+ return pool->enforce_weak_;
+ }
static inline bool get_is_placeholder(const Descriptor* descriptor) {
return descriptor->is_placeholder_;
}
+ static inline void assert_mutex_held(const DescriptorPool* pool) {
+ if (pool->mutex_ != NULL) {
+ pool->mutex_->AssertHeld();
+ }
+ }
// Must be run only after options have been interpreted.
//
@@ -2169,6 +2670,7 @@ class DescriptorBuilder {
void ValidateMapKey(FieldDescriptor* field,
const FieldDescriptorProto& proto);
+
};
const FileDescriptor* DescriptorPool::BuildFile(
@@ -2178,6 +2680,8 @@ const FileDescriptor* DescriptorPool::BuildFile(
"DescriptorDatabase. You must instead find a way to get your file "
"into the underlying database.";
GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK.
+ tables_->known_bad_symbols_.clear();
+ tables_->known_bad_files_.clear();
return DescriptorBuilder(this, tables_.get(), NULL).BuildFile(proto);
}
@@ -2189,6 +2693,8 @@ const FileDescriptor* DescriptorPool::BuildFileCollectingErrors(
"DescriptorDatabase. You must instead find a way to get your file "
"into the underlying database.";
GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK.
+ tables_->known_bad_symbols_.clear();
+ tables_->known_bad_files_.clear();
return DescriptorBuilder(this, tables_.get(),
error_collector).BuildFile(proto);
}
@@ -2196,8 +2702,16 @@ const FileDescriptor* DescriptorPool::BuildFileCollectingErrors(
const FileDescriptor* DescriptorPool::BuildFileFromDatabase(
const FileDescriptorProto& proto) const {
mutex_->AssertHeld();
- return DescriptorBuilder(this, tables_.get(),
- default_error_collector_).BuildFile(proto);
+ if (tables_->known_bad_files_.count(proto.name()) > 0) {
+ return NULL;
+ }
+ const FileDescriptor* result =
+ DescriptorBuilder(this, tables_.get(),
+ default_error_collector_).BuildFile(proto);
+ if (result == NULL) {
+ tables_->known_bad_files_.insert(proto.name());
+ }
+ return result;
}
DescriptorBuilder::DescriptorBuilder(
@@ -2208,7 +2722,8 @@ DescriptorBuilder::DescriptorBuilder(
tables_(tables),
error_collector_(error_collector),
had_errors_(false),
- possible_undeclared_dependency_(NULL) {}
+ possible_undeclared_dependency_(NULL),
+ undefine_resolved_name_("") {}
DescriptorBuilder::~DescriptorBuilder() {}
@@ -2230,21 +2745,53 @@ void DescriptorBuilder::AddError(
had_errors_ = true;
}
+void DescriptorBuilder::AddError(
+ const string& element_name,
+ const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const char* error) {
+ AddError(element_name, descriptor, location, string(error));
+}
+
void DescriptorBuilder::AddNotDefinedError(
const string& element_name,
const Message& descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location,
const string& undefined_symbol) {
- if (possible_undeclared_dependency_ == NULL) {
+ if (possible_undeclared_dependency_ == NULL &&
+ undefine_resolved_name_.empty()) {
AddError(element_name, descriptor, location,
"\"" + undefined_symbol + "\" is not defined.");
} else {
- AddError(element_name, descriptor, location,
- "\"" + possible_undeclared_dependency_name_ +
- "\" seems to be defined in \"" +
- possible_undeclared_dependency_->name() + "\", which is not "
- "imported by \"" + filename_ + "\". To use it here, please "
- "add the necessary import.");
+ if (possible_undeclared_dependency_ != NULL) {
+ AddError(element_name, descriptor, location,
+ "\"" + possible_undeclared_dependency_name_ +
+ "\" seems to be defined in \"" +
+ possible_undeclared_dependency_->name() + "\", which is not "
+ "imported by \"" + filename_ + "\". To use it here, please "
+ "add the necessary import.");
+ }
+ if (!undefine_resolved_name_.empty()) {
+ AddError(element_name, descriptor, location,
+ "\"" + undefined_symbol + "\" is resolved to \"" +
+ undefine_resolved_name_ + "\", which is not defined. "
+ "The innermost scope is searched first in name resolution. "
+ "Consider using a leading '.'(i.e., \"."
+ + undefined_symbol +
+ "\") to start from the outermost scope.");
+ }
+ }
+}
+
+void DescriptorBuilder::AddWarning(
+ const string& element_name, const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const string& error) {
+ if (error_collector_ == NULL) {
+ GOOGLE_LOG(WARNING) << filename_ << " " << element_name << ": " << error;
+ } else {
+ error_collector_->AddWarning(filename_, element_name, &descriptor, location,
+ error);
}
}
@@ -2255,31 +2802,48 @@ bool DescriptorBuilder::IsInPackage(const FileDescriptor* file,
file->package()[package_name.size()] == '.');
}
-Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name) {
- Symbol result;
+void DescriptorBuilder::RecordPublicDependencies(const FileDescriptor* file) {
+ if (file == NULL || !dependencies_.insert(file).second) return;
+ for (int i = 0; file != NULL && i < file->public_dependency_count(); i++) {
+ RecordPublicDependencies(file->public_dependency(i));
+ }
+}
- // We need to search our pool and all its underlays.
- const DescriptorPool* pool = pool_;
- while (true) {
- // If we are looking at an underlay, we must lock its mutex_, since we are
- // accessing the underlay's tables_ dircetly.
- MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_);
+Symbol DescriptorBuilder::FindSymbolNotEnforcingDepsHelper(
+ const DescriptorPool* pool, const string& name) {
+ // If we are looking at an underlay, we must lock its mutex_, since we are
+ // accessing the underlay's tables_ directly.
+ MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_);
+
+ Symbol result = pool->tables_->FindSymbol(name);
+ if (result.IsNull() && pool->underlay_ != NULL) {
+ // Symbol not found; check the underlay.
+ result = FindSymbolNotEnforcingDepsHelper(pool->underlay_, name);
+ }
- // Note that we don't have to check fallback_database_ here because the
- // symbol has to be in one of its file's direct dependencies, and we have
- // already loaded those by the time we get here.
- result = pool->tables_->FindSymbol(name);
- if (!result.IsNull()) break;
- if (pool->underlay_ == NULL) return kNullSymbol;
- pool = pool->underlay_;
+ if (result.IsNull()) {
+ // In theory, we shouldn't need to check fallback_database_ because the
+ // symbol should be in one of its file's direct dependencies, and we have
+ // already loaded those by the time we get here. But we check anyway so
+ // that we can generate better error message when dependencies are missing
+ // (i.e., "missing dependency" rather than "type is not defined").
+ if (pool->TryFindSymbolInFallbackDatabase(name)) {
+ result = pool->tables_->FindSymbol(name);
+ }
}
return result;
}
+Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name) {
+ return FindSymbolNotEnforcingDepsHelper(pool_, name);
+}
+
Symbol DescriptorBuilder::FindSymbol(const string& name) {
Symbol result = FindSymbolNotEnforcingDeps(name);
+ if (result.IsNull()) return result;
+
if (!pool_->enforce_dependencies_) {
// Hack for CompilerUpgrader.
return result;
@@ -2288,9 +2852,9 @@ Symbol DescriptorBuilder::FindSymbol(const string& name) {
// Only find symbols which were defined in this file or one of its
// dependencies.
const FileDescriptor* file = result.GetFile();
- if (file == file_) return result;
- for (int i = 0; i < file_->dependency_count(); i++) {
- if (file == file_->dependency(i)) return result;
+ if (file == file_ || dependencies_.count(file) > 0) {
+ unused_dependency_.erase(file);
+ return result;
}
if (result.type == Symbol::PACKAGE) {
@@ -2302,12 +2866,10 @@ Symbol DescriptorBuilder::FindSymbol(const string& name) {
// dependency also defines the same package. We can't really rule out this
// symbol unless none of the dependencies define it.
if (IsInPackage(file_, name)) return result;
- for (int i = 0; i < file_->dependency_count(); i++) {
+ for (set<const FileDescriptor*>::const_iterator it = dependencies_.begin();
+ it != dependencies_.end(); ++it) {
// Note: A dependency may be NULL if it was not found or had errors.
- if (file_->dependency(i) != NULL &&
- IsInPackage(file_->dependency(i), name)) {
- return result;
- }
+ if (*it != NULL && IsInPackage(*it, name)) return result;
}
}
@@ -2319,6 +2881,7 @@ Symbol DescriptorBuilder::FindSymbol(const string& name) {
Symbol DescriptorBuilder::LookupSymbolNoPlaceholder(
const string& name, const string& relative_to, ResolveMode resolve_mode) {
possible_undeclared_dependency_ = NULL;
+ undefine_resolved_name_.clear();
if (name.size() > 0 && name[0] == '.') {
// Fully-qualified name.
@@ -2336,7 +2899,7 @@ Symbol DescriptorBuilder::LookupSymbolNoPlaceholder(
// }
// So, we look for just "Foo" first, then look for "Bar.baz" within it if
// found.
- int name_dot_pos = name.find_first_of('.');
+ string::size_type name_dot_pos = name.find_first_of('.');
string first_part_of_name;
if (name_dot_pos == string::npos) {
first_part_of_name = name;
@@ -2367,7 +2930,11 @@ Symbol DescriptorBuilder::LookupSymbolNoPlaceholder(
if (result.IsAggregate()) {
scope_to_try.append(name, first_part_of_name.size(),
name.size() - first_part_of_name.size());
- return FindSymbol(scope_to_try);
+ result = FindSymbol(scope_to_try);
+ if (result.IsNull()) {
+ undefine_resolved_name_ = scope_to_try;
+ }
+ return result;
} else {
// We found a symbol but it's not an aggregate. Continue the loop.
}
@@ -2420,7 +2987,7 @@ Symbol DescriptorBuilder::NewPlaceholder(const string& name,
placeholder_name = tables_->AllocateString(
placeholder_full_name->substr(dotpos + 1));
} else {
- placeholder_package = &kEmptyString;
+ placeholder_package = &internal::GetEmptyString();
placeholder_name = placeholder_full_name;
}
@@ -2428,12 +2995,15 @@ Symbol DescriptorBuilder::NewPlaceholder(const string& name,
FileDescriptor* placeholder_file = tables_->Allocate<FileDescriptor>();
memset(placeholder_file, 0, sizeof(*placeholder_file));
+ placeholder_file->source_code_info_ = &SourceCodeInfo::default_instance();
+
placeholder_file->name_ =
tables_->AllocateString(*placeholder_full_name + ".placeholder.proto");
placeholder_file->package_ = placeholder_package;
placeholder_file->pool_ = pool_;
placeholder_file->options_ = &FileOptions::default_instance();
placeholder_file->tables_ = &FileDescriptorTables::kEmpty;
+ placeholder_file->is_placeholder_ = true;
// All other fields are zero or NULL.
if (placeholder_type == PLACEHOLDER_ENUM) {
@@ -2504,10 +3074,11 @@ const FileDescriptor* DescriptorBuilder::NewPlaceholderFile(
memset(placeholder, 0, sizeof(*placeholder));
placeholder->name_ = tables_->AllocateString(name);
- placeholder->package_ = &kEmptyString;
+ placeholder->package_ = &internal::GetEmptyString();
placeholder->pool_ = pool_;
placeholder->options_ = &FileOptions::default_instance();
placeholder->tables_ = &FileDescriptorTables::kEmpty;
+ placeholder->is_placeholder_ = true;
// All other fields are zero or NULL.
return placeholder;
@@ -2648,7 +3219,11 @@ template<class DescriptorT> void DescriptorBuilder::AllocateOptionsImpl(
// tables_->AllocateMessage<typename DescriptorT::OptionsType>();
typename DescriptorT::OptionsType* const dummy = NULL;
typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy);
- options->CopyFrom(orig_options);
+ // Avoid using MergeFrom()/CopyFrom() in this class to make it -fno-rtti
+ // friendly. Without RTTI, MergeFrom() and CopyFrom() will fallback to the
+ // reflection based method, which requires the Descriptor. However, we are in
+ // the middle of building the descriptors, thus the deadlock.
+ options->ParseFromString(orig_options.SerializeAsString());
descriptor->options_ = options;
// Don't add to options_to_interpret_ unless there were uninterpreted
@@ -2674,6 +3249,45 @@ template<class DescriptorT> void DescriptorBuilder::AllocateOptionsImpl(
METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \
}
+void DescriptorBuilder::AddRecursiveImportError(
+ const FileDescriptorProto& proto, int from_here) {
+ string error_message("File recursively imports itself: ");
+ for (int i = from_here; i < tables_->pending_files_.size(); i++) {
+ error_message.append(tables_->pending_files_[i]);
+ error_message.append(" -> ");
+ }
+ error_message.append(proto.name());
+
+ AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
+ error_message);
+}
+
+void DescriptorBuilder::AddTwiceListedError(const FileDescriptorProto& proto,
+ int index) {
+ AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
+ "Import \"" + proto.dependency(index) + "\" was listed twice.");
+}
+
+void DescriptorBuilder::AddImportError(const FileDescriptorProto& proto,
+ int index) {
+ string message;
+ if (pool_->fallback_database_ == NULL) {
+ message = "Import \"" + proto.dependency(index) +
+ "\" has not been loaded.";
+ } else {
+ message = "Import \"" + proto.dependency(index) +
+ "\" was not found or had errors.";
+ }
+ AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, message);
+}
+
+static bool ExistingFileMatchesProto(const FileDescriptor* existing_file,
+ const FileDescriptorProto& proto) {
+ FileDescriptorProto existing_proto;
+ existing_file->CopyTo(&existing_proto);
+ return existing_proto.SerializeAsString() == proto.SerializeAsString();
+}
+
const FileDescriptor* DescriptorBuilder::BuildFile(
const FileDescriptorProto& proto) {
filename_ = proto.name();
@@ -2686,9 +3300,7 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
const FileDescriptor* existing_file = tables_->FindFile(filename_);
if (existing_file != NULL) {
// File already in pool. Compare the existing one to the input.
- FileDescriptorProto existing_proto;
- existing_file->CopyTo(&existing_proto);
- if (existing_proto.SerializeAsString() == proto.SerializeAsString()) {
+ if (ExistingFileMatchesProto(existing_file, proto)) {
// They're identical. Return the existing descriptor.
return existing_file;
}
@@ -2707,15 +3319,7 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
// at all.
for (int i = 0; i < tables_->pending_files_.size(); i++) {
if (tables_->pending_files_[i] == proto.name()) {
- string error_message("File recursively imports itself: ");
- for (; i < tables_->pending_files_.size(); i++) {
- error_message.append(tables_->pending_files_[i]);
- error_message.append(" -> ");
- }
- error_message.append(proto.name());
-
- AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
- error_message);
+ AddRecursiveImportError(proto, i);
return NULL;
}
}
@@ -2737,11 +3341,20 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
}
// Checkpoint the tables so that we can roll back if something goes wrong.
- tables_->Checkpoint();
+ tables_->AddCheckpoint();
FileDescriptor* result = tables_->Allocate<FileDescriptor>();
file_ = result;
+ result->is_placeholder_ = false;
+ if (proto.has_source_code_info()) {
+ SourceCodeInfo *info = tables_->AllocateMessage<SourceCodeInfo>();
+ info->CopyFrom(proto.source_code_info());
+ result->source_code_info_ = info;
+ } else {
+ result->source_code_info_ = &SourceCodeInfo::default_instance();
+ }
+
file_tables_ = tables_->AllocateFileTables();
file_->tables_ = file_tables_;
@@ -2768,7 +3381,7 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
"A file with this name is already in the pool.");
// Bail out early so that if this is actually the exact same file, we
// don't end up reporting that every single symbol is already defined.
- tables_->Rollback();
+ tables_->RollbackToLastCheckpoint();
return NULL;
}
if (!result->package().empty()) {
@@ -2780,11 +3393,14 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
result->dependency_count_ = proto.dependency_size();
result->dependencies_ =
tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size());
+ unused_dependency_.clear();
+ set<int> weak_deps;
+ for (int i = 0; i < proto.weak_dependency_size(); ++i) {
+ weak_deps.insert(proto.weak_dependency(i));
+ }
for (int i = 0; i < proto.dependency_size(); i++) {
if (!seen_dependencies.insert(proto.dependency(i)).second) {
- AddError(proto.name(), proto,
- DescriptorPool::ErrorCollector::OTHER,
- "Import \"" + proto.dependency(i) + "\" was listed twice.");
+ AddTwiceListedError(proto, i);
}
const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i));
@@ -2793,26 +3409,67 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
}
if (dependency == NULL) {
- if (pool_->allow_unknown_) {
+ if (pool_->allow_unknown_ ||
+ (!pool_->enforce_weak_ && weak_deps.find(i) != weak_deps.end())) {
dependency = NewPlaceholderFile(proto.dependency(i));
} else {
- string message;
- if (pool_->fallback_database_ == NULL) {
- message = "Import \"" + proto.dependency(i) +
- "\" has not been loaded.";
- } else {
- message = "Import \"" + proto.dependency(i) +
- "\" was not found or had errors.";
- }
- AddError(proto.name(), proto,
- DescriptorPool::ErrorCollector::OTHER,
- message);
+ AddImportError(proto, i);
+ }
+ } else {
+ // Add to unused_dependency_ to track unused imported files.
+ // Note: do not track unused imported files for public import.
+ if (pool_->enforce_dependencies_ &&
+ (pool_->unused_import_track_files_.find(proto.name()) !=
+ pool_->unused_import_track_files_.end()) &&
+ (dependency->public_dependency_count() == 0)) {
+ unused_dependency_.insert(dependency);
}
}
result->dependencies_[i] = dependency;
}
+ // Check public dependencies.
+ int public_dependency_count = 0;
+ result->public_dependencies_ = tables_->AllocateArray<int>(
+ proto.public_dependency_size());
+ for (int i = 0; i < proto.public_dependency_size(); i++) {
+ // Only put valid public dependency indexes.
+ int index = proto.public_dependency(i);
+ if (index >= 0 && index < proto.dependency_size()) {
+ result->public_dependencies_[public_dependency_count++] = index;
+ // Do not track unused imported files for public import.
+ unused_dependency_.erase(result->dependency(index));
+ } else {
+ AddError(proto.name(), proto,
+ DescriptorPool::ErrorCollector::OTHER,
+ "Invalid public dependency index.");
+ }
+ }
+ result->public_dependency_count_ = public_dependency_count;
+
+ // Build dependency set
+ dependencies_.clear();
+ for (int i = 0; i < result->dependency_count(); i++) {
+ RecordPublicDependencies(result->dependency(i));
+ }
+
+ // Check weak dependencies.
+ int weak_dependency_count = 0;
+ result->weak_dependencies_ = tables_->AllocateArray<int>(
+ proto.weak_dependency_size());
+ for (int i = 0; i < proto.weak_dependency_size(); i++) {
+ int index = proto.weak_dependency(i);
+ if (index >= 0 && index < proto.dependency_size()) {
+ result->weak_dependencies_[weak_dependency_count++] = index;
+ } else {
+ AddError(proto.name(), proto,
+ DescriptorPool::ErrorCollector::OTHER,
+ "Invalid weak dependency index.");
+ }
+ }
+ result->weak_dependency_count_ = weak_dependency_count;
+
// Convert children.
BUILD_ARRAY(proto, result, message_type, BuildMessage , NULL);
BUILD_ARRAY(proto, result, enum_type , BuildEnum , NULL);
@@ -2849,11 +3506,16 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
ValidateFileOptions(result, proto);
}
+
+ if (!unused_dependency_.empty()) {
+ LogUnusedDependency(result);
+ }
+
if (had_errors_) {
- tables_->Rollback();
+ tables_->RollbackToLastCheckpoint();
return NULL;
} else {
- tables_->Checkpoint();
+ tables_->ClearLastCheckpoint();
return result;
}
}
@@ -2876,6 +3538,8 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
result->is_placeholder_ = false;
result->is_unqualified_placeholder_ = false;
+ // Build oneofs first so that fields and extension ranges can refer to them.
+ BUILD_ARRAY(proto, result, oneof_decl , BuildOneof , result);
BUILD_ARRAY(proto, result, field , BuildField , result);
BUILD_ARRAY(proto, result, nested_type , BuildMessage , result);
BUILD_ARRAY(proto, result, enum_type , BuildEnum , result);
@@ -2966,6 +3630,19 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
result->label_ = static_cast<FieldDescriptor::Label>(
implicit_cast<int>(proto.label()));
+ // An extension cannot have a required field (b/13365836).
+ if (result->is_extension_ &&
+ result->label_ == FieldDescriptor::LABEL_REQUIRED) {
+ AddError(result->full_name(), proto,
+ // Error location `TYPE`: we would really like to indicate
+ // `LABEL`, but the `ErrorLocation` enum has no entry for this, and
+ // we don't necessarily know about all implementations of the
+ // `ErrorCollector` interface to extend them to handle the new
+ // error location type properly.
+ DescriptorPool::ErrorCollector::TYPE,
+ "Message extensions cannot have required fields.");
+ }
+
// Some of these may be filled in when cross-linking.
result->containing_type_ = NULL;
result->extension_scope_ = NULL;
@@ -3009,7 +3686,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
result->default_value_float_ = numeric_limits<float>::quiet_NaN();
} else {
result->default_value_float_ =
- NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
+ io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
}
break;
case FieldDescriptor::CPPTYPE_DOUBLE:
@@ -3021,7 +3698,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
result->default_value_double_ = numeric_limits<double>::quiet_NaN();
} else {
result->default_value_double_ =
- NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
+ io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
}
break;
case FieldDescriptor::CPPTYPE_BOOL:
@@ -3045,7 +3722,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
UnescapeCEscapeString(proto.default_value()));
} else {
result->default_value_string_ =
- tables_->AllocateString(proto.default_value());
+ tables_->AllocateString(proto.default_value());
}
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
@@ -3063,7 +3740,8 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
if (proto.default_value().empty() || *end_pos != '\0') {
AddError(result->full_name(), proto,
DescriptorPool::ErrorCollector::DEFAULT_VALUE,
- "Couldn't parse default value.");
+ "Couldn't parse default value \"" + proto.default_value() +
+ "\".");
}
}
} else {
@@ -3095,7 +3773,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
result->default_value_enum_ = NULL;
break;
case FieldDescriptor::CPPTYPE_STRING:
- result->default_value_string_ = &kEmptyString;
+ result->default_value_string_ = &internal::GetEmptyString();
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
break;
@@ -3106,7 +3784,15 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
if (result->number() <= 0) {
AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
"Field numbers must be positive integers.");
- } else if (result->number() > FieldDescriptor::kMaxNumber) {
+ } else if (!is_extension && result->number() > FieldDescriptor::kMaxNumber) {
+ // Only validate that the number is within the valid field range if it is
+ // not an extension. Since extension numbers are validated with the
+ // extendee's valid set of extension numbers, and those are in turn
+ // validated against the max allowed number, the check is unnecessary for
+ // extension fields.
+ // This avoids cross-linking issues that arise when attempting to check if
+ // the extendee is a message_set_wire_format message, which has a higher max
+ // on extension numbers.
AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
strings::Substitute("Field numbers cannot be greater than $0.",
FieldDescriptor::kMaxNumber));
@@ -3128,6 +3814,16 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
}
result->extension_scope_ = parent;
+
+ if (proto.has_oneof_index()) {
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::OTHER,
+ "FieldDescriptorProto.oneof_index should not be set for "
+ "extensions.");
+ }
+
+ // Fill in later (maybe).
+ result->containing_oneof_ = NULL;
} else {
if (proto.has_extendee()) {
AddError(result->full_name(), proto,
@@ -3136,6 +3832,23 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
}
result->containing_type_ = parent;
+
+ if (proto.has_oneof_index()) {
+ if (proto.oneof_index() < 0 ||
+ proto.oneof_index() >= parent->oneof_decl_count()) {
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::OTHER,
+ strings::Substitute("FieldDescriptorProto.oneof_index $0 is "
+ "out of range for type \"$1\".",
+ proto.oneof_index(),
+ parent->name()));
+ result->containing_oneof_ = NULL;
+ } else {
+ result->containing_oneof_ = parent->oneof_decl(proto.oneof_index());
+ }
+ } else {
+ result->containing_oneof_ = NULL;
+ }
}
// Copy options.
@@ -3161,12 +3874,10 @@ void DescriptorBuilder::BuildExtensionRange(
"Extension numbers must be positive integers.");
}
- if (result->end > FieldDescriptor::kMaxNumber + 1) {
- AddError(parent->full_name(), proto,
- DescriptorPool::ErrorCollector::NUMBER,
- strings::Substitute("Extension numbers cannot be greater than $0.",
- FieldDescriptor::kMaxNumber));
- }
+ // Checking of the upper bound of the extension range is deferred until after
+ // options interpreting. This allows messages with message_set_wire_format to
+ // have extensions beyond FieldDescriptor::kMaxNumber, since the extension
+ // numbers are actually used as int32s in the message_set_wire_format.
if (result->start >= result->end) {
AddError(parent->full_name(), proto,
@@ -3175,6 +3886,28 @@ void DescriptorBuilder::BuildExtensionRange(
}
}
+void DescriptorBuilder::BuildOneof(const OneofDescriptorProto& proto,
+ Descriptor* parent,
+ OneofDescriptor* result) {
+ string* full_name = tables_->AllocateString(parent->full_name());
+ full_name->append(1, '.');
+ full_name->append(proto.name());
+
+ ValidateSymbolName(proto.name(), *full_name, proto);
+
+ result->name_ = tables_->AllocateString(proto.name());
+ result->full_name_ = full_name;
+
+ result->containing_type_ = parent;
+
+ // We need to fill these in later.
+ result->field_count_ = 0;
+ result->fields_ = NULL;
+
+ AddSymbol(result->full_name(), parent, result->name(),
+ proto, Symbol(result));
+}
+
void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto,
const Descriptor* parent,
EnumDescriptor* result) {
@@ -3283,7 +4016,7 @@ void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto,
}
void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto,
- const void* dummy,
+ const void* /* dummy */,
ServiceDescriptor* result) {
string* full_name = tables_->AllocateString(file_->package());
if (!full_name->empty()) full_name->append(1, '.');
@@ -3384,6 +4117,46 @@ void DescriptorBuilder::CrossLinkMessage(
for (int i = 0; i < message->extension_count(); i++) {
CrossLinkField(&message->extensions_[i], proto.extension(i));
}
+
+ // Set up field array for each oneof.
+
+ // First count the number of fields per oneof.
+ for (int i = 0; i < message->field_count(); i++) {
+ const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof();
+ if (oneof_decl != NULL) {
+ // Must go through oneof_decls_ array to get a non-const version of the
+ // OneofDescriptor.
+ ++message->oneof_decls_[oneof_decl->index()].field_count_;
+ }
+ }
+
+ // Then allocate the arrays.
+ for (int i = 0; i < message->oneof_decl_count(); i++) {
+ OneofDescriptor* oneof_decl = &message->oneof_decls_[i];
+
+ if (oneof_decl->field_count() == 0) {
+ AddError(message->full_name() + "." + oneof_decl->name(),
+ proto.oneof_decl(i),
+ DescriptorPool::ErrorCollector::NAME,
+ "Oneof must have at least one field.");
+ }
+
+ oneof_decl->fields_ =
+ tables_->AllocateArray<const FieldDescriptor*>(oneof_decl->field_count_);
+ oneof_decl->field_count_ = 0;
+ }
+
+ // Then fill them in.
+ for (int i = 0; i < message->field_count(); i++) {
+ const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof();
+ if (oneof_decl != NULL) {
+ OneofDescriptor* mutable_oneof_decl =
+ &message->oneof_decls_[oneof_decl->index()];
+ message->fields_[i].index_in_oneof_ = mutable_oneof_decl->field_count_;
+ mutable_oneof_decl->fields_[mutable_oneof_decl->field_count_++] =
+ message->field(i);
+ }
+ }
}
void DescriptorBuilder::CrossLinkField(
@@ -3408,7 +4181,10 @@ void DescriptorBuilder::CrossLinkField(
}
field->containing_type_ = extendee.descriptor;
- if (!field->containing_type()->IsExtensionNumber(field->number())) {
+ const Descriptor::ExtensionRange* extension_range = field->containing_type()
+ ->FindExtensionRangeContainingNumber(field->number());
+
+ if (extension_range == NULL) {
AddError(field->full_name(), proto,
DescriptorPool::ErrorCollector::NUMBER,
strings::Substitute("\"$0\" does not declare $1 as an "
@@ -3418,6 +4194,17 @@ void DescriptorBuilder::CrossLinkField(
}
}
+ if (field->containing_oneof() != NULL) {
+ if (field->label() != FieldDescriptor::LABEL_OPTIONAL) {
+ // Note that this error will never happen when parsing .proto files.
+ // It can only happen if you manually construct a FileDescriptorProto
+ // that is incorrect.
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::NAME,
+ "Fields of oneofs must themselves have label LABEL_OPTIONAL.");
+ }
+ }
+
if (proto.has_type_name()) {
// Assume we are expecting a message type unless the proto contains some
// evidence that it expects an enum type. This only makes a difference if
@@ -3430,6 +4217,11 @@ void DescriptorBuilder::CrossLinkField(
expecting_enum ? PLACEHOLDER_ENUM : PLACEHOLDER_MESSAGE,
LOOKUP_TYPES);
+ // If the type is a weak type, we change the type to a google.protobuf.Empty field.
+ if (type.IsNull() && !pool_->enforce_weak_ && proto.options().weak()) {
+ type = FindSymbol(kNonLinkedWeakMessageReplacementName);
+ }
+
if (type.IsNull()) {
AddNotDefinedError(field->full_name(), proto,
DescriptorPool::ErrorCollector::TYPE,
@@ -3481,21 +4273,34 @@ void DescriptorBuilder::CrossLinkField(
}
if (field->has_default_value()) {
- // We can't just use field->enum_type()->FindValueByName() here
- // because that locks the pool's mutex, which we have already locked
- // at this point.
- Symbol default_value =
- LookupSymbolNoPlaceholder(proto.default_value(),
- field->enum_type()->full_name());
-
- if (default_value.type == Symbol::ENUM_VALUE &&
- default_value.enum_value_descriptor->type() == field->enum_type()) {
- field->default_value_enum_ = default_value.enum_value_descriptor;
- } else {
+ // Ensure that the default value is an identifier. Parser cannot always
+ // verify this because it does not have complete type information.
+ // N.B. that this check yields better error messages but is not
+ // necessary for correctness (an enum symbol must be a valid identifier
+ // anyway), only for better errors.
+ if (!io::Tokenizer::IsIdentifier(proto.default_value())) {
AddError(field->full_name(), proto,
DescriptorPool::ErrorCollector::DEFAULT_VALUE,
- "Enum type \"" + field->enum_type()->full_name() +
- "\" has no value named \"" + proto.default_value() + "\".");
+ "Default value for an enum field must be an identifier.");
+ } else {
+ // We can't just use field->enum_type()->FindValueByName() here
+ // because that locks the pool's mutex, which we have already locked
+ // at this point.
+ Symbol default_value =
+ LookupSymbolNoPlaceholder(proto.default_value(),
+ field->enum_type()->full_name());
+
+ if (default_value.type == Symbol::ENUM_VALUE &&
+ default_value.enum_value_descriptor->type() ==
+ field->enum_type()) {
+ field->default_value_enum_ = default_value.enum_value_descriptor;
+ } else {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+ "Enum type \"" + field->enum_type()->full_name() +
+ "\" has no value named \"" + proto.default_value() +
+ "\".");
+ }
}
} else if (field->enum_type()->value_count() > 0) {
// All enums must have at least one value, or we would have reported
@@ -3539,12 +4344,26 @@ void DescriptorBuilder::CrossLinkField(
field->containing_type()->full_name(),
conflicting_field->name()));
}
- }
-
- if (field->is_extension()) {
- // No need for error checking: if the extension number collided,
- // we've already been informed of it by the if() above.
- tables_->AddExtension(field);
+ } else {
+ if (field->is_extension()) {
+ if (!tables_->AddExtension(field)) {
+ const FieldDescriptor* conflicting_field =
+ tables_->FindExtension(field->containing_type(), field->number());
+ string error_msg = strings::Substitute(
+ "Extension number $0 has already been used in \"$1\" by extension "
+ "\"$2\" defined in $3.",
+ field->number(),
+ field->containing_type()->full_name(),
+ conflicting_field->full_name(),
+ conflicting_field->file()->name());
+ // Conflicting extension numbers should be an error. However, before
+ // turning this into an error we need to fix all existing broken
+ // protos first.
+ // TODO(xiaofeng): Change this to an error.
+ AddWarning(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::NUMBER, error_msg);
+ }
+ }
}
// Add the field to the lowercase-name and camelcase-name tables.
@@ -3563,7 +4382,8 @@ void DescriptorBuilder::CrossLinkEnum(
}
void DescriptorBuilder::CrossLinkEnumValue(
- EnumValueDescriptor* enum_value, const EnumValueDescriptorProto& proto) {
+ EnumValueDescriptor* enum_value,
+ const EnumValueDescriptorProto& /* proto */) {
if (enum_value->options_ == NULL) {
enum_value->options_ = &EnumValueOptions::default_instance();
}
@@ -3627,7 +4447,6 @@ static bool IsLite(const FileDescriptor* file) {
// TODO(kenton): I don't even remember how many of these conditions are
// actually possible. I'm just being super-safe.
return file != NULL &&
- &file->options() != NULL &&
&file->options() != &FileOptions::default_instance() &&
file->options().optimize_for() == FileOptions::LITE_RUNTIME;
}
@@ -3655,12 +4474,27 @@ void DescriptorBuilder::ValidateFileOptions(FileDescriptor* file,
}
}
+
void DescriptorBuilder::ValidateMessageOptions(Descriptor* message,
const DescriptorProto& proto) {
VALIDATE_OPTIONS_FROM_ARRAY(message, field, Field);
VALIDATE_OPTIONS_FROM_ARRAY(message, nested_type, Message);
VALIDATE_OPTIONS_FROM_ARRAY(message, enum_type, Enum);
VALIDATE_OPTIONS_FROM_ARRAY(message, extension, Field);
+
+ const int64 max_extension_range =
+ static_cast<int64>(message->options().message_set_wire_format() ?
+ kint32max :
+ FieldDescriptor::kMaxNumber);
+ for (int i = 0; i < message->extension_range_count(); ++i) {
+ if (message->extension_range(i)->end > max_extension_range + 1) {
+ AddError(
+ message->full_name(), proto.extension_range(i),
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("Extension numbers cannot be greater than $0.",
+ max_extension_range));
+ }
+ }
}
void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field,
@@ -3669,6 +4503,15 @@ void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field,
ValidateMapKey(field, proto);
}
+ // Only message type fields may be lazy.
+ if (field->options().lazy()) {
+ if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::TYPE,
+ "[lazy = true] can only be specified for submessage fields.");
+ }
+ }
+
// Only repeated primitive fields may be packed.
if (field->options().packed() && !field->is_packable()) {
AddError(
@@ -3707,30 +4550,61 @@ void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field,
"files. Note that you cannot extend a non-lite type to contain "
"a lite type, but the reverse is allowed.");
}
+
}
void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm,
const EnumDescriptorProto& proto) {
VALIDATE_OPTIONS_FROM_ARRAY(enm, value, EnumValue);
+ if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) {
+ map<int, string> used_values;
+ for (int i = 0; i < enm->value_count(); ++i) {
+ const EnumValueDescriptor* enum_value = enm->value(i);
+ if (used_values.find(enum_value->number()) != used_values.end()) {
+ string error =
+ "\"" + enum_value->full_name() +
+ "\" uses the same enum value as \"" +
+ used_values[enum_value->number()] + "\". If this is intended, set "
+ "'option allow_alias = true;' to the enum definition.";
+ if (!enm->options().allow_alias()) {
+ // Generate error if duplicated enum values are explicitly disallowed.
+ AddError(enm->full_name(), proto,
+ DescriptorPool::ErrorCollector::NUMBER,
+ error);
+ } else {
+ // Generate warning if duplicated values are found but the option
+ // isn't set.
+ GOOGLE_LOG(ERROR) << error;
+ }
+ } else {
+ used_values[enum_value->number()] = enum_value->full_name();
+ }
+ }
+ }
}
void DescriptorBuilder::ValidateEnumValueOptions(
- EnumValueDescriptor* enum_value, const EnumValueDescriptorProto& proto) {
+ EnumValueDescriptor* /* enum_value */,
+ const EnumValueDescriptorProto& /* proto */) {
// Nothing to do so far.
}
void DescriptorBuilder::ValidateServiceOptions(ServiceDescriptor* service,
const ServiceDescriptorProto& proto) {
- if (IsLite(service->file())) {
+ if (IsLite(service->file()) &&
+ (service->file()->options().cc_generic_services() ||
+ service->file()->options().java_generic_services())) {
AddError(service->full_name(), proto,
DescriptorPool::ErrorCollector::NAME,
- "Files with optimize_for = LITE_RUNTIME cannot define services.");
+ "Files with optimize_for = LITE_RUNTIME cannot define services "
+ "unless you set both options cc_generic_services and "
+ "java_generic_sevices to false.");
}
VALIDATE_OPTIONS_FROM_ARRAY(service, method, Method);
}
-void DescriptorBuilder::ValidateMethodOptions(MethodDescriptor* method,
- const MethodDescriptorProto& proto) {
+void DescriptorBuilder::ValidateMethodOptions(MethodDescriptor* /* method */,
+ const MethodDescriptorProto& /* proto */) {
// Nothing to do so far.
}
@@ -3787,6 +4661,7 @@ void DescriptorBuilder::ValidateMapKey(FieldDescriptor* field,
field->experimental_map_key_ = key_field;
}
+
#undef VALIDATE_OPTIONS_FROM_ARRAY
// -------------------------------------------------------------------
@@ -3877,9 +4752,11 @@ bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
// file we're currently building. The descriptor should be there as long as
// the file we're building imported "google/protobuf/descriptors.proto".
- // Note that we use DescriptorBuilder::FindSymbol(), not
+ // Note that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not
// DescriptorPool::FindMessageTypeByName() because we're already holding the
- // pool's mutex, and the latter method locks it again.
+ // pool's mutex, and the latter method locks it again. We don't use
+ // FindSymbol() because files that use custom options only need to depend on
+ // the file that defines the option, not descriptor.proto itself.
Symbol symbol = builder_->FindSymbolNotEnforcingDeps(
options->GetDescriptor()->full_name());
if (!symbol.IsNull() && symbol.type == Symbol::MESSAGE) {
@@ -3915,8 +4792,8 @@ bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
// DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows
// relative lookups, and 2) because we're already holding the pool's
// mutex, and the latter method locks it again.
- Symbol symbol = builder_->LookupSymbol(name_part,
- options_to_interpret_->name_scope);
+ symbol = builder_->LookupSymbol(name_part,
+ options_to_interpret_->name_scope);
if (!symbol.IsNull() && symbol.type == Symbol::FIELD) {
field = symbol.field_descriptor;
}
@@ -3936,6 +4813,15 @@ bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
// so we will just leave it as uninterpreted.
AddWithoutInterpreting(*uninterpreted_option_, options);
return true;
+ } else if (!(builder_->undefine_resolved_name_).empty()) {
+ // Option is resolved to a name which is not defined.
+ return AddNameError(
+ "Option \"" + debug_msg_name + "\" is resolved to \"(" +
+ builder_->undefine_resolved_name_ +
+ ")\", which is not defined. The innermost scope is searched first "
+ "in name resolution. Consider using a leading '.'(i.e., \"(." +
+ debug_msg_name.substr(1) +
+ "\") to start from the outermost scope.");
} else {
return AddNameError("Option \"" + debug_msg_name + "\" unknown.");
}
@@ -3956,22 +4842,20 @@ bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
"\" is not a field or extension of message \"" +
descriptor->name() + "\".");
}
- } else if (field->is_repeated()) {
- return AddNameError("Option field \"" + debug_msg_name +
- "\" is repeated. Repeated options are not "
- "supported.");
} else if (i < uninterpreted_option_->name_size() - 1) {
if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
return AddNameError("Option \"" + debug_msg_name +
"\" is an atomic type, not a message.");
+ } else if (field->is_repeated()) {
+ return AddNameError("Option field \"" + debug_msg_name +
+ "\" is a repeated message. Repeated message "
+ "options must be initialized using an "
+ "aggregate value.");
} else {
// Drill down into the submessage.
intermediate_fields.push_back(field);
descriptor = field->message_type();
}
- } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- return AddNameError("Option field \"" + debug_msg_name +
- "\" cannot be of message type.");
}
}
@@ -3983,7 +4867,7 @@ bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
// known will populate them correctly.
// First see if the option is already set.
- if (!ExamineIfOptionIsSet(
+ if (!field->is_repeated() && !ExamineIfOptionIsSet(
intermediate_fields.begin(),
intermediate_fields.end(),
field, debug_msg_name,
@@ -4306,18 +5190,119 @@ bool DescriptorBuilder::OptionInterpreter::SetOptionValue(
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
- // We don't currently support defining a message-typed option, so we
- // should never actually get here.
- return AddValueError("Option \"" + option_field->full_name() +
- "\" is a message. To set fields within it, use "
- "syntax like \"" + option_field->name() +
- ".foo = value\".");
+ if (!SetAggregateOption(option_field, unknown_fields)) {
+ return false;
+ }
break;
}
return true;
}
+class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder
+ : public TextFormat::Finder {
+ public:
+ DescriptorBuilder* builder_;
+
+ virtual const FieldDescriptor* FindExtension(
+ Message* message, const string& name) const {
+ assert_mutex_held(builder_->pool_);
+ const Descriptor* descriptor = message->GetDescriptor();
+ Symbol result = builder_->LookupSymbolNoPlaceholder(
+ name, descriptor->full_name());
+ if (result.type == Symbol::FIELD &&
+ result.field_descriptor->is_extension()) {
+ return result.field_descriptor;
+ } else if (result.type == Symbol::MESSAGE &&
+ descriptor->options().message_set_wire_format()) {
+ const Descriptor* foreign_type = result.descriptor;
+ // The text format allows MessageSet items to be specified using
+ // the type name, rather than the extension identifier. If the symbol
+ // lookup returned a Message, and the enclosing Message has
+ // message_set_wire_format = true, then return the message set
+ // extension, if one exists.
+ for (int i = 0; i < foreign_type->extension_count(); i++) {
+ const FieldDescriptor* extension = foreign_type->extension(i);
+ if (extension->containing_type() == descriptor &&
+ extension->type() == FieldDescriptor::TYPE_MESSAGE &&
+ extension->is_optional() &&
+ extension->message_type() == foreign_type) {
+ // Found it.
+ return extension;
+ }
+ }
+ }
+ return NULL;
+ }
+};
+
+// A custom error collector to record any text-format parsing errors
+namespace {
+class AggregateErrorCollector : public io::ErrorCollector {
+ public:
+ string error_;
+
+ virtual void AddError(int /* line */, int /* column */,
+ const string& message) {
+ if (!error_.empty()) {
+ error_ += "; ";
+ }
+ error_ += message;
+ }
+
+ virtual void AddWarning(int /* line */, int /* column */,
+ const string& /* message */) {
+ // Ignore warnings
+ }
+};
+}
+
+// We construct a dynamic message of the type corresponding to
+// option_field, parse the supplied text-format string into this
+// message, and serialize the resulting message to produce the value.
+bool DescriptorBuilder::OptionInterpreter::SetAggregateOption(
+ const FieldDescriptor* option_field,
+ UnknownFieldSet* unknown_fields) {
+ if (!uninterpreted_option_->has_aggregate_value()) {
+ return AddValueError("Option \"" + option_field->full_name() +
+ "\" is a message. To set the entire message, use "
+ "syntax like \"" + option_field->name() +
+ " = { <proto text format> }\". "
+ "To set fields within it, use "
+ "syntax like \"" + option_field->name() +
+ ".foo = value\".");
+ }
+
+ const Descriptor* type = option_field->message_type();
+ scoped_ptr<Message> dynamic(dynamic_factory_.GetPrototype(type)->New());
+ GOOGLE_CHECK(dynamic.get() != NULL)
+ << "Could not create an instance of " << option_field->DebugString();
+
+ AggregateErrorCollector collector;
+ AggregateOptionFinder finder;
+ finder.builder_ = builder_;
+ TextFormat::Parser parser;
+ parser.RecordErrorsTo(&collector);
+ parser.SetFinder(&finder);
+ if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(),
+ dynamic.get())) {
+ AddValueError("Error while parsing option value for \"" +
+ option_field->name() + "\": " + collector.error_);
+ return false;
+ } else {
+ string serial;
+ dynamic->SerializeToString(&serial); // Never fails
+ if (option_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ unknown_fields->AddLengthDelimited(option_field->number(), serial);
+ } else {
+ GOOGLE_CHECK_EQ(option_field->type(), FieldDescriptor::TYPE_GROUP);
+ UnknownFieldSet* group = unknown_fields->AddGroup(option_field->number());
+ group->ParseFromString(serial);
+ }
+ return true;
+ }
+}
+
void DescriptorBuilder::OptionInterpreter::SetInt32(int number, int32 value,
FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
switch (type) {
@@ -4397,5 +5382,39 @@ void DescriptorBuilder::OptionInterpreter::SetUInt64(int number, uint64 value,
}
}
+void DescriptorBuilder::LogUnusedDependency(const FileDescriptor* result) {
+
+ if (!unused_dependency_.empty()) {
+ std::set<string> annotation_extensions;
+ annotation_extensions.insert("google.protobuf.MessageOptions");
+ annotation_extensions.insert("google.protobuf.FileOptions");
+ annotation_extensions.insert("google.protobuf.FieldOptions");
+ annotation_extensions.insert("google.protobuf.EnumOptions");
+ annotation_extensions.insert("google.protobuf.EnumValueOptions");
+ annotation_extensions.insert("google.protobuf.ServiceOptions");
+ annotation_extensions.insert("google.protobuf.MethodOptions");
+ annotation_extensions.insert("google.protobuf.StreamOptions");
+ for (set<const FileDescriptor*>::const_iterator
+ it = unused_dependency_.begin();
+ it != unused_dependency_.end(); ++it) {
+ // Do not log warnings for proto files which extend annotations.
+ int i;
+ for (i = 0 ; i < (*it)->extension_count(); ++i) {
+ if (annotation_extensions.find(
+ (*it)->extension(i)->containing_type()->full_name())
+ != annotation_extensions.end()) {
+ break;
+ }
+ }
+ // 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.";
+ }
+ }
+ }
+}
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h
index 7f87dd8..361943d 100644
--- a/src/google/protobuf/descriptor.h
+++ b/src/google/protobuf/descriptor.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -54,6 +54,7 @@
#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__
#define GOOGLE_PROTOBUF_DESCRIPTOR_H__
+#include <set>
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
@@ -65,6 +66,7 @@ namespace protobuf {
// Defined in this file.
class Descriptor;
class FieldDescriptor;
+class OneofDescriptor;
class EnumDescriptor;
class EnumValueDescriptor;
class ServiceDescriptor;
@@ -76,6 +78,7 @@ class DescriptorPool;
// Defined in descriptor.proto
class DescriptorProto;
class FieldDescriptorProto;
+class OneofDescriptorProto;
class EnumDescriptorProto;
class EnumValueDescriptorProto;
class ServiceDescriptorProto;
@@ -89,6 +92,7 @@ class ServiceOptions;
class MethodOptions;
class FileOptions;
class UninterpretedOption;
+class SourceCodeInfo;
// Defined in message.h
class Message;
@@ -100,6 +104,20 @@ class FileDescriptorTables;
// Defined in unknown_field_set.h.
class UnknownField;
+// NB, all indices are zero-based.
+struct SourceLocation {
+ int start_line;
+ int end_line;
+ int start_column;
+ int end_column;
+
+ // Doc comments found at the source location.
+ // TODO(kenton): Maybe this struct should have been named SourceInfo or
+ // something instead. Oh well.
+ string leading_comments;
+ string trailing_comments;
+};
+
// Describes a type of protocol message, or a particular group within a
// message. To obtain the Descriptor for a given message object, call
// Message::GetDescriptor(). Generated message classes also have a
@@ -144,6 +162,11 @@ class LIBPROTOBUF_EXPORT Descriptor {
// will be suitable for re-parsing.
string DebugString() const;
+ // Returns true if this is a placeholder for an unknown type. This will
+ // only be the case if this descriptor comes from a DescriptorPool
+ // with AllowUnknownDependencies() set.
+ bool is_placeholder() const;
+
// Field stuff -----------------------------------------------------
// The number of fields in this message type.
@@ -171,6 +194,15 @@ class LIBPROTOBUF_EXPORT Descriptor {
const FieldDescriptor* FindFieldByCamelcaseName(
const string& camelcase_name) const;
+ // The number of oneofs in this message type.
+ int oneof_decl_count() const;
+ // Get a oneof by index, where 0 <= index < oneof_decl_count().
+ // These are returned in the order they were defined in the .proto file.
+ const OneofDescriptor* oneof_decl(int index) const;
+
+ // Looks up a oneof by name. Returns NULL if no such oneof exists.
+ const OneofDescriptor* FindOneofByName(const string& name) const;
+
// Nested type stuff -----------------------------------------------
// The number of nested types in this message type.
@@ -217,6 +249,9 @@ class LIBPROTOBUF_EXPORT Descriptor {
// Returns true if the number is in one of the extension ranges.
bool IsExtensionNumber(int number) const;
+ // Returns NULL if no extension range contains the given number.
+ const ExtensionRange* FindExtensionRangeContainingNumber(int number) const;
+
// The number of extensions -- extending *other* messages -- that were
// defined nested within this message type's scope.
int extension_count() const;
@@ -236,6 +271,13 @@ class LIBPROTOBUF_EXPORT Descriptor {
// this message type's scope.
const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const;
+ // Source Location ---------------------------------------------------
+
+ // Updates |*out_location| to the source location of the complete
+ // extent of this message declaration. Returns false and leaves
+ // |*out_location| unchanged iff location information was not available.
+ bool GetSourceLocation(SourceLocation* out_location) const;
+
private:
typedef MessageOptions OptionsType;
@@ -243,6 +285,10 @@ class LIBPROTOBUF_EXPORT Descriptor {
// correct depth
void DebugString(int depth, string *contents) const;
+ // Walks up the descriptor tree to generate the source location path
+ // to this descriptor from the file root.
+ void GetLocationPath(std::vector<int>* output) const;
+
const string* name_;
const string* full_name_;
const FileDescriptor* file_;
@@ -256,6 +302,8 @@ class LIBPROTOBUF_EXPORT Descriptor {
int field_count_;
FieldDescriptor* fields_;
+ int oneof_decl_count_;
+ OneofDescriptor* oneof_decls_;
int nested_type_count_;
Descriptor* nested_types_;
int enum_type_count_;
@@ -273,6 +321,7 @@ class LIBPROTOBUF_EXPORT Descriptor {
friend class DescriptorBuilder;
friend class EnumDescriptor;
friend class FieldDescriptor;
+ friend class OneofDescriptor;
friend class MethodDescriptor;
friend class FileDescriptor;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Descriptor);
@@ -388,15 +437,19 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
// when parsing formats which prefer to use camel-case naming style.
const string& camelcase_name() const;
- Type type() const; // Declared type of this field.
- CppType cpp_type() const; // C++ type of this field.
- Label label() const; // optional/required/repeated
+ Type type() const; // Declared type of this field.
+ const char* type_name() const; // Name of the declared type.
+ CppType cpp_type() const; // C++ type of this field.
+ const char* cpp_type_name() const; // Name of the C++ type.
+ Label label() const; // optional/required/repeated
bool is_required() const; // shorthand for label() == LABEL_REQUIRED
bool is_optional() const; // shorthand for label() == LABEL_OPTIONAL
bool is_repeated() const; // shorthand for label() == LABEL_REPEATED
bool is_packable() const; // shorthand for is_repeated() &&
// IsTypePackable(type())
+ bool is_packed() const; // shorthand for is_packable() &&
+ // options().packed()
// Index of this field within the message's field array, or the file or
// extension scope's extensions array.
@@ -439,6 +492,13 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
// this is the extended type. Never NULL.
const Descriptor* containing_type() const;
+ // If the field is a member of a oneof, this is the one, otherwise this is
+ // NULL.
+ const OneofDescriptor* containing_oneof() const;
+
+ // If the field is a member of a oneof, returns the index in that oneof.
+ int index_in_oneof() const;
+
// An extension may be declared within the scope of another message. If this
// field is an extension (is_extension() is true), then extension_scope()
// returns that message, or NULL if the extension was declared at global
@@ -447,10 +507,10 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
const Descriptor* extension_scope() const;
// If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the
- // message or the group type. Otherwise, undefined.
+ // message or the group type. Otherwise, returns null.
const Descriptor* message_type() const;
// If type is TYPE_ENUM, returns a descriptor for the enum. Otherwise,
- // undefined.
+ // returns null.
const EnumDescriptor* enum_type() const;
// EXPERIMENTAL; DO NOT USE.
@@ -476,20 +536,39 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
// Helper method to get the CppType for a particular Type.
static CppType TypeToCppType(Type type);
+ // Helper method to get the name of a Type.
+ static const char* TypeName(Type type);
+
+ // Helper method to get the name of a CppType.
+ static const char* CppTypeName(CppType cpp_type);
+
// Return true iff [packed = true] is valid for fields of this type.
static inline bool IsTypePackable(Type field_type);
+ // Source Location ---------------------------------------------------
+
+ // Updates |*out_location| to the source location of the complete
+ // extent of this field declaration. Returns false and leaves
+ // |*out_location| unchanged iff location information was not available.
+ bool GetSourceLocation(SourceLocation* out_location) const;
+
private:
typedef FieldOptions OptionsType;
// See Descriptor::DebugString().
- void DebugString(int depth, string *contents) const;
+ enum PrintLabelFlag { PRINT_LABEL, OMIT_LABEL };
+ void DebugString(int depth, PrintLabelFlag print_label_flag,
+ string* contents) const;
// formats the default value appropriately and returns it as a string.
// Must have a default value to call this. If quote_string_type is true, then
// types of CPPTYPE_STRING whill be surrounded by quotes and CEscaped.
string DefaultValueAsString(bool quote_string_type) const;
+ // Walks up the descriptor tree to generate the source location path
+ // to this descriptor from the file root.
+ void GetLocationPath(std::vector<int>* output) const;
+
const string* name_;
const string* full_name_;
const string* lowercase_name_;
@@ -499,7 +578,9 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
Type type_;
Label label_;
bool is_extension_;
+ int index_in_oneof_;
const Descriptor* containing_type_;
+ const OneofDescriptor* containing_oneof_;
const Descriptor* extension_scope_;
const Descriptor* message_type_;
const EnumDescriptor* enum_type_;
@@ -527,6 +608,8 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
static const char * const kTypeToName[MAX_TYPE + 1];
+ static const char * const kCppTypeToName[MAX_CPPTYPE + 1];
+
static const char * const kLabelToName[MAX_LABEL + 1];
// Must be constructed using DescriptorPool.
@@ -534,9 +617,66 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
friend class DescriptorBuilder;
friend class FileDescriptor;
friend class Descriptor;
+ friend class OneofDescriptor;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldDescriptor);
};
+// Describes a oneof defined in a message type.
+class LIBPROTOBUF_EXPORT OneofDescriptor {
+ public:
+ const string& name() const; // Name of this oneof.
+ const string& full_name() const; // Fully-qualified name of the oneof.
+
+ // Index of this oneof within the message's oneof array.
+ int index() const;
+
+ // The Descriptor for the message containing this oneof.
+ const Descriptor* containing_type() const;
+
+ // The number of (non-extension) fields which are members of this oneof.
+ int field_count() const;
+ // Get a member of this oneof, in the order in which they were declared in the
+ // .proto file. Does not include extensions.
+ const FieldDescriptor* field(int index) const;
+
+ // See Descriptor::CopyTo().
+ void CopyTo(OneofDescriptorProto* proto) const;
+
+ // See Descriptor::DebugString().
+ string DebugString() const;
+
+ // Source Location ---------------------------------------------------
+
+ // Updates |*out_location| to the source location of the complete
+ // extent of this oneof declaration. Returns false and leaves
+ // |*out_location| unchanged iff location information was not available.
+ bool GetSourceLocation(SourceLocation* out_location) const;
+
+ private:
+ // See Descriptor::DebugString().
+ void DebugString(int depth, string* contents) const;
+
+ // Walks up the descriptor tree to generate the source location path
+ // to this descriptor from the file root.
+ void GetLocationPath(std::vector<int>* output) const;
+
+ const string* name_;
+ const string* full_name_;
+ const Descriptor* containing_type_;
+ bool is_extendable_;
+ int field_count_;
+ const FieldDescriptor** fields_;
+ // 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.
+
+ // Must be constructed using DescriptorPool.
+ OneofDescriptor() {}
+ friend class DescriptorBuilder;
+ friend class Descriptor;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OneofDescriptor);
+};
+
// Describes an enum type defined in a .proto file. To get the EnumDescriptor
// for a generated enum type, call TypeName_descriptor(). Use DescriptorPool
// to construct your own descriptors.
@@ -583,12 +723,28 @@ class LIBPROTOBUF_EXPORT EnumDescriptor {
// See Descriptor::DebugString().
string DebugString() const;
+ // Returns true if this is a placeholder for an unknown enum. This will
+ // only be the case if this descriptor comes from a DescriptorPool
+ // with AllowUnknownDependencies() set.
+ bool is_placeholder() const;
+
+ // Source Location ---------------------------------------------------
+
+ // Updates |*out_location| to the source location of the complete
+ // extent of this enum declaration. Returns false and leaves
+ // |*out_location| unchanged iff location information was not available.
+ bool GetSourceLocation(SourceLocation* out_location) const;
+
private:
typedef EnumOptions OptionsType;
// See Descriptor::DebugString().
void DebugString(int depth, string *contents) const;
+ // Walks up the descriptor tree to generate the source location path
+ // to this descriptor from the file root.
+ void GetLocationPath(std::vector<int>* output) const;
+
const string* name_;
const string* full_name_;
const FileDescriptor* file_;
@@ -650,12 +806,23 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptor {
// See Descriptor::DebugString().
string DebugString() const;
+ // Source Location ---------------------------------------------------
+
+ // Updates |*out_location| to the source location of the complete
+ // extent of this enum value declaration. Returns false and leaves
+ // |*out_location| unchanged iff location information was not available.
+ bool GetSourceLocation(SourceLocation* out_location) const;
+
private:
typedef EnumValueOptions OptionsType;
// See Descriptor::DebugString().
void DebugString(int depth, string *contents) const;
+ // Walks up the descriptor tree to generate the source location path
+ // to this descriptor from the file root.
+ void GetLocationPath(std::vector<int>* output) const;
+
const string* name_;
const string* full_name_;
int number_;
@@ -703,19 +870,29 @@ class LIBPROTOBUF_EXPORT ServiceDescriptor {
// Look up a MethodDescriptor by name.
const MethodDescriptor* FindMethodByName(const string& name) const;
-
// See Descriptor::CopyTo().
void CopyTo(ServiceDescriptorProto* proto) const;
// See Descriptor::DebugString().
string DebugString() const;
+ // Source Location ---------------------------------------------------
+
+ // Updates |*out_location| to the source location of the complete
+ // extent of this service declaration. Returns false and leaves
+ // |*out_location| unchanged iff location information was not available.
+ bool GetSourceLocation(SourceLocation* out_location) const;
+
private:
typedef ServiceOptions OptionsType;
// See Descriptor::DebugString().
void DebugString(string *contents) const;
+ // Walks up the descriptor tree to generate the source location path
+ // to this descriptor from the file root.
+ void GetLocationPath(std::vector<int>* output) const;
+
const string* name_;
const string* full_name_;
const FileDescriptor* file_;
@@ -768,12 +945,23 @@ class LIBPROTOBUF_EXPORT MethodDescriptor {
// See Descriptor::DebugString().
string DebugString() const;
+ // Source Location ---------------------------------------------------
+
+ // Updates |*out_location| to the source location of the complete
+ // extent of this method declaration. Returns false and leaves
+ // |*out_location| unchanged iff location information was not available.
+ bool GetSourceLocation(SourceLocation* out_location) const;
+
private:
typedef MethodOptions OptionsType;
// See Descriptor::DebugString().
void DebugString(int depth, string *contents) const;
+ // Walks up the descriptor tree to generate the source location path
+ // to this descriptor from the file root.
+ void GetLocationPath(std::vector<int>* output) const;
+
const string* name_;
const string* full_name_;
const ServiceDescriptor* service_;
@@ -791,6 +979,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptor {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MethodDescriptor);
};
+
// Describes a whole .proto file. To get the FileDescriptor for a compiled-in
// file, get the descriptor for something defined in that file and call
// descriptor->file(). Use DescriptorPool to construct your own descriptors.
@@ -813,6 +1002,22 @@ class LIBPROTOBUF_EXPORT FileDescriptor {
// These are returned in the order they were defined in the .proto file.
const FileDescriptor* dependency(int index) const;
+ // The number of files public imported by this one.
+ // The public dependency list is a subset of the dependency list.
+ int public_dependency_count() const;
+ // Gets a public imported file by index, where 0 <= index <
+ // public_dependency_count().
+ // These are returned in the order they were defined in the .proto file.
+ const FileDescriptor* public_dependency(int index) const;
+
+ // The number of files that are imported for weak fields.
+ // The weak dependency list is a subset of the dependency list.
+ int weak_dependency_count() const;
+ // Gets a weak imported file by index, where 0 <= index <
+ // weak_dependency_count().
+ // These are returned in the order they were defined in the .proto file.
+ const FileDescriptor* weak_dependency(int index) const;
+
// Number of top-level message types defined in this file. (This does not
// include nested types.)
int message_type_count() const;
@@ -866,12 +1071,33 @@ class LIBPROTOBUF_EXPORT FileDescriptor {
const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const;
// See Descriptor::CopyTo().
+ // Notes:
+ // - This method does NOT copy source code information since it is relatively
+ // large and rarely needed. See CopySourceCodeInfoTo() below.
void CopyTo(FileDescriptorProto* proto) const;
+ // Write the source code information of this FileDescriptor into the given
+ // FileDescriptorProto. See CopyTo() above.
+ void CopySourceCodeInfoTo(FileDescriptorProto* proto) const;
// See Descriptor::DebugString().
string DebugString() const;
+ // Returns true if this is a placeholder for an unknown file. This will
+ // only be the case if this descriptor comes from a DescriptorPool
+ // with AllowUnknownDependencies() set.
+ bool is_placeholder() const;
+
private:
+ // Source Location ---------------------------------------------------
+
+ // Updates |*out_location| to the source location of the complete
+ // extent of the declaration or declaration-part denoted by |path|.
+ // Returns false and leaves |*out_location| unchanged iff location
+ // information was not available. (See SourceCodeInfo for
+ // description of path encoding.)
+ bool GetSourceLocation(const std::vector<int>& path,
+ SourceLocation* out_location) const;
+
typedef FileOptions OptionsType;
const string* name_;
@@ -879,6 +1105,10 @@ class LIBPROTOBUF_EXPORT FileDescriptor {
const DescriptorPool* pool_;
int dependency_count_;
const FileDescriptor** dependencies_;
+ int public_dependency_count_;
+ int* public_dependencies_;
+ int weak_dependency_count_;
+ int* weak_dependencies_;
int message_type_count_;
Descriptor* message_types_;
int enum_type_count_;
@@ -886,10 +1116,12 @@ class LIBPROTOBUF_EXPORT FileDescriptor {
int service_count_;
ServiceDescriptor* services_;
int extension_count_;
+ bool is_placeholder_;
FieldDescriptor* extensions_;
const FileOptions* options_;
const FileDescriptorTables* tables_;
+ const SourceCodeInfo* source_code_info_;
// IMPORTANT: If you add a new field, make sure to search for all instances
// of Allocate<FileDescriptor>() and AllocateArray<FileDescriptor>() in
// descriptor.cc and update them to initialize the field.
@@ -898,7 +1130,10 @@ class LIBPROTOBUF_EXPORT FileDescriptor {
friend class DescriptorBuilder;
friend class Descriptor;
friend class FieldDescriptor;
+ friend class OneofDescriptor;
friend class EnumDescriptor;
+ friend class EnumValueDescriptor;
+ friend class MethodDescriptor;
friend class ServiceDescriptor;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileDescriptor);
};
@@ -953,6 +1188,10 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
// to GOOGLE_LOG(ERROR). Remember that files are built on-demand, so this
// ErrorCollector may be called from any thread that calls one of the
// Find*By*() methods.
+ // - The DescriptorDatabase must not be mutated during the lifetime of
+ // the DescriptorPool. Even if the client takes care to avoid data races,
+ // changes to the content of the DescriptorDatabase may not be reflected
+ // in subsequent lookups in the DescriptorPool.
class ErrorCollector;
explicit DescriptorPool(DescriptorDatabase* fallback_database,
ErrorCollector* error_collector = NULL);
@@ -983,6 +1222,7 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
const Descriptor* FindMessageTypeByName(const string& name) const;
const FieldDescriptor* FindFieldByName(const string& name) const;
const FieldDescriptor* FindExtensionByName(const string& name) const;
+ const OneofDescriptor* FindOneofByName(const string& name) const;
const EnumDescriptor* FindEnumTypeByName(const string& name) const;
const EnumValueDescriptor* FindEnumValueByName(const string& name) const;
const ServiceDescriptor* FindServiceByName(const string& name) const;
@@ -999,7 +1239,7 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
// found: extensions defined in the fallback database might not be found
// depending on the database implementation.
void FindAllExtensions(const Descriptor* extendee,
- vector<const FieldDescriptor*>* out) const;
+ std::vector<const FieldDescriptor*>* out) const;
// Building descriptors --------------------------------------------
@@ -1027,7 +1267,8 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
OTHER // some other problem
};
- // Reports an error in the FileDescriptorProto.
+ // Reports an error in the FileDescriptorProto. Use this function if the
+ // problem occured should interrupt building the FileDescriptorProto.
virtual void AddError(
const string& filename, // File name in which the error occurred.
const string& element_name, // Full name of the erroneous element.
@@ -1036,6 +1277,16 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
const string& message // Human-readable error message.
) = 0;
+ // Reports a warning in the FileDescriptorProto. Use this function if the
+ // problem occured should NOT interrupt building the FileDescriptorProto.
+ virtual void AddWarning(
+ const string& filename, // File name in which the error occurred.
+ const string& element_name, // Full name of the erroneous element.
+ const Message* descriptor, // Descriptor of the erroneous element.
+ ErrorLocation location, // One of the location constants, above.
+ const string& message // Human-readable error message.
+ ) {}
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector);
};
@@ -1056,7 +1307,8 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
// to types or other files that are not found in the DescriptorPool (or its
// backing DescriptorDatabase, if any). If you call
// AllowUnknownDependencies(), however, then unknown types and files
- // will be replaced by placeholder descriptors. This can allow you to
+ // will be replaced by placeholder descriptors (which can be identified by
+ // the is_placeholder() method). This can allow you to
// perform some useful operations with a .proto file even if you do not
// have access to other .proto files on which it depends. However, some
// heuristics must be used to fill in the gaps in information, and these
@@ -1065,10 +1317,15 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
// or an enum, as well as what package it resides in. Furthermore,
// placeholder types will not be discoverable via FindMessageTypeByName()
// and similar methods, which could confuse some descriptor-based algorithms.
- // Generally, the results of this option should only be relied upon for
- // debugging purposes.
+ // Generally, the results of this option should be handled with extreme care.
void AllowUnknownDependencies() { allow_unknown_ = true; }
+ // By default, weak imports are allowed to be missing, in which case we will
+ // use a placeholder for the dependency and convert the field to be an Empty
+ // message field. If you call EnforceWeakDependencies(true), however, the
+ // DescriptorPool will report a import not found error.
+ void EnforceWeakDependencies(bool enforce) { enforce_weak_ = enforce; }
+
// Internal stuff --------------------------------------------------
// These methods MUST NOT be called from outside the proto2 library.
// These methods may contain hidden pitfalls and may be removed in a
@@ -1106,7 +1363,7 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
// For internal use only: Gets a non-const pointer to the generated pool.
// This is called at static-initialization time only, so thread-safety is
// not a concern. If both an underlay and a fallback database are present,
- // the fallback database takes precedence.
+ // the underlay takes precedence.
static DescriptorPool* internal_generated_pool();
// For internal use only: Changes the behavior of BuildFile() such that it
@@ -1124,6 +1381,12 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
// lazy descriptor initialization behavior.
bool InternalIsFileLoaded(const string& filename) const;
+
+ // Add a file to unused_import_track_files_. DescriptorBuilder will log
+ // warnings for those files if there is any unused import.
+ void AddUnusedImportTrackFile(const string& file_name);
+ void ClearUnusedImportTrackFiles();
+
private:
friend class Descriptor;
friend class FieldDescriptor;
@@ -1132,6 +1395,11 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
friend class FileDescriptor;
friend class DescriptorBuilder;
+ // Return true if the given name is a sub-symbol of any non-package
+ // descriptor that already exists in the descriptor pool. (The full
+ // definition of such types is already known.)
+ bool IsSubSymbolOfBuiltType(const string& name) const;
+
// Tries to find something in the fallback database and link in the
// corresponding proto file. Returns true if successful, in which case
// the caller should search for the thing again. These are declared
@@ -1163,6 +1431,8 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
bool enforce_dependencies_;
bool allow_unknown_;
+ bool enforce_weak_;
+ std::set<string> unused_import_track_files_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool);
};
@@ -1190,10 +1460,12 @@ PROTOBUF_DEFINE_ACCESSOR(Descriptor, file, const FileDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, field_count, int)
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, oneof_decl_count, int)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, nested_type_count, int)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, enum_type_count, int)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, field, const FieldDescriptor*)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, oneof_decl, const OneofDescriptor*)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, nested_type, const Descriptor*)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, enum_type, const EnumDescriptor*)
@@ -1204,6 +1476,7 @@ PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension_range,
PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension,
const FieldDescriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions);
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, is_placeholder, bool)
PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, full_name)
@@ -1215,12 +1488,15 @@ PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, type, FieldDescriptor::Type)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, label, FieldDescriptor::Label)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_oneof,
+ const OneofDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, index_in_oneof, int)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, extension_scope, const Descriptor*)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, message_type, const Descriptor*)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, enum_type, const EnumDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, experimental_map_key,
const FieldDescriptor*)
-PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions);
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int32 , int32 )
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64 , int64 )
@@ -1233,6 +1509,11 @@ PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_enum,
const EnumValueDescriptor*)
PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, default_value_string)
+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_STRING_ACCESSOR(EnumDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, full_name)
PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, file, const FileDescriptor*)
@@ -1241,12 +1522,13 @@ PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, value,
const EnumValueDescriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions);
+PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, is_placeholder, bool)
PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, full_name)
PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int)
PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*)
-PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions);
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions)
PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, full_name)
@@ -1262,16 +1544,18 @@ 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_STRING_ACCESSOR(FileDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, package)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, pool, const DescriptorPool*)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, dependency_count, int)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, public_dependency_count, int)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, weak_dependency_count, int)
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_ACCESSOR(FileDescriptor, is_placeholder, bool)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, message_type, const Descriptor*)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, enum_type, const EnumDescriptor*)
@@ -1286,6 +1570,10 @@ PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, extension,
// A few accessors differ from the macros...
+inline bool Descriptor::IsExtensionNumber(int number) const {
+ return FindExtensionRangeContainingNumber(number) != NULL;
+}
+
inline bool FieldDescriptor::is_required() const {
return label() == LABEL_REQUIRED;
}
@@ -1306,50 +1594,70 @@ inline bool FieldDescriptor::is_packable() const {
// in the parent's array of children.
inline int FieldDescriptor::index() const {
if (!is_extension_) {
- return this - containing_type_->fields_;
+ return static_cast<int>(this - containing_type_->fields_);
} else if (extension_scope_ != NULL) {
- return this - extension_scope_->extensions_;
+ return static_cast<int>(this - extension_scope_->extensions_);
} else {
- return this - file_->extensions_;
+ return static_cast<int>(this - file_->extensions_);
}
}
inline int Descriptor::index() const {
if (containing_type_ == NULL) {
- return this - file_->message_types_;
+ return static_cast<int>(this - file_->message_types_);
} else {
- return this - containing_type_->nested_types_;
+ return static_cast<int>(this - containing_type_->nested_types_);
}
}
+inline int OneofDescriptor::index() const {
+ return static_cast<int>(this - containing_type_->oneof_decls_);
+}
+
inline int EnumDescriptor::index() const {
if (containing_type_ == NULL) {
- return this - file_->enum_types_;
+ return static_cast<int>(this - file_->enum_types_);
} else {
- return this - containing_type_->enum_types_;
+ return static_cast<int>(this - containing_type_->enum_types_);
}
}
inline int EnumValueDescriptor::index() const {
- return this - type_->values_;
+ return static_cast<int>(this - type_->values_);
}
inline int ServiceDescriptor::index() const {
- return this - file_->services_;
+ return static_cast<int>(this - file_->services_);
}
inline int MethodDescriptor::index() const {
- return this - service_->methods_;
+ return static_cast<int>(this - service_->methods_);
+}
+
+inline const char* FieldDescriptor::type_name() const {
+ return kTypeToName[type_];
}
inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const {
return kTypeToCppTypeMap[type_];
}
+inline const char* FieldDescriptor::cpp_type_name() const {
+ return kCppTypeToName[kTypeToCppTypeMap[type_]];
+}
+
inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) {
return kTypeToCppTypeMap[type];
}
+inline const char* FieldDescriptor::TypeName(Type type) {
+ return kTypeToName[type];
+}
+
+inline const char* FieldDescriptor::CppTypeName(CppType cpp_type) {
+ return kCppTypeToName[cpp_type];
+}
+
inline bool FieldDescriptor::IsTypePackable(Type field_type) {
return (field_type != FieldDescriptor::TYPE_STRING &&
field_type != FieldDescriptor::TYPE_GROUP &&
@@ -1361,6 +1669,22 @@ inline const FileDescriptor* FileDescriptor::dependency(int index) const {
return dependencies_[index];
}
+inline const FileDescriptor* FileDescriptor::public_dependency(
+ int index) const {
+ return dependencies_[public_dependencies_[index]];
+}
+
+inline const FileDescriptor* FileDescriptor::weak_dependency(
+ int index) const {
+ return dependencies_[weak_dependencies_[index]];
+}
+
+// Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because fields_ is actually an array
+// of pointers rather than the usual array of objects.
+inline const FieldDescriptor* OneofDescriptor::field(int index) const {
+ return fields_[index];
+}
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index f61e7cd..c3aa2fb 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -1,11 +1,17 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/descriptor.proto
#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
#include "google/protobuf/descriptor.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// @@protoc_insertion_point(includes)
@@ -32,6 +38,9 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
FieldDescriptorProto_reflection_ = NULL;
const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor_ = NULL;
const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* OneofDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ OneofDescriptorProto_reflection_ = NULL;
const ::google::protobuf::Descriptor* EnumDescriptorProto_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
EnumDescriptorProto_reflection_ = NULL;
@@ -73,6 +82,12 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
const ::google::protobuf::Descriptor* UninterpretedOption_NamePart_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
UninterpretedOption_NamePart_reflection_ = NULL;
+const ::google::protobuf::Descriptor* SourceCodeInfo_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ SourceCodeInfo_reflection_ = NULL;
+const ::google::protobuf::Descriptor* SourceCodeInfo_Location_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ SourceCodeInfo_Location_reflection_ = NULL;
} // namespace
@@ -99,15 +114,18 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::MessageFactory::generated_factory(),
sizeof(FileDescriptorSet));
FileDescriptorProto_descriptor_ = file->message_type(1);
- static const int FileDescriptorProto_offsets_[8] = {
+ static const int FileDescriptorProto_offsets_[11] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, package_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, dependency_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, public_dependency_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, weak_dependency_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, message_type_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, enum_type_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, service_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, extension_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, options_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, source_code_info_),
};
FileDescriptorProto_reflection_ =
new ::google::protobuf::internal::GeneratedMessageReflection(
@@ -121,13 +139,14 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::MessageFactory::generated_factory(),
sizeof(FileDescriptorProto));
DescriptorProto_descriptor_ = file->message_type(2);
- static const int DescriptorProto_offsets_[7] = {
+ static const int DescriptorProto_offsets_[8] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, field_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, nested_type_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, enum_type_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_range_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, oneof_decl_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, options_),
};
DescriptorProto_reflection_ =
@@ -158,7 +177,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::MessageFactory::generated_factory(),
sizeof(DescriptorProto_ExtensionRange));
FieldDescriptorProto_descriptor_ = file->message_type(3);
- static const int FieldDescriptorProto_offsets_[8] = {
+ static const int FieldDescriptorProto_offsets_[9] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, number_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, label_),
@@ -166,6 +185,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, extendee_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, default_value_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, oneof_index_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, options_),
};
FieldDescriptorProto_reflection_ =
@@ -181,7 +201,22 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
sizeof(FieldDescriptorProto));
FieldDescriptorProto_Type_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(0);
FieldDescriptorProto_Label_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(1);
- EnumDescriptorProto_descriptor_ = file->message_type(4);
+ OneofDescriptorProto_descriptor_ = file->message_type(4);
+ static const int OneofDescriptorProto_offsets_[1] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, name_),
+ };
+ OneofDescriptorProto_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ OneofDescriptorProto_descriptor_,
+ OneofDescriptorProto::default_instance_,
+ OneofDescriptorProto_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(OneofDescriptorProto));
+ EnumDescriptorProto_descriptor_ = file->message_type(5);
static const int EnumDescriptorProto_offsets_[3] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, value_),
@@ -198,7 +233,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(EnumDescriptorProto));
- EnumValueDescriptorProto_descriptor_ = file->message_type(5);
+ EnumValueDescriptorProto_descriptor_ = file->message_type(6);
static const int EnumValueDescriptorProto_offsets_[3] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, number_),
@@ -215,7 +250,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(EnumValueDescriptorProto));
- ServiceDescriptorProto_descriptor_ = file->message_type(6);
+ ServiceDescriptorProto_descriptor_ = file->message_type(7);
static const int ServiceDescriptorProto_offsets_[3] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, method_),
@@ -232,7 +267,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(ServiceDescriptorProto));
- MethodDescriptorProto_descriptor_ = file->message_type(7);
+ MethodDescriptorProto_descriptor_ = file->message_type(8);
static const int MethodDescriptorProto_offsets_[4] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, input_type_),
@@ -250,15 +285,19 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(MethodDescriptorProto));
- FileOptions_descriptor_ = file->message_type(8);
- static const int FileOptions_offsets_[8] = {
+ FileOptions_descriptor_ = file->message_type(9);
+ static const int FileOptions_offsets_[12] = {
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_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generate_equals_and_hash_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_string_check_utf8_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, optimize_for_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, go_package_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_generic_services_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generic_services_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, py_generic_services_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, deprecated_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_),
};
FileOptions_reflection_ =
@@ -273,10 +312,11 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::MessageFactory::generated_factory(),
sizeof(FileOptions));
FileOptions_OptimizeMode_descriptor_ = FileOptions_descriptor_->enum_type(0);
- MessageOptions_descriptor_ = file->message_type(9);
- static const int MessageOptions_offsets_[3] = {
+ MessageOptions_descriptor_ = file->message_type(10);
+ static const int MessageOptions_offsets_[4] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, message_set_wire_format_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, no_standard_descriptor_accessor_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, deprecated_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, uninterpreted_option_),
};
MessageOptions_reflection_ =
@@ -290,12 +330,14 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(MessageOptions));
- FieldOptions_descriptor_ = file->message_type(10);
- static const int FieldOptions_offsets_[5] = {
+ FieldOptions_descriptor_ = file->message_type(11);
+ static const int FieldOptions_offsets_[7] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, packed_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, lazy_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, deprecated_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, experimental_map_key_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, weak_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, uninterpreted_option_),
};
FieldOptions_reflection_ =
@@ -310,8 +352,10 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::MessageFactory::generated_factory(),
sizeof(FieldOptions));
FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0);
- EnumOptions_descriptor_ = file->message_type(11);
- static const int EnumOptions_offsets_[1] = {
+ EnumOptions_descriptor_ = file->message_type(12);
+ static const int EnumOptions_offsets_[3] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, allow_alias_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, deprecated_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, uninterpreted_option_),
};
EnumOptions_reflection_ =
@@ -325,8 +369,9 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(EnumOptions));
- EnumValueOptions_descriptor_ = file->message_type(12);
- static const int EnumValueOptions_offsets_[1] = {
+ EnumValueOptions_descriptor_ = file->message_type(13);
+ static const int EnumValueOptions_offsets_[2] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, deprecated_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, uninterpreted_option_),
};
EnumValueOptions_reflection_ =
@@ -340,8 +385,9 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(EnumValueOptions));
- ServiceOptions_descriptor_ = file->message_type(13);
- static const int ServiceOptions_offsets_[1] = {
+ ServiceOptions_descriptor_ = file->message_type(14);
+ static const int ServiceOptions_offsets_[2] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, deprecated_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, uninterpreted_option_),
};
ServiceOptions_reflection_ =
@@ -355,8 +401,9 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(ServiceOptions));
- MethodOptions_descriptor_ = file->message_type(14);
- static const int MethodOptions_offsets_[1] = {
+ MethodOptions_descriptor_ = file->message_type(15);
+ static const int MethodOptions_offsets_[2] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, deprecated_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, uninterpreted_option_),
};
MethodOptions_reflection_ =
@@ -370,14 +417,15 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(MethodOptions));
- UninterpretedOption_descriptor_ = file->message_type(15);
- static const int UninterpretedOption_offsets_[6] = {
+ UninterpretedOption_descriptor_ = file->message_type(16);
+ static const int UninterpretedOption_offsets_[7] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, identifier_value_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, positive_int_value_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, negative_int_value_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, double_value_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, string_value_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, aggregate_value_),
};
UninterpretedOption_reflection_ =
new ::google::protobuf::internal::GeneratedMessageReflection(
@@ -406,6 +454,39 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(UninterpretedOption_NamePart));
+ SourceCodeInfo_descriptor_ = file->message_type(17);
+ static const int SourceCodeInfo_offsets_[1] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_),
+ };
+ SourceCodeInfo_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ SourceCodeInfo_descriptor_,
+ SourceCodeInfo::default_instance_,
+ SourceCodeInfo_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(SourceCodeInfo));
+ SourceCodeInfo_Location_descriptor_ = SourceCodeInfo_descriptor_->nested_type(0);
+ static const int SourceCodeInfo_Location_offsets_[4] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, path_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, span_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, leading_comments_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, trailing_comments_),
+ };
+ SourceCodeInfo_Location_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ SourceCodeInfo_Location_descriptor_,
+ SourceCodeInfo_Location::default_instance_,
+ SourceCodeInfo_Location_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(SourceCodeInfo_Location));
}
namespace {
@@ -429,6 +510,8 @@ void protobuf_RegisterTypes(const ::std::string&) {
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
FieldDescriptorProto_descriptor_, &FieldDescriptorProto::default_instance());
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ OneofDescriptorProto_descriptor_, &OneofDescriptorProto::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
EnumDescriptorProto_descriptor_, &EnumDescriptorProto::default_instance());
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
EnumValueDescriptorProto_descriptor_, &EnumValueDescriptorProto::default_instance());
@@ -454,6 +537,10 @@ void protobuf_RegisterTypes(const ::std::string&) {
UninterpretedOption_descriptor_, &UninterpretedOption::default_instance());
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
UninterpretedOption_NamePart_descriptor_, &UninterpretedOption_NamePart::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ SourceCodeInfo_descriptor_, &SourceCodeInfo::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ SourceCodeInfo_Location_descriptor_, &SourceCodeInfo_Location::default_instance());
}
} // namespace
@@ -469,6 +556,8 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() {
delete DescriptorProto_ExtensionRange_reflection_;
delete FieldDescriptorProto::default_instance_;
delete FieldDescriptorProto_reflection_;
+ delete OneofDescriptorProto::default_instance_;
+ delete OneofDescriptorProto_reflection_;
delete EnumDescriptorProto::default_instance_;
delete EnumDescriptorProto_reflection_;
delete EnumValueDescriptorProto::default_instance_;
@@ -495,6 +584,10 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() {
delete UninterpretedOption_reflection_;
delete UninterpretedOption_NamePart::default_instance_;
delete UninterpretedOption_NamePart_reflection_;
+ delete SourceCodeInfo::default_instance_;
+ delete SourceCodeInfo_reflection_;
+ delete SourceCodeInfo_Location::default_instance_;
+ delete SourceCodeInfo_Location_reflection_;
}
void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
@@ -507,96 +600,115 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
"\n google/protobuf/descriptor.proto\022\017goog"
"le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
"\030\001 \003(\0132$.google.protobuf.FileDescriptorP"
- "roto\"\334\002\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
+ "roto\"\313\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
"(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022"
- "6\n\014message_type\030\004 \003(\0132 .google.protobuf."
- "DescriptorProto\0227\n\tenum_type\030\005 \003(\0132$.goo"
- "gle.protobuf.EnumDescriptorProto\0228\n\007serv"
- "ice\030\006 \003(\0132\'.google.protobuf.ServiceDescr"
- "iptorProto\0228\n\textension\030\007 \003(\0132%.google.p"
- "rotobuf.FieldDescriptorProto\022-\n\007options\030"
- "\010 \001(\0132\034.google.protobuf.FileOptions\"\251\003\n\017"
- "DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005field\030\002"
- " \003(\0132%.google.protobuf.FieldDescriptorPr"
- "oto\0228\n\textension\030\006 \003(\0132%.google.protobuf"
- ".FieldDescriptorProto\0225\n\013nested_type\030\003 \003"
- "(\0132 .google.protobuf.DescriptorProto\0227\n\t"
- "enum_type\030\004 \003(\0132$.google.protobuf.EnumDe"
- "scriptorProto\022H\n\017extension_range\030\005 \003(\0132/"
- ".google.protobuf.DescriptorProto.Extensi"
- "onRange\0220\n\007options\030\007 \001(\0132\037.google.protob"
- "uf.MessageOptions\032,\n\016ExtensionRange\022\r\n\005s"
- "tart\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"\224\005\n\024FieldDescrip"
- "torProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\003 \001(\005\022:"
- "\n\005label\030\004 \001(\0162+.google.protobuf.FieldDes"
- "criptorProto.Label\0228\n\004type\030\005 \001(\0162*.googl"
- "e.protobuf.FieldDescriptorProto.Type\022\021\n\t"
- "type_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001(\t\022\025\n\rdef"
- "ault_value\030\007 \001(\t\022.\n\007options\030\010 \001(\0132\035.goog"
- "le.protobuf.FieldOptions\"\266\002\n\004Type\022\017\n\013TYP"
- "E_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\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\014T"
- "YPE_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\013TYP"
- "E_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXED"
- "32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021"
- "\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTI"
- "ONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPE"
- "ATED\020\003\"\214\001\n\023EnumDescriptorProto\022\014\n\004name\030\001"
- " \001(\t\0228\n\005value\030\002 \003(\0132).google.protobuf.En"
- "umValueDescriptorProto\022-\n\007options\030\003 \001(\0132"
- "\034.google.protobuf.EnumOptions\"l\n\030EnumVal"
- "ueDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006numbe"
- "r\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.google.protob"
- "uf.EnumValueOptions\"\220\001\n\026ServiceDescripto"
- "rProto\022\014\n\004name\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.g"
- "oogle.protobuf.MethodDescriptorProto\0220\n\007"
- "options\030\003 \001(\0132\037.google.protobuf.ServiceO"
- "ptions\"\177\n\025MethodDescriptorProto\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.google.protobu"
- "f.MethodOptions\"\244\003\n\013FileOptions\022\024\n\014java_"
- "package\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"
- "F\n\014optimize_for\030\t \001(\0162).google.protobuf."
- "FileOptions.OptimizeMode:\005SPEED\022!\n\023cc_ge"
- "neric_services\030\020 \001(\010:\004true\022#\n\025java_gener"
- "ic_services\030\021 \001(\010:\004true\022!\n\023py_generic_se"
- "rvices\030\022 \001(\010:\004true\022C\n\024uninterpreted_opti"
- "on\030\347\007 \003(\0132$.google.protobuf.Uninterprete"
- "dOption\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCO"
- "DE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\270"
- "\001\n\016MessageOptions\022&\n\027message_set_wire_fo"
- "rmat\030\001 \001(\010:\005false\022.\n\037no_standard_descrip"
- "tor_accessor\030\002 \001(\010:\005false\022C\n\024uninterpret"
- "ed_option\030\347\007 \003(\0132$.google.protobuf.Unint"
- "erpretedOption*\t\010\350\007\020\200\200\200\200\002\"\224\002\n\014FieldOptio"
- "ns\022:\n\005ctype\030\001 \001(\0162#.google.protobuf.Fiel"
- "dOptions.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\031"
- "\n\ndeprecated\030\003 \001(\010:\005false\022\034\n\024experimenta"
- "l_map_key\030\t \001(\t\022C\n\024uninterpreted_option\030"
- "\347\007 \003(\0132$.google.protobuf.UninterpretedOp"
- "tion\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014S"
- "TRING_PIECE\020\002*\t\010\350\007\020\200\200\200\200\002\"]\n\013EnumOptions\022"
- "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google."
- "protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\""
- "b\n\020EnumValueOptions\022C\n\024uninterpreted_opt"
- "ion\030\347\007 \003(\0132$.google.protobuf.Uninterpret"
- "edOption*\t\010\350\007\020\200\200\200\200\002\"`\n\016ServiceOptions\022C\n"
- "\024uninterpreted_option\030\347\007 \003(\0132$.google.pr"
- "otobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"_\n"
- "\rMethodOptions\022C\n\024uninterpreted_option\030\347"
- "\007 \003(\0132$.google.protobuf.UninterpretedOpt"
- "ion*\t\010\350\007\020\200\200\200\200\002\"\205\002\n\023UninterpretedOption\022;"
- "\n\004name\030\002 \003(\0132-.google.protobuf.Uninterpr"
- "etedOption.NamePart\022\030\n\020identifier_value\030"
- "\003 \001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n\022neg"
- "ative_int_value\030\005 \001(\003\022\024\n\014double_value\030\006 "
- "\001(\001\022\024\n\014string_value\030\007 \001(\014\0323\n\010NamePart\022\021\n"
- "\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010B)"
- "\n\023com.google.protobufB\020DescriptorProtosH"
- "\001", 3681);
+ "\031\n\021public_dependency\030\n \003(\005\022\027\n\017weak_depen"
+ "dency\030\013 \003(\005\0226\n\014message_type\030\004 \003(\0132 .goog"
+ "le.protobuf.DescriptorProto\0227\n\tenum_type"
+ "\030\005 \003(\0132$.google.protobuf.EnumDescriptorP"
+ "roto\0228\n\007service\030\006 \003(\0132\'.google.protobuf."
+ "ServiceDescriptorProto\0228\n\textension\030\007 \003("
+ "\0132%.google.protobuf.FieldDescriptorProto"
+ "\022-\n\007options\030\010 \001(\0132\034.google.protobuf.File"
+ "Options\0229\n\020source_code_info\030\t \001(\0132\037.goog"
+ "le.protobuf.SourceCodeInfo\"\344\003\n\017Descripto"
+ "rProto\022\014\n\004name\030\001 \001(\t\0224\n\005field\030\002 \003(\0132%.go"
+ "ogle.protobuf.FieldDescriptorProto\0228\n\tex"
+ "tension\030\006 \003(\0132%.google.protobuf.FieldDes"
+ "criptorProto\0225\n\013nested_type\030\003 \003(\0132 .goog"
+ "le.protobuf.DescriptorProto\0227\n\tenum_type"
+ "\030\004 \003(\0132$.google.protobuf.EnumDescriptorP"
+ "roto\022H\n\017extension_range\030\005 \003(\0132/.google.p"
+ "rotobuf.DescriptorProto.ExtensionRange\0229"
+ "\n\noneof_decl\030\010 \003(\0132%.google.protobuf.One"
+ "ofDescriptorProto\0220\n\007options\030\007 \001(\0132\037.goo"
+ "gle.protobuf.MessageOptions\032,\n\016Extension"
+ "Range\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"\251\005\n\024Fi"
+ "eldDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006numb"
+ "er\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.google.protobu"
+ "f.FieldDescriptorProto.Label\0228\n\004type\030\005 \001"
+ "(\0162*.google.protobuf.FieldDescriptorProt"
+ "o.Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010extendee\030\002 "
+ "\001(\t\022\025\n\rdefault_value\030\007 \001(\t\022\023\n\013oneof_inde"
+ "x\030\t \001(\005\022.\n\007options\030\010 \001(\0132\035.google.protob"
+ "uf.FieldOptions\"\266\002\n\004Type\022\017\n\013TYPE_DOUBLE\020"
+ "\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYP"
+ "E_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED"
+ "64\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_M"
+ "ESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020"
+ "\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rT"
+ "YPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_"
+ "SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTIONAL\020\001\022\022\n"
+ "\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPEATED\020\003\"$\n"
+ "\024OneofDescriptorProto\022\014\n\004name\030\001 \001(\t\"\214\001\n\023"
+ "EnumDescriptorProto\022\014\n\004name\030\001 \001(\t\0228\n\005val"
+ "ue\030\002 \003(\0132).google.protobuf.EnumValueDesc"
+ "riptorProto\022-\n\007options\030\003 \001(\0132\034.google.pr"
+ "otobuf.EnumOptions\"l\n\030EnumValueDescripto"
+ "rProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007"
+ "options\030\003 \001(\0132!.google.protobuf.EnumValu"
+ "eOptions\"\220\001\n\026ServiceDescriptorProto\022\014\n\004n"
+ "ame\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.google.proto"
+ "buf.MethodDescriptorProto\0220\n\007options\030\003 \001"
+ "(\0132\037.google.protobuf.ServiceOptions\"\177\n\025M"
+ "ethodDescriptorProto\022\014\n\004name\030\001 \001(\t\022\022\n\nin"
+ "put_type\030\002 \001(\t\022\023\n\013output_type\030\003 \001(\t\022/\n\007o"
+ "ptions\030\004 \001(\0132\036.google.protobuf.MethodOpt"
+ "ions\"\253\004\n\013FileOptions\022\024\n\014java_package\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_gen"
+ "erate_equals_and_hash\030\024 \001(\010:\005false\022%\n\026ja"
+ "va_string_check_utf8\030\033 \001(\010:\005false\022F\n\014opt"
+ "imize_for\030\t \001(\0162).google.protobuf.FileOp"
+ "tions.OptimizeMode:\005SPEED\022\022\n\ngo_package\030"
+ "\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(\010:\005fals"
+ "e\022$\n\025java_generic_services\030\021 \001(\010:\005false\022"
+ "\"\n\023py_generic_services\030\022 \001(\010:\005false\022\031\n\nd"
+ "eprecated\030\027 \001(\010:\005false\022C\n\024uninterpreted_"
+ "option\030\347\007 \003(\0132$.google.protobuf.Uninterp"
+ "retedOption\":\n\014OptimizeMode\022\t\n\005SPEED\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\"\323\001\n\016MessageOptions\022&\n\027message_set_wir"
+ "e_format\030\001 \001(\010:\005false\022.\n\037no_standard_des"
+ "criptor_accessor\030\002 \001(\010:\005false\022\031\n\ndepreca"
+ "ted\030\003 \001(\010:\005false\022C\n\024uninterpreted_option"
+ "\030\347\007 \003(\0132$.google.protobuf.UninterpretedO"
+ "ption*\t\010\350\007\020\200\200\200\200\002\"\276\002\n\014FieldOptions\022:\n\005cty"
+ "pe\030\001 \001(\0162#.google.protobuf.FieldOptions."
+ "CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\023\n\004lazy\030\005 "
+ "\001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\034\n"
+ "\024experimental_map_key\030\t \001(\t\022\023\n\004weak\030\n \001("
+ "\010:\005false\022C\n\024uninterpreted_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_P"
+ "IECE\020\002*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013EnumOptions\022\023\n\013all"
+ "ow_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005fals"
+ "e\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.googl"
+ "e.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.UninterpretedOpti"
+ "on*\t\010\350\007\020\200\200\200\200\002\"z\n\rMethodOptions\022\031\n\ndeprec"
+ "ated\030! \001(\010:\005false\022C\n\024uninterpreted_optio"
+ "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted"
+ "Option*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023UninterpretedOptio"
+ "n\022;\n\004name\030\002 \003(\0132-.google.protobuf.Uninte"
+ "rpretedOption.NamePart\022\030\n\020identifier_val"
+ "ue\030\003 \001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n\022"
+ "negative_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\017aggregat"
+ "e_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\"\261\001\n\016SourceCod"
+ "eInfo\022:\n\010location\030\001 \003(\0132(.google.protobu"
+ "f.SourceCodeInfo.Location\032c\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\020lea"
+ "ding_comments\030\003 \001(\t\022\031\n\021trailing_comments"
+ "\030\004 \001(\tB)\n\023com.google.protobufB\020Descripto"
+ "rProtosH\001", 4449);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
FileDescriptorSet::default_instance_ = new FileDescriptorSet();
@@ -604,6 +716,7 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
DescriptorProto::default_instance_ = new DescriptorProto();
DescriptorProto_ExtensionRange::default_instance_ = new DescriptorProto_ExtensionRange();
FieldDescriptorProto::default_instance_ = new FieldDescriptorProto();
+ OneofDescriptorProto::default_instance_ = new OneofDescriptorProto();
EnumDescriptorProto::default_instance_ = new EnumDescriptorProto();
EnumValueDescriptorProto::default_instance_ = new EnumValueDescriptorProto();
ServiceDescriptorProto::default_instance_ = new ServiceDescriptorProto();
@@ -617,11 +730,14 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
MethodOptions::default_instance_ = new MethodOptions();
UninterpretedOption::default_instance_ = new UninterpretedOption();
UninterpretedOption_NamePart::default_instance_ = new UninterpretedOption_NamePart();
+ SourceCodeInfo::default_instance_ = new SourceCodeInfo();
+ SourceCodeInfo_Location::default_instance_ = new SourceCodeInfo_Location();
FileDescriptorSet::default_instance_->InitAsDefaultInstance();
FileDescriptorProto::default_instance_->InitAsDefaultInstance();
DescriptorProto::default_instance_->InitAsDefaultInstance();
DescriptorProto_ExtensionRange::default_instance_->InitAsDefaultInstance();
FieldDescriptorProto::default_instance_->InitAsDefaultInstance();
+ OneofDescriptorProto::default_instance_->InitAsDefaultInstance();
EnumDescriptorProto::default_instance_->InitAsDefaultInstance();
EnumValueDescriptorProto::default_instance_->InitAsDefaultInstance();
ServiceDescriptorProto::default_instance_->InitAsDefaultInstance();
@@ -635,6 +751,8 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
MethodOptions::default_instance_->InitAsDefaultInstance();
UninterpretedOption::default_instance_->InitAsDefaultInstance();
UninterpretedOption_NamePart::default_instance_->InitAsDefaultInstance();
+ SourceCodeInfo::default_instance_->InitAsDefaultInstance();
+ SourceCodeInfo_Location::default_instance_->InitAsDefaultInstance();
::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto);
}
@@ -645,7 +763,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fdescriptor_2eproto_;
-
// ===================================================================
#ifndef _MSC_VER
@@ -655,6 +772,7 @@ const int FileDescriptorSet::kFileFieldNumber;
FileDescriptorSet::FileDescriptorSet()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorSet)
}
void FileDescriptorSet::InitAsDefaultInstance() {
@@ -664,6 +782,7 @@ FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorSet)
}
void FileDescriptorSet::SharedCtor() {
@@ -672,6 +791,7 @@ void FileDescriptorSet::SharedCtor() {
}
FileDescriptorSet::~FileDescriptorSet() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorSet)
SharedDtor();
}
@@ -691,7 +811,8 @@ const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() {
}
const FileDescriptorSet& FileDescriptorSet::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
FileDescriptorSet* FileDescriptorSet::default_instance_ = NULL;
@@ -708,30 +829,34 @@ void FileDescriptorSet::Clear() {
bool FileDescriptorSet::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.FileDescriptorSet)
+ 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.FileDescriptorProto file = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 10) {
parse_file:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_file()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(10)) goto parse_file;
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -739,43 +864,52 @@ bool FileDescriptorSet::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.FileDescriptorSet)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.FileDescriptorSet)
+ return false;
#undef DO_
}
void FileDescriptorSet::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.FileDescriptorSet)
// repeated .google.protobuf.FileDescriptorProto file = 1;
for (int i = 0; i < this->file_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
1, this->file(i), output);
}
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorSet)
}
::google::protobuf::uint8* FileDescriptorSet::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorSet)
// repeated .google.protobuf.FileDescriptorProto file = 1;
for (int i = 0; i < this->file_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
1, this->file(i), target);
}
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorSet)
return target;
}
int FileDescriptorSet::ByteSize() const {
int total_size = 0;
-
+
// repeated .google.protobuf.FileDescriptorProto file = 1;
total_size += 1 * this->file_size();
for (int i = 0; i < this->file_size(); i++) {
@@ -783,7 +917,7 @@ int FileDescriptorSet::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->file(i));
}
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -826,10 +960,8 @@ void FileDescriptorSet::CopyFrom(const FileDescriptorSet& from) {
}
bool FileDescriptorSet::IsInitialized() const {
-
- for (int i = 0; i < file_size(); i++) {
- if (!this->file(i).IsInitialized()) return false;
- }
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->file())) return false;
return true;
}
@@ -853,55 +985,63 @@ void FileDescriptorSet::Swap(FileDescriptorSet* other) {
// ===================================================================
-const ::std::string FileDescriptorProto::_default_name_;
-const ::std::string FileDescriptorProto::_default_package_;
#ifndef _MSC_VER
const int FileDescriptorProto::kNameFieldNumber;
const int FileDescriptorProto::kPackageFieldNumber;
const int FileDescriptorProto::kDependencyFieldNumber;
+const int FileDescriptorProto::kPublicDependencyFieldNumber;
+const int FileDescriptorProto::kWeakDependencyFieldNumber;
const int FileDescriptorProto::kMessageTypeFieldNumber;
const int FileDescriptorProto::kEnumTypeFieldNumber;
const int FileDescriptorProto::kServiceFieldNumber;
const int FileDescriptorProto::kExtensionFieldNumber;
const int FileDescriptorProto::kOptionsFieldNumber;
+const int FileDescriptorProto::kSourceCodeInfoFieldNumber;
#endif // !_MSC_VER
FileDescriptorProto::FileDescriptorProto()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorProto)
}
void FileDescriptorProto::InitAsDefaultInstance() {
options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance());
+ source_code_info_ = const_cast< ::google::protobuf::SourceCodeInfo*>(&::google::protobuf::SourceCodeInfo::default_instance());
}
FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorProto)
}
void FileDescriptorProto::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
- package_ = const_cast< ::std::string*>(&_default_package_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
options_ = NULL;
+ source_code_info_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
FileDescriptorProto::~FileDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorProto)
SharedDtor();
}
void FileDescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete name_;
}
- if (package_ != &_default_package_) {
+ if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete package_;
}
if (this != default_instance_) {
delete options_;
+ delete source_code_info_;
}
}
@@ -916,7 +1056,8 @@ const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() {
}
const FileDescriptorProto& FileDescriptorProto::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
FileDescriptorProto* FileDescriptorProto::default_instance_ = NULL;
@@ -926,22 +1067,29 @@ FileDescriptorProto* FileDescriptorProto::New() const {
}
void FileDescriptorProto::Clear() {
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (_has_bits_[0 / 32] & 3) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
}
- if (_has_bit(1)) {
- if (package_ != &_default_package_) {
+ if (has_package()) {
+ if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
package_->clear();
}
}
- if (_has_bit(7)) {
+ }
+ if (_has_bits_[8 / 32] & 1536) {
+ if (has_options()) {
if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
}
+ if (has_source_code_info()) {
+ if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
+ }
}
dependency_.Clear();
+ public_dependency_.Clear();
+ weak_dependency_.Clear();
message_type_.Clear();
enum_type_.Clear();
service_.Clear();
@@ -952,140 +1100,192 @@ void FileDescriptorProto::Clear() {
bool FileDescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.FileDescriptorProto)
+ 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)) {
// optional string name = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "name");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(18)) goto parse_package;
break;
}
-
+
// optional string package = 2;
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 18) {
parse_package:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_package()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->package().data(), this->package().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "package");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(26)) goto parse_dependency;
break;
}
-
+
// repeated string dependency = 3;
case 3: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 26) {
parse_dependency:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->add_dependency()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
- this->dependency(0).data(), this->dependency(0).length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->dependency(this->dependency_size() - 1).data(),
+ this->dependency(this->dependency_size() - 1).length(),
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "dependency");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(26)) goto parse_dependency;
if (input->ExpectTag(34)) goto parse_message_type;
break;
}
-
+
// repeated .google.protobuf.DescriptorProto message_type = 4;
case 4: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 34) {
parse_message_type:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_message_type()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(34)) goto parse_message_type;
if (input->ExpectTag(42)) goto parse_enum_type;
break;
}
-
+
// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
case 5: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 42) {
parse_enum_type:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_enum_type()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(42)) goto parse_enum_type;
if (input->ExpectTag(50)) goto parse_service;
break;
}
-
+
// repeated .google.protobuf.ServiceDescriptorProto service = 6;
case 6: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 50) {
parse_service:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_service()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(50)) goto parse_service;
if (input->ExpectTag(58)) goto parse_extension;
break;
}
-
+
// repeated .google.protobuf.FieldDescriptorProto extension = 7;
case 7: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 58) {
parse_extension:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_extension()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(58)) goto parse_extension;
if (input->ExpectTag(66)) goto parse_options;
break;
}
-
+
// optional .google.protobuf.FileOptions options = 8;
case 8: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 66) {
parse_options:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, mutable_options()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(74)) goto parse_source_code_info;
+ break;
+ }
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ case 9: {
+ if (tag == 74) {
+ parse_source_code_info:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_source_code_info()));
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(80)) goto parse_public_dependency;
+ break;
+ }
+
+ // repeated int32 public_dependency = 10;
+ case 10: {
+ if (tag == 80) {
+ parse_public_dependency:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ 1, 80, input, this->mutable_public_dependency())));
+ } else if (tag == 82) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, this->mutable_public_dependency())));
+ } else {
+ goto handle_unusual;
}
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectTag(80)) goto parse_public_dependency;
+ if (input->ExpectTag(88)) goto parse_weak_dependency;
break;
}
-
+
+ // repeated int32 weak_dependency = 11;
+ case 11: {
+ if (tag == 88) {
+ parse_weak_dependency:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ 1, 88, input, this->mutable_weak_dependency())));
+ } else if (tag == 90) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, this->mutable_weak_dependency())));
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(88)) goto parse_weak_dependency;
+ if (input->ExpectAtEnd()) goto success;
+ break;
+ }
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -1093,151 +1293,203 @@ bool FileDescriptorProto::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.FileDescriptorProto)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.FileDescriptorProto)
+ return false;
#undef DO_
}
void FileDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.FileDescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
}
-
+
// optional string package = 2;
- if (_has_bit(1)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_package()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->package().data(), this->package().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "package");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
2, this->package(), output);
}
-
+
// repeated string dependency = 3;
for (int i = 0; i < this->dependency_size(); i++) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->dependency(i).data(), this->dependency(i).length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "dependency");
::google::protobuf::internal::WireFormatLite::WriteString(
3, this->dependency(i), output);
}
-
+
// repeated .google.protobuf.DescriptorProto message_type = 4;
for (int i = 0; i < this->message_type_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
4, this->message_type(i), output);
}
-
+
// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
for (int i = 0; i < this->enum_type_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
5, this->enum_type(i), output);
}
-
+
// repeated .google.protobuf.ServiceDescriptorProto service = 6;
for (int i = 0; i < this->service_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
6, this->service(i), output);
}
-
+
// repeated .google.protobuf.FieldDescriptorProto extension = 7;
for (int i = 0; i < this->extension_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
7, this->extension(i), output);
}
-
+
// optional .google.protobuf.FileOptions options = 8;
- if (_has_bit(7)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
8, this->options(), output);
}
-
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ if (has_source_code_info()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 9, this->source_code_info(), output);
+ }
+
+ // repeated int32 public_dependency = 10;
+ for (int i = 0; i < this->public_dependency_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(
+ 10, this->public_dependency(i), output);
+ }
+
+ // repeated int32 weak_dependency = 11;
+ for (int i = 0; i < this->weak_dependency_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(
+ 11, this->weak_dependency(i), output);
+ }
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorProto)
}
::google::protobuf::uint8* FileDescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
1, this->name(), target);
}
-
+
// optional string package = 2;
- if (_has_bit(1)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_package()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->package().data(), this->package().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "package");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
2, this->package(), target);
}
-
+
// repeated string dependency = 3;
for (int i = 0; i < this->dependency_size(); i++) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->dependency(i).data(), this->dependency(i).length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "dependency");
target = ::google::protobuf::internal::WireFormatLite::
WriteStringToArray(3, this->dependency(i), target);
}
-
+
// repeated .google.protobuf.DescriptorProto message_type = 4;
for (int i = 0; i < this->message_type_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
4, this->message_type(i), target);
}
-
+
// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
for (int i = 0; i < this->enum_type_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
5, this->enum_type(i), target);
}
-
+
// repeated .google.protobuf.ServiceDescriptorProto service = 6;
for (int i = 0; i < this->service_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
6, this->service(i), target);
}
-
+
// repeated .google.protobuf.FieldDescriptorProto extension = 7;
for (int i = 0; i < this->extension_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
7, this->extension(i), target);
}
-
+
// optional .google.protobuf.FileOptions options = 8;
- if (_has_bit(7)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
8, this->options(), 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);
+ }
+
+ // repeated int32 public_dependency = 10;
+ for (int i = 0; i < this->public_dependency_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteInt32ToArray(10, this->public_dependency(i), target);
+ }
+
+ // repeated int32 weak_dependency = 11;
+ for (int i = 0; i < this->weak_dependency_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteInt32ToArray(11, this->weak_dependency(i), target);
+ }
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorProto)
return target;
}
int FileDescriptorProto::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// optional string name = 1;
if (has_name()) {
@@ -1245,21 +1497,30 @@ int FileDescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::StringSize(
this->name());
}
-
+
// optional string package = 2;
if (has_package()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->package());
}
-
+
+ }
+ if (_has_bits_[9 / 32] & (0xffu << (9 % 32))) {
// optional .google.protobuf.FileOptions options = 8;
if (has_options()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->options());
}
-
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ if (has_source_code_info()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->source_code_info());
+ }
+
}
// repeated string dependency = 3;
total_size += 1 * this->dependency_size();
@@ -1267,7 +1528,27 @@ int FileDescriptorProto::ByteSize() const {
total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
this->dependency(i));
}
-
+
+ // repeated int32 public_dependency = 10;
+ {
+ int data_size = 0;
+ for (int i = 0; i < this->public_dependency_size(); i++) {
+ data_size += ::google::protobuf::internal::WireFormatLite::
+ Int32Size(this->public_dependency(i));
+ }
+ total_size += 1 * this->public_dependency_size() + data_size;
+ }
+
+ // repeated int32 weak_dependency = 11;
+ {
+ int data_size = 0;
+ for (int i = 0; i < this->weak_dependency_size(); i++) {
+ data_size += ::google::protobuf::internal::WireFormatLite::
+ Int32Size(this->weak_dependency(i));
+ }
+ total_size += 1 * this->weak_dependency_size() + data_size;
+ }
+
// repeated .google.protobuf.DescriptorProto message_type = 4;
total_size += 1 * this->message_type_size();
for (int i = 0; i < this->message_type_size(); i++) {
@@ -1275,7 +1556,7 @@ int FileDescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->message_type(i));
}
-
+
// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
total_size += 1 * this->enum_type_size();
for (int i = 0; i < this->enum_type_size(); i++) {
@@ -1283,7 +1564,7 @@ int FileDescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->enum_type(i));
}
-
+
// repeated .google.protobuf.ServiceDescriptorProto service = 6;
total_size += 1 * this->service_size();
for (int i = 0; i < this->service_size(); i++) {
@@ -1291,7 +1572,7 @@ int FileDescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->service(i));
}
-
+
// repeated .google.protobuf.FieldDescriptorProto extension = 7;
total_size += 1 * this->extension_size();
for (int i = 0; i < this->extension_size(); i++) {
@@ -1299,7 +1580,7 @@ int FileDescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->extension(i));
}
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -1326,20 +1607,27 @@ void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) {
GOOGLE_CHECK_NE(&from, this);
dependency_.MergeFrom(from.dependency_);
+ public_dependency_.MergeFrom(from.public_dependency_);
+ weak_dependency_.MergeFrom(from.weak_dependency_);
message_type_.MergeFrom(from.message_type_);
enum_type_.MergeFrom(from.enum_type_);
service_.MergeFrom(from.service_);
extension_.MergeFrom(from.extension_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(1)) {
+ if (from.has_package()) {
set_package(from.package());
}
- if (from._has_bit(7)) {
+ }
+ if (from._has_bits_[9 / 32] & (0xffu << (9 % 32))) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options());
}
+ if (from.has_source_code_info()) {
+ mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom(from.source_code_info());
+ }
}
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}
@@ -1357,19 +1645,11 @@ void FileDescriptorProto::CopyFrom(const FileDescriptorProto& from) {
}
bool FileDescriptorProto::IsInitialized() const {
-
- for (int i = 0; i < message_type_size(); i++) {
- if (!this->message_type(i).IsInitialized()) return false;
- }
- for (int i = 0; i < enum_type_size(); i++) {
- if (!this->enum_type(i).IsInitialized()) return false;
- }
- for (int i = 0; i < service_size(); i++) {
- if (!this->service(i).IsInitialized()) return false;
- }
- for (int i = 0; i < extension_size(); i++) {
- if (!this->extension(i).IsInitialized()) return false;
- }
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->message_type())) return false;
+ if (!::google::protobuf::internal::AllAreInitialized(this->enum_type())) return false;
+ if (!::google::protobuf::internal::AllAreInitialized(this->service())) return false;
+ if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false;
if (has_options()) {
if (!this->options().IsInitialized()) return false;
}
@@ -1381,11 +1661,14 @@ void FileDescriptorProto::Swap(FileDescriptorProto* other) {
std::swap(name_, other->name_);
std::swap(package_, other->package_);
dependency_.Swap(&other->dependency_);
+ public_dependency_.Swap(&other->public_dependency_);
+ weak_dependency_.Swap(&other->weak_dependency_);
message_type_.Swap(&other->message_type_);
enum_type_.Swap(&other->enum_type_);
service_.Swap(&other->service_);
extension_.Swap(&other->extension_);
std::swap(options_, other->options_);
+ std::swap(source_code_info_, other->source_code_info_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
std::swap(_cached_size_, other->_cached_size_);
@@ -1411,6 +1694,7 @@ const int DescriptorProto_ExtensionRange::kEndFieldNumber;
DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto.ExtensionRange)
}
void DescriptorProto_ExtensionRange::InitAsDefaultInstance() {
@@ -1420,6 +1704,7 @@ DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorP
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ExtensionRange)
}
void DescriptorProto_ExtensionRange::SharedCtor() {
@@ -1430,6 +1715,7 @@ void DescriptorProto_ExtensionRange::SharedCtor() {
}
DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() {
+ // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ExtensionRange)
SharedDtor();
}
@@ -1449,7 +1735,8 @@ const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor
}
const DescriptorProto_ExtensionRange& DescriptorProto_ExtensionRange::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::default_instance_ = NULL;
@@ -1459,56 +1746,70 @@ DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::New() const {
}
void DescriptorProto_ExtensionRange::Clear() {
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- start_ = 0;
- end_ = 0;
- }
+#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
+ &reinterpret_cast<DescriptorProto_ExtensionRange*>(16)->f) - \
+ reinterpret_cast<char*>(16))
+
+#define ZR_(first, last) do { \
+ size_t f = OFFSET_OF_FIELD_(first); \
+ size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
+ ::memset(&first, 0, n); \
+ } while (0)
+
+ ZR_(start_, end_);
+
+#undef OFFSET_OF_FIELD_
+#undef ZR_
+
::memset(_has_bits_, 0, sizeof(_has_bits_));
mutable_unknown_fields()->Clear();
}
bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.DescriptorProto.ExtensionRange)
+ 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)) {
// optional int32 start = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 8) {
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
input, &start_)));
- _set_bit(0);
+ set_has_start();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(16)) goto parse_end;
break;
}
-
+
// optional int32 end = 2;
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 16) {
parse_end:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
input, &end_)));
- _set_bit(1);
+ set_has_end();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -1516,50 +1817,59 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.DescriptorProto.ExtensionRange)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.DescriptorProto.ExtensionRange)
+ return false;
#undef DO_
}
void DescriptorProto_ExtensionRange::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.DescriptorProto.ExtensionRange)
// optional int32 start = 1;
- if (_has_bit(0)) {
+ if (has_start()) {
::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output);
}
-
+
// optional int32 end = 2;
- if (_has_bit(1)) {
+ if (has_end()) {
::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output);
}
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto.ExtensionRange)
}
::google::protobuf::uint8* DescriptorProto_ExtensionRange::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ExtensionRange)
// optional int32 start = 1;
- if (_has_bit(0)) {
+ if (has_start()) {
target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target);
}
-
+
// optional int32 end = 2;
- if (_has_bit(1)) {
+ if (has_end()) {
target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target);
}
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ExtensionRange)
return target;
}
int DescriptorProto_ExtensionRange::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// optional int32 start = 1;
if (has_start()) {
@@ -1567,14 +1877,14 @@ int DescriptorProto_ExtensionRange::ByteSize() const {
::google::protobuf::internal::WireFormatLite::Int32Size(
this->start());
}
-
+
// optional int32 end = 2;
if (has_end()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::Int32Size(
this->end());
}
-
+
}
if (!unknown_fields().empty()) {
total_size +=
@@ -1602,10 +1912,10 @@ void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message
void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_start()) {
set_start(from.start());
}
- if (from._has_bit(1)) {
+ if (from.has_end()) {
set_end(from.end());
}
}
@@ -1625,7 +1935,7 @@ void DescriptorProto_ExtensionRange::CopyFrom(const DescriptorProto_ExtensionRan
}
bool DescriptorProto_ExtensionRange::IsInitialized() const {
-
+
return true;
}
@@ -1650,7 +1960,6 @@ void DescriptorProto_ExtensionRange::Swap(DescriptorProto_ExtensionRange* other)
// -------------------------------------------------------------------
-const ::std::string DescriptorProto::_default_name_;
#ifndef _MSC_VER
const int DescriptorProto::kNameFieldNumber;
const int DescriptorProto::kFieldFieldNumber;
@@ -1658,12 +1967,14 @@ const int DescriptorProto::kExtensionFieldNumber;
const int DescriptorProto::kNestedTypeFieldNumber;
const int DescriptorProto::kEnumTypeFieldNumber;
const int DescriptorProto::kExtensionRangeFieldNumber;
+const int DescriptorProto::kOneofDeclFieldNumber;
const int DescriptorProto::kOptionsFieldNumber;
#endif // !_MSC_VER
DescriptorProto::DescriptorProto()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto)
}
void DescriptorProto::InitAsDefaultInstance() {
@@ -1674,21 +1985,24 @@ DescriptorProto::DescriptorProto(const DescriptorProto& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto)
}
void DescriptorProto::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
options_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
DescriptorProto::~DescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto)
SharedDtor();
}
void DescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete name_;
}
if (this != default_instance_) {
@@ -1707,7 +2021,8 @@ const ::google::protobuf::Descriptor* DescriptorProto::descriptor() {
}
const DescriptorProto& DescriptorProto::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
DescriptorProto* DescriptorProto::default_instance_ = NULL;
@@ -1717,13 +2032,13 @@ DescriptorProto* DescriptorProto::New() const {
}
void DescriptorProto::Clear() {
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (_has_bits_[0 / 32] & 129) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
}
- if (_has_bit(6)) {
+ if (has_options()) {
if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
}
}
@@ -1732,126 +2047,140 @@ void DescriptorProto::Clear() {
nested_type_.Clear();
enum_type_.Clear();
extension_range_.Clear();
+ oneof_decl_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
mutable_unknown_fields()->Clear();
}
bool DescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.DescriptorProto)
+ 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)) {
// optional string name = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "name");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(18)) goto parse_field;
break;
}
-
+
// repeated .google.protobuf.FieldDescriptorProto field = 2;
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 18) {
parse_field:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_field()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(18)) goto parse_field;
if (input->ExpectTag(26)) goto parse_nested_type;
break;
}
-
+
// repeated .google.protobuf.DescriptorProto nested_type = 3;
case 3: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 26) {
parse_nested_type:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_nested_type()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(26)) goto parse_nested_type;
if (input->ExpectTag(34)) goto parse_enum_type;
break;
}
-
+
// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
case 4: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 34) {
parse_enum_type:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_enum_type()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(34)) goto parse_enum_type;
if (input->ExpectTag(42)) goto parse_extension_range;
break;
}
-
+
// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
case 5: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 42) {
parse_extension_range:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_extension_range()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(42)) goto parse_extension_range;
if (input->ExpectTag(50)) goto parse_extension;
break;
}
-
+
// repeated .google.protobuf.FieldDescriptorProto extension = 6;
case 6: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 50) {
parse_extension:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_extension()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(50)) goto parse_extension;
if (input->ExpectTag(58)) goto parse_options;
break;
}
-
+
// optional .google.protobuf.MessageOptions options = 7;
case 7: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 58) {
parse_options:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, mutable_options()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectTag(66)) goto parse_oneof_decl;
break;
}
-
+
+ // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+ case 8: {
+ if (tag == 66) {
+ parse_oneof_decl:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_oneof_decl()));
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(66)) goto parse_oneof_decl;
+ if (input->ExpectAtEnd()) goto success;
+ break;
+ }
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -1859,127 +2188,151 @@ bool DescriptorProto::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.DescriptorProto)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.DescriptorProto)
+ return false;
#undef DO_
}
void DescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.DescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
}
-
+
// repeated .google.protobuf.FieldDescriptorProto field = 2;
for (int i = 0; i < this->field_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
2, this->field(i), output);
}
-
+
// repeated .google.protobuf.DescriptorProto nested_type = 3;
for (int i = 0; i < this->nested_type_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
3, this->nested_type(i), output);
}
-
+
// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
for (int i = 0; i < this->enum_type_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
4, this->enum_type(i), output);
}
-
+
// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
for (int i = 0; i < this->extension_range_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
5, this->extension_range(i), output);
}
-
+
// repeated .google.protobuf.FieldDescriptorProto extension = 6;
for (int i = 0; i < this->extension_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
6, this->extension(i), output);
}
-
+
// optional .google.protobuf.MessageOptions options = 7;
- if (_has_bit(6)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
7, this->options(), output);
}
-
+
+ // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+ for (int i = 0; i < this->oneof_decl_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 8, this->oneof_decl(i), output);
+ }
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto)
}
::google::protobuf::uint8* DescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
1, this->name(), target);
}
-
+
// repeated .google.protobuf.FieldDescriptorProto field = 2;
for (int i = 0; i < this->field_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
2, this->field(i), target);
}
-
+
// repeated .google.protobuf.DescriptorProto nested_type = 3;
for (int i = 0; i < this->nested_type_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
3, this->nested_type(i), target);
}
-
+
// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
for (int i = 0; i < this->enum_type_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
4, this->enum_type(i), target);
}
-
+
// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
for (int i = 0; i < this->extension_range_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
5, this->extension_range(i), target);
}
-
+
// repeated .google.protobuf.FieldDescriptorProto extension = 6;
for (int i = 0; i < this->extension_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
6, this->extension(i), target);
}
-
+
// optional .google.protobuf.MessageOptions options = 7;
- if (_has_bit(6)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
7, this->options(), target);
}
-
+
+ // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+ for (int i = 0; i < this->oneof_decl_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 8, this->oneof_decl(i), target);
+ }
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto)
return target;
}
int DescriptorProto::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// optional string name = 1;
if (has_name()) {
@@ -1987,14 +2340,14 @@ int DescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::StringSize(
this->name());
}
-
+
// optional .google.protobuf.MessageOptions options = 7;
if (has_options()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->options());
}
-
+
}
// repeated .google.protobuf.FieldDescriptorProto field = 2;
total_size += 1 * this->field_size();
@@ -2003,7 +2356,7 @@ int DescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->field(i));
}
-
+
// repeated .google.protobuf.FieldDescriptorProto extension = 6;
total_size += 1 * this->extension_size();
for (int i = 0; i < this->extension_size(); i++) {
@@ -2011,7 +2364,7 @@ int DescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->extension(i));
}
-
+
// repeated .google.protobuf.DescriptorProto nested_type = 3;
total_size += 1 * this->nested_type_size();
for (int i = 0; i < this->nested_type_size(); i++) {
@@ -2019,7 +2372,7 @@ int DescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->nested_type(i));
}
-
+
// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
total_size += 1 * this->enum_type_size();
for (int i = 0; i < this->enum_type_size(); i++) {
@@ -2027,7 +2380,7 @@ int DescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->enum_type(i));
}
-
+
// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
total_size += 1 * this->extension_range_size();
for (int i = 0; i < this->extension_range_size(); i++) {
@@ -2035,7 +2388,15 @@ int DescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->extension_range(i));
}
-
+
+ // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+ total_size += 1 * this->oneof_decl_size();
+ for (int i = 0; i < this->oneof_decl_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->oneof_decl(i));
+ }
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -2066,11 +2427,12 @@ void DescriptorProto::MergeFrom(const DescriptorProto& from) {
nested_type_.MergeFrom(from.nested_type_);
enum_type_.MergeFrom(from.enum_type_);
extension_range_.MergeFrom(from.extension_range_);
+ oneof_decl_.MergeFrom(from.oneof_decl_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(6)) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::MessageOptions::MergeFrom(from.options());
}
}
@@ -2090,19 +2452,11 @@ void DescriptorProto::CopyFrom(const DescriptorProto& from) {
}
bool DescriptorProto::IsInitialized() const {
-
- for (int i = 0; i < field_size(); i++) {
- if (!this->field(i).IsInitialized()) return false;
- }
- for (int i = 0; i < extension_size(); i++) {
- if (!this->extension(i).IsInitialized()) return false;
- }
- for (int i = 0; i < nested_type_size(); i++) {
- if (!this->nested_type(i).IsInitialized()) return false;
- }
- for (int i = 0; i < enum_type_size(); i++) {
- if (!this->enum_type(i).IsInitialized()) return false;
- }
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->field())) return false;
+ 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 (has_options()) {
if (!this->options().IsInitialized()) return false;
}
@@ -2117,6 +2471,7 @@ void DescriptorProto::Swap(DescriptorProto* other) {
nested_type_.Swap(&other->nested_type_);
enum_type_.Swap(&other->enum_type_);
extension_range_.Swap(&other->extension_range_);
+ oneof_decl_.Swap(&other->oneof_decl_);
std::swap(options_, other->options_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
@@ -2211,10 +2566,6 @@ const FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN;
const FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX;
const int FieldDescriptorProto::Label_ARRAYSIZE;
#endif // _MSC_VER
-const ::std::string FieldDescriptorProto::_default_name_;
-const ::std::string FieldDescriptorProto::_default_type_name_;
-const ::std::string FieldDescriptorProto::_default_extendee_;
-const ::std::string FieldDescriptorProto::_default_default_value_;
#ifndef _MSC_VER
const int FieldDescriptorProto::kNameFieldNumber;
const int FieldDescriptorProto::kNumberFieldNumber;
@@ -2223,12 +2574,14 @@ const int FieldDescriptorProto::kTypeFieldNumber;
const int FieldDescriptorProto::kTypeNameFieldNumber;
const int FieldDescriptorProto::kExtendeeFieldNumber;
const int FieldDescriptorProto::kDefaultValueFieldNumber;
+const int FieldDescriptorProto::kOneofIndexFieldNumber;
const int FieldDescriptorProto::kOptionsFieldNumber;
#endif // !_MSC_VER
FieldDescriptorProto::FieldDescriptorProto()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.FieldDescriptorProto)
}
void FieldDescriptorProto::InitAsDefaultInstance() {
@@ -2239,36 +2592,40 @@ FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldDescriptorProto)
}
void FieldDescriptorProto::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
number_ = 0;
label_ = 1;
type_ = 1;
- type_name_ = const_cast< ::std::string*>(&_default_type_name_);
- extendee_ = const_cast< ::std::string*>(&_default_extendee_);
- default_value_ = const_cast< ::std::string*>(&_default_default_value_);
+ type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ oneof_index_ = 0;
options_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
FieldDescriptorProto::~FieldDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FieldDescriptorProto)
SharedDtor();
}
void FieldDescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete name_;
}
- if (type_name_ != &_default_type_name_) {
+ if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete type_name_;
}
- if (extendee_ != &_default_extendee_) {
+ if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete extendee_;
}
- if (default_value_ != &_default_default_value_) {
+ if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete default_value_;
}
if (this != default_instance_) {
@@ -2287,7 +2644,8 @@ const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() {
}
const FieldDescriptorProto& FieldDescriptorProto::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
FieldDescriptorProto* FieldDescriptorProto::default_instance_ = NULL;
@@ -2297,33 +2655,34 @@ FieldDescriptorProto* FieldDescriptorProto::New() const {
}
void FieldDescriptorProto::Clear() {
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (_has_bits_[0 / 32] & 255) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
}
number_ = 0;
label_ = 1;
type_ = 1;
- if (_has_bit(4)) {
- if (type_name_ != &_default_type_name_) {
+ if (has_type_name()) {
+ if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
type_name_->clear();
}
}
- if (_has_bit(5)) {
- if (extendee_ != &_default_extendee_) {
+ if (has_extendee()) {
+ if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
extendee_->clear();
}
}
- if (_has_bit(6)) {
- if (default_value_ != &_default_default_value_) {
+ if (has_default_value()) {
+ if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
default_value_->clear();
}
}
- if (_has_bit(7)) {
- if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
- }
+ oneof_index_ = 0;
+ }
+ if (has_options()) {
+ if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
}
::memset(_has_bits_, 0, sizeof(_has_bits_));
mutable_unknown_fields()->Clear();
@@ -2331,63 +2690,65 @@ void FieldDescriptorProto::Clear() {
bool FieldDescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.FieldDescriptorProto)
+ 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)) {
// optional string name = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "name");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(18)) goto parse_extendee;
break;
}
-
+
// optional string extendee = 2;
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 18) {
parse_extendee:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_extendee()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->extendee().data(), this->extendee().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "extendee");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(24)) goto parse_number;
break;
}
-
+
// optional int32 number = 3;
case 3: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 24) {
parse_number:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
input, &number_)));
- _set_bit(1);
+ set_has_number();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(32)) goto parse_label;
break;
}
-
+
// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
case 4: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 32) {
parse_label:
int value;
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
@@ -2399,16 +2760,15 @@ bool FieldDescriptorProto::MergePartialFromCodedStream(
mutable_unknown_fields()->AddVarint(4, value);
}
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(40)) goto parse_type;
break;
}
-
+
// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
case 5: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 40) {
parse_type:
int value;
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
@@ -2420,65 +2780,80 @@ bool FieldDescriptorProto::MergePartialFromCodedStream(
mutable_unknown_fields()->AddVarint(5, value);
}
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(50)) goto parse_type_name;
break;
}
-
+
// optional string type_name = 6;
case 6: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 50) {
parse_type_name:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_type_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->type_name().data(), this->type_name().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "type_name");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(58)) goto parse_default_value;
break;
}
-
+
// optional string default_value = 7;
case 7: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 58) {
parse_default_value:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_default_value()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->default_value().data(), this->default_value().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "default_value");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(66)) goto parse_options;
break;
}
-
+
// optional .google.protobuf.FieldOptions options = 8;
case 8: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 66) {
parse_options:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, mutable_options()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(72)) goto parse_oneof_index;
+ break;
+ }
+
+ // optional int32 oneof_index = 9;
+ case 9: {
+ if (tag == 72) {
+ parse_oneof_index:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &oneof_index_)));
+ set_has_oneof_index();
+ } else {
+ goto handle_unusual;
}
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -2486,153 +2861,180 @@ bool FieldDescriptorProto::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.FieldDescriptorProto)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.FieldDescriptorProto)
+ return false;
#undef DO_
}
void FieldDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.FieldDescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
}
-
+
// optional string extendee = 2;
- if (_has_bit(5)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_extendee()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->extendee().data(), this->extendee().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "extendee");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
2, this->extendee(), output);
}
-
+
// optional int32 number = 3;
- if (_has_bit(1)) {
+ if (has_number()) {
::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output);
}
-
+
// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
- if (_has_bit(2)) {
+ if (has_label()) {
::google::protobuf::internal::WireFormatLite::WriteEnum(
4, this->label(), output);
}
-
+
// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
- if (_has_bit(3)) {
+ if (has_type()) {
::google::protobuf::internal::WireFormatLite::WriteEnum(
5, this->type(), output);
}
-
+
// optional string type_name = 6;
- if (_has_bit(4)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_type_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->type_name().data(), this->type_name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "type_name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
6, this->type_name(), output);
}
-
+
// optional string default_value = 7;
- if (_has_bit(6)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_default_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->default_value().data(), this->default_value().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "default_value");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
7, this->default_value(), output);
}
-
+
// optional .google.protobuf.FieldOptions options = 8;
- if (_has_bit(7)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
8, this->options(), output);
}
-
+
+ // optional int32 oneof_index = 9;
+ if (has_oneof_index()) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(9, this->oneof_index(), output);
+ }
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.FieldDescriptorProto)
}
::google::protobuf::uint8* FieldDescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldDescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
1, this->name(), target);
}
-
+
// optional string extendee = 2;
- if (_has_bit(5)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_extendee()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->extendee().data(), this->extendee().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "extendee");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
2, this->extendee(), target);
}
-
+
// optional int32 number = 3;
- if (_has_bit(1)) {
+ if (has_number()) {
target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target);
}
-
+
// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
- if (_has_bit(2)) {
+ if (has_label()) {
target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
4, this->label(), target);
}
-
+
// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
- if (_has_bit(3)) {
+ if (has_type()) {
target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
5, this->type(), target);
}
-
+
// optional string type_name = 6;
- if (_has_bit(4)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_type_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->type_name().data(), this->type_name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "type_name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
6, this->type_name(), target);
}
-
+
// optional string default_value = 7;
- if (_has_bit(6)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_default_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->default_value().data(), this->default_value().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "default_value");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
7, this->default_value(), target);
}
-
+
// optional .google.protobuf.FieldOptions options = 8;
- if (_has_bit(7)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
8, this->options(), target);
}
-
+
+ // optional int32 oneof_index = 9;
+ if (has_oneof_index()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(9, this->oneof_index(), target);
+ }
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldDescriptorProto)
return target;
}
int FieldDescriptorProto::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// optional string name = 1;
if (has_name()) {
@@ -2640,54 +3042,63 @@ int FieldDescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::StringSize(
this->name());
}
-
+
// optional int32 number = 3;
if (has_number()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::Int32Size(
this->number());
}
-
+
// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
if (has_label()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::EnumSize(this->label());
}
-
+
// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
if (has_type()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
}
-
+
// optional string type_name = 6;
if (has_type_name()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->type_name());
}
-
+
// optional string extendee = 2;
if (has_extendee()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->extendee());
}
-
+
// optional string default_value = 7;
if (has_default_value()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->default_value());
}
-
+
+ // optional int32 oneof_index = 9;
+ if (has_oneof_index()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->oneof_index());
+ }
+
+ }
+ if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
// optional .google.protobuf.FieldOptions options = 8;
if (has_options()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->options());
}
-
+
}
if (!unknown_fields().empty()) {
total_size +=
@@ -2715,28 +3126,33 @@ void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(1)) {
+ if (from.has_number()) {
set_number(from.number());
}
- if (from._has_bit(2)) {
+ if (from.has_label()) {
set_label(from.label());
}
- if (from._has_bit(3)) {
+ if (from.has_type()) {
set_type(from.type());
}
- if (from._has_bit(4)) {
+ if (from.has_type_name()) {
set_type_name(from.type_name());
}
- if (from._has_bit(5)) {
+ if (from.has_extendee()) {
set_extendee(from.extendee());
}
- if (from._has_bit(6)) {
+ if (from.has_default_value()) {
set_default_value(from.default_value());
}
- if (from._has_bit(7)) {
+ if (from.has_oneof_index()) {
+ set_oneof_index(from.oneof_index());
+ }
+ }
+ if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::FieldOptions::MergeFrom(from.options());
}
}
@@ -2756,7 +3172,7 @@ void FieldDescriptorProto::CopyFrom(const FieldDescriptorProto& from) {
}
bool FieldDescriptorProto::IsInitialized() const {
-
+
if (has_options()) {
if (!this->options().IsInitialized()) return false;
}
@@ -2772,6 +3188,7 @@ void FieldDescriptorProto::Swap(FieldDescriptorProto* other) {
std::swap(type_name_, other->type_name_);
std::swap(extendee_, other->extendee_);
std::swap(default_value_, other->default_value_);
+ std::swap(oneof_index_, other->oneof_index_);
std::swap(options_, other->options_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
@@ -2790,7 +3207,249 @@ void FieldDescriptorProto::Swap(FieldDescriptorProto* other) {
// ===================================================================
-const ::std::string EnumDescriptorProto::_default_name_;
+#ifndef _MSC_VER
+const int OneofDescriptorProto::kNameFieldNumber;
+#endif // !_MSC_VER
+
+OneofDescriptorProto::OneofDescriptorProto()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.OneofDescriptorProto)
+}
+
+void OneofDescriptorProto::InitAsDefaultInstance() {
+}
+
+OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofDescriptorProto)
+}
+
+void OneofDescriptorProto::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
+ _cached_size_ = 0;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+OneofDescriptorProto::~OneofDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.OneofDescriptorProto)
+ SharedDtor();
+}
+
+void OneofDescriptorProto::SharedDtor() {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete name_;
+ }
+ if (this != default_instance_) {
+ }
+}
+
+void OneofDescriptorProto::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* OneofDescriptorProto::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return OneofDescriptorProto_descriptor_;
+}
+
+const OneofDescriptorProto& OneofDescriptorProto::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+OneofDescriptorProto* OneofDescriptorProto::default_instance_ = NULL;
+
+OneofDescriptorProto* OneofDescriptorProto::New() const {
+ return new OneofDescriptorProto;
+}
+
+void OneofDescriptorProto::Clear() {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ name_->clear();
+ }
+ }
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool OneofDescriptorProto::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:google.protobuf.OneofDescriptorProto)
+ 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)) {
+ // optional string name = 1;
+ case 1: {
+ if (tag == 10) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_name()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "name");
+ } 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.OneofDescriptorProto)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.OneofDescriptorProto)
+ return false;
+#undef DO_
+}
+
+void OneofDescriptorProto::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.OneofDescriptorProto)
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+ 1, this->name(), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+ // @@protoc_insertion_point(serialize_end:google.protobuf.OneofDescriptorProto)
+}
+
+::google::protobuf::uint8* OneofDescriptorProto::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofDescriptorProto)
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->name(), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofDescriptorProto)
+ return target;
+}
+
+int OneofDescriptorProto::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional string name = 1;
+ if (has_name()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name());
+ }
+
+ }
+ if (!unknown_fields().empty()) {
+ 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 OneofDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const OneofDescriptorProto* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const OneofDescriptorProto*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void OneofDescriptorProto::MergeFrom(const OneofDescriptorProto& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_name()) {
+ set_name(from.name());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void OneofDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void OneofDescriptorProto::CopyFrom(const OneofDescriptorProto& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool OneofDescriptorProto::IsInitialized() const {
+
+ return true;
+}
+
+void OneofDescriptorProto::Swap(OneofDescriptorProto* other) {
+ if (other != this) {
+ std::swap(name_, other->name_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata OneofDescriptorProto::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = OneofDescriptorProto_descriptor_;
+ metadata.reflection = OneofDescriptorProto_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
#ifndef _MSC_VER
const int EnumDescriptorProto::kNameFieldNumber;
const int EnumDescriptorProto::kValueFieldNumber;
@@ -2800,6 +3459,7 @@ const int EnumDescriptorProto::kOptionsFieldNumber;
EnumDescriptorProto::EnumDescriptorProto()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.EnumDescriptorProto)
}
void EnumDescriptorProto::InitAsDefaultInstance() {
@@ -2810,21 +3470,24 @@ EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto)
}
void EnumDescriptorProto::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
options_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
EnumDescriptorProto::~EnumDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto)
SharedDtor();
}
void EnumDescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete name_;
}
if (this != default_instance_) {
@@ -2843,7 +3506,8 @@ const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() {
}
const EnumDescriptorProto& EnumDescriptorProto::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
EnumDescriptorProto* EnumDescriptorProto::default_instance_ = NULL;
@@ -2853,13 +3517,13 @@ EnumDescriptorProto* EnumDescriptorProto::New() const {
}
void EnumDescriptorProto::Clear() {
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (_has_bits_[0 / 32] & 5) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
}
- if (_has_bit(2)) {
+ if (has_options()) {
if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
}
}
@@ -2870,60 +3534,63 @@ void EnumDescriptorProto::Clear() {
bool EnumDescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.EnumDescriptorProto)
+ 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)) {
// optional string name = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "name");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(18)) goto parse_value;
break;
}
-
+
// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 18) {
parse_value:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_value()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(18)) goto parse_value;
if (input->ExpectTag(26)) goto parse_options;
break;
}
-
+
// optional .google.protobuf.EnumOptions options = 3;
case 3: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 26) {
parse_options:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, mutable_options()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -2931,75 +3598,86 @@ bool EnumDescriptorProto::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.EnumDescriptorProto)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.EnumDescriptorProto)
+ return false;
#undef DO_
}
void EnumDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.EnumDescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
}
-
+
// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
for (int i = 0; i < this->value_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
2, this->value(i), output);
}
-
+
// optional .google.protobuf.EnumOptions options = 3;
- if (_has_bit(2)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
3, this->options(), output);
}
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.EnumDescriptorProto)
}
::google::protobuf::uint8* EnumDescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumDescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
1, this->name(), target);
}
-
+
// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
for (int i = 0; i < this->value_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
2, this->value(i), target);
}
-
+
// optional .google.protobuf.EnumOptions options = 3;
- if (_has_bit(2)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
3, this->options(), target);
}
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto)
return target;
}
int EnumDescriptorProto::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// optional string name = 1;
if (has_name()) {
@@ -3007,14 +3685,14 @@ int EnumDescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::StringSize(
this->name());
}
-
+
// optional .google.protobuf.EnumOptions options = 3;
if (has_options()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->options());
}
-
+
}
// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
total_size += 1 * this->value_size();
@@ -3023,7 +3701,7 @@ int EnumDescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->value(i));
}
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -3051,10 +3729,10 @@ void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) {
GOOGLE_CHECK_NE(&from, this);
value_.MergeFrom(from.value_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(2)) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::EnumOptions::MergeFrom(from.options());
}
}
@@ -3074,10 +3752,8 @@ void EnumDescriptorProto::CopyFrom(const EnumDescriptorProto& from) {
}
bool EnumDescriptorProto::IsInitialized() const {
-
- for (int i = 0; i < value_size(); i++) {
- if (!this->value(i).IsInitialized()) return false;
- }
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->value())) return false;
if (has_options()) {
if (!this->options().IsInitialized()) return false;
}
@@ -3106,7 +3782,6 @@ void EnumDescriptorProto::Swap(EnumDescriptorProto* other) {
// ===================================================================
-const ::std::string EnumValueDescriptorProto::_default_name_;
#ifndef _MSC_VER
const int EnumValueDescriptorProto::kNameFieldNumber;
const int EnumValueDescriptorProto::kNumberFieldNumber;
@@ -3116,6 +3791,7 @@ const int EnumValueDescriptorProto::kOptionsFieldNumber;
EnumValueDescriptorProto::EnumValueDescriptorProto()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.EnumValueDescriptorProto)
}
void EnumValueDescriptorProto::InitAsDefaultInstance() {
@@ -3126,22 +3802,25 @@ EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProt
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueDescriptorProto)
}
void EnumValueDescriptorProto::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
number_ = 0;
options_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
EnumValueDescriptorProto::~EnumValueDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumValueDescriptorProto)
SharedDtor();
}
void EnumValueDescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete name_;
}
if (this != default_instance_) {
@@ -3160,7 +3839,8 @@ const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() {
}
const EnumValueDescriptorProto& EnumValueDescriptorProto::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
EnumValueDescriptorProto* EnumValueDescriptorProto::default_instance_ = NULL;
@@ -3170,14 +3850,14 @@ EnumValueDescriptorProto* EnumValueDescriptorProto::New() const {
}
void EnumValueDescriptorProto::Clear() {
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (_has_bits_[0 / 32] & 7) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
}
number_ = 0;
- if (_has_bit(2)) {
+ if (has_options()) {
if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
}
}
@@ -3187,61 +3867,64 @@ void EnumValueDescriptorProto::Clear() {
bool EnumValueDescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.EnumValueDescriptorProto)
+ 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)) {
// optional string name = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "name");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(16)) goto parse_number;
break;
}
-
+
// optional int32 number = 2;
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 16) {
parse_number:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
input, &number_)));
- _set_bit(1);
+ set_has_number();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(26)) goto parse_options;
break;
}
-
+
// optional .google.protobuf.EnumValueOptions options = 3;
case 3: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 26) {
parse_options:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, mutable_options()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -3249,72 +3932,83 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.EnumValueDescriptorProto)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.EnumValueDescriptorProto)
+ return false;
#undef DO_
}
void EnumValueDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValueDescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
}
-
+
// optional int32 number = 2;
- if (_has_bit(1)) {
+ if (has_number()) {
::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output);
}
-
+
// optional .google.protobuf.EnumValueOptions options = 3;
- if (_has_bit(2)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
3, this->options(), output);
}
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueDescriptorProto)
}
::google::protobuf::uint8* EnumValueDescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueDescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
1, this->name(), target);
}
-
+
// optional int32 number = 2;
- if (_has_bit(1)) {
+ if (has_number()) {
target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target);
}
-
+
// optional .google.protobuf.EnumValueOptions options = 3;
- if (_has_bit(2)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
3, this->options(), target);
}
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueDescriptorProto)
return target;
}
int EnumValueDescriptorProto::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// optional string name = 1;
if (has_name()) {
@@ -3322,21 +4016,21 @@ int EnumValueDescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::StringSize(
this->name());
}
-
+
// optional int32 number = 2;
if (has_number()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::Int32Size(
this->number());
}
-
+
// optional .google.protobuf.EnumValueOptions options = 3;
if (has_options()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->options());
}
-
+
}
if (!unknown_fields().empty()) {
total_size +=
@@ -3364,13 +4058,13 @@ void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from
void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(1)) {
+ if (from.has_number()) {
set_number(from.number());
}
- if (from._has_bit(2)) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom(from.options());
}
}
@@ -3390,7 +4084,7 @@ void EnumValueDescriptorProto::CopyFrom(const EnumValueDescriptorProto& from) {
}
bool EnumValueDescriptorProto::IsInitialized() const {
-
+
if (has_options()) {
if (!this->options().IsInitialized()) return false;
}
@@ -3419,7 +4113,6 @@ void EnumValueDescriptorProto::Swap(EnumValueDescriptorProto* other) {
// ===================================================================
-const ::std::string ServiceDescriptorProto::_default_name_;
#ifndef _MSC_VER
const int ServiceDescriptorProto::kNameFieldNumber;
const int ServiceDescriptorProto::kMethodFieldNumber;
@@ -3429,6 +4122,7 @@ const int ServiceDescriptorProto::kOptionsFieldNumber;
ServiceDescriptorProto::ServiceDescriptorProto()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.ServiceDescriptorProto)
}
void ServiceDescriptorProto::InitAsDefaultInstance() {
@@ -3439,21 +4133,24 @@ ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& fro
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceDescriptorProto)
}
void ServiceDescriptorProto::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
options_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
ServiceDescriptorProto::~ServiceDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.ServiceDescriptorProto)
SharedDtor();
}
void ServiceDescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete name_;
}
if (this != default_instance_) {
@@ -3472,7 +4169,8 @@ const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() {
}
const ServiceDescriptorProto& ServiceDescriptorProto::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
ServiceDescriptorProto* ServiceDescriptorProto::default_instance_ = NULL;
@@ -3482,13 +4180,13 @@ ServiceDescriptorProto* ServiceDescriptorProto::New() const {
}
void ServiceDescriptorProto::Clear() {
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (_has_bits_[0 / 32] & 5) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
}
- if (_has_bit(2)) {
+ if (has_options()) {
if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
}
}
@@ -3499,60 +4197,63 @@ void ServiceDescriptorProto::Clear() {
bool ServiceDescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.ServiceDescriptorProto)
+ 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)) {
// optional string name = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "name");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(18)) goto parse_method;
break;
}
-
+
// repeated .google.protobuf.MethodDescriptorProto method = 2;
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 18) {
parse_method:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_method()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(18)) goto parse_method;
if (input->ExpectTag(26)) goto parse_options;
break;
}
-
+
// optional .google.protobuf.ServiceOptions options = 3;
case 3: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 26) {
parse_options:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, mutable_options()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -3560,75 +4261,86 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.ServiceDescriptorProto)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.ServiceDescriptorProto)
+ return false;
#undef DO_
}
void ServiceDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.ServiceDescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
}
-
+
// repeated .google.protobuf.MethodDescriptorProto method = 2;
for (int i = 0; i < this->method_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
2, this->method(i), output);
}
-
+
// optional .google.protobuf.ServiceOptions options = 3;
- if (_has_bit(2)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
3, this->options(), output);
}
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.ServiceDescriptorProto)
}
::google::protobuf::uint8* ServiceDescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceDescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
1, this->name(), target);
}
-
+
// repeated .google.protobuf.MethodDescriptorProto method = 2;
for (int i = 0; i < this->method_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
2, this->method(i), target);
}
-
+
// optional .google.protobuf.ServiceOptions options = 3;
- if (_has_bit(2)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
3, this->options(), target);
}
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceDescriptorProto)
return target;
}
int ServiceDescriptorProto::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// optional string name = 1;
if (has_name()) {
@@ -3636,14 +4348,14 @@ int ServiceDescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::StringSize(
this->name());
}
-
+
// optional .google.protobuf.ServiceOptions options = 3;
if (has_options()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->options());
}
-
+
}
// repeated .google.protobuf.MethodDescriptorProto method = 2;
total_size += 1 * this->method_size();
@@ -3652,7 +4364,7 @@ int ServiceDescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->method(i));
}
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -3680,10 +4392,10 @@ void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) {
GOOGLE_CHECK_NE(&from, this);
method_.MergeFrom(from.method_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(2)) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::ServiceOptions::MergeFrom(from.options());
}
}
@@ -3703,10 +4415,8 @@ void ServiceDescriptorProto::CopyFrom(const ServiceDescriptorProto& from) {
}
bool ServiceDescriptorProto::IsInitialized() const {
-
- for (int i = 0; i < method_size(); i++) {
- if (!this->method(i).IsInitialized()) return false;
- }
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->method())) return false;
if (has_options()) {
if (!this->options().IsInitialized()) return false;
}
@@ -3735,9 +4445,6 @@ void ServiceDescriptorProto::Swap(ServiceDescriptorProto* other) {
// ===================================================================
-const ::std::string MethodDescriptorProto::_default_name_;
-const ::std::string MethodDescriptorProto::_default_input_type_;
-const ::std::string MethodDescriptorProto::_default_output_type_;
#ifndef _MSC_VER
const int MethodDescriptorProto::kNameFieldNumber;
const int MethodDescriptorProto::kInputTypeFieldNumber;
@@ -3748,6 +4455,7 @@ const int MethodDescriptorProto::kOptionsFieldNumber;
MethodDescriptorProto::MethodDescriptorProto()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.MethodDescriptorProto)
}
void MethodDescriptorProto::InitAsDefaultInstance() {
@@ -3758,29 +4466,32 @@ MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodDescriptorProto)
}
void MethodDescriptorProto::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
- input_type_ = const_cast< ::std::string*>(&_default_input_type_);
- output_type_ = const_cast< ::std::string*>(&_default_output_type_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
options_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
MethodDescriptorProto::~MethodDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.MethodDescriptorProto)
SharedDtor();
}
void MethodDescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete name_;
}
- if (input_type_ != &_default_input_type_) {
+ if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete input_type_;
}
- if (output_type_ != &_default_output_type_) {
+ if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete output_type_;
}
if (this != default_instance_) {
@@ -3799,7 +4510,8 @@ const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() {
}
const MethodDescriptorProto& MethodDescriptorProto::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
MethodDescriptorProto* MethodDescriptorProto::default_instance_ = NULL;
@@ -3809,23 +4521,23 @@ MethodDescriptorProto* MethodDescriptorProto::New() const {
}
void MethodDescriptorProto::Clear() {
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (_has_bits_[0 / 32] & 15) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
}
- if (_has_bit(1)) {
- if (input_type_ != &_default_input_type_) {
+ if (has_input_type()) {
+ if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
input_type_->clear();
}
}
- if (_has_bit(2)) {
- if (output_type_ != &_default_output_type_) {
+ if (has_output_type()) {
+ if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
output_type_->clear();
}
}
- if (_has_bit(3)) {
+ if (has_options()) {
if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
}
}
@@ -3835,79 +4547,83 @@ void MethodDescriptorProto::Clear() {
bool MethodDescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.MethodDescriptorProto)
+ 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)) {
// optional string name = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "name");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(18)) goto parse_input_type;
break;
}
-
+
// optional string input_type = 2;
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 18) {
parse_input_type:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_input_type()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->input_type().data(), this->input_type().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "input_type");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(26)) goto parse_output_type;
break;
}
-
+
// optional string output_type = 3;
case 3: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 26) {
parse_output_type:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_output_type()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->output_type().data(), this->output_type().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "output_type");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(34)) goto parse_options;
break;
}
-
+
// optional .google.protobuf.MethodOptions options = 4;
case 4: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 34) {
parse_options:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, mutable_options()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -3915,100 +4631,115 @@ bool MethodDescriptorProto::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.MethodDescriptorProto)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.MethodDescriptorProto)
+ return false;
#undef DO_
}
void MethodDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.MethodDescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
}
-
+
// optional string input_type = 2;
- if (_has_bit(1)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_input_type()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->input_type().data(), this->input_type().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "input_type");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
2, this->input_type(), output);
}
-
+
// optional string output_type = 3;
- if (_has_bit(2)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_output_type()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->output_type().data(), this->output_type().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "output_type");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
3, this->output_type(), output);
}
-
+
// optional .google.protobuf.MethodOptions options = 4;
- if (_has_bit(3)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
4, this->options(), output);
}
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.MethodDescriptorProto)
}
::google::protobuf::uint8* MethodDescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodDescriptorProto)
// optional string name = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
1, this->name(), target);
}
-
+
// optional string input_type = 2;
- if (_has_bit(1)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_input_type()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->input_type().data(), this->input_type().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "input_type");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
2, this->input_type(), target);
}
-
+
// optional string output_type = 3;
- if (_has_bit(2)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_output_type()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->output_type().data(), this->output_type().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "output_type");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
3, this->output_type(), target);
}
-
+
// optional .google.protobuf.MethodOptions options = 4;
- if (_has_bit(3)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
4, this->options(), target);
}
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodDescriptorProto)
return target;
}
int MethodDescriptorProto::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// optional string name = 1;
if (has_name()) {
@@ -4016,28 +4747,28 @@ int MethodDescriptorProto::ByteSize() const {
::google::protobuf::internal::WireFormatLite::StringSize(
this->name());
}
-
+
// optional string input_type = 2;
if (has_input_type()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->input_type());
}
-
+
// optional string output_type = 3;
if (has_output_type()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->output_type());
}
-
+
// optional .google.protobuf.MethodOptions options = 4;
if (has_options()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->options());
}
-
+
}
if (!unknown_fields().empty()) {
total_size +=
@@ -4065,16 +4796,16 @@ void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(1)) {
+ if (from.has_input_type()) {
set_input_type(from.input_type());
}
- if (from._has_bit(2)) {
+ if (from.has_output_type()) {
set_output_type(from.output_type());
}
- if (from._has_bit(3)) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::MethodOptions::MergeFrom(from.options());
}
}
@@ -4094,7 +4825,7 @@ void MethodDescriptorProto::CopyFrom(const MethodDescriptorProto& from) {
}
bool MethodDescriptorProto::IsInitialized() const {
-
+
if (has_options()) {
if (!this->options().IsInitialized()) return false;
}
@@ -4147,22 +4878,25 @@ const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN;
const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
const int FileOptions::OptimizeMode_ARRAYSIZE;
#endif // _MSC_VER
-const ::std::string FileOptions::_default_java_package_;
-const ::std::string FileOptions::_default_java_outer_classname_;
#ifndef _MSC_VER
const int FileOptions::kJavaPackageFieldNumber;
const int FileOptions::kJavaOuterClassnameFieldNumber;
const int FileOptions::kJavaMultipleFilesFieldNumber;
+const int FileOptions::kJavaGenerateEqualsAndHashFieldNumber;
+const int FileOptions::kJavaStringCheckUtf8FieldNumber;
const int FileOptions::kOptimizeForFieldNumber;
+const int FileOptions::kGoPackageFieldNumber;
const int FileOptions::kCcGenericServicesFieldNumber;
const int FileOptions::kJavaGenericServicesFieldNumber;
const int FileOptions::kPyGenericServicesFieldNumber;
+const int FileOptions::kDeprecatedFieldNumber;
const int FileOptions::kUninterpretedOptionFieldNumber;
#endif // !_MSC_VER
FileOptions::FileOptions()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.FileOptions)
}
void FileOptions::InitAsDefaultInstance() {
@@ -4172,31 +4906,41 @@ FileOptions::FileOptions(const FileOptions& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FileOptions)
}
void FileOptions::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
- java_package_ = const_cast< ::std::string*>(&_default_java_package_);
- java_outer_classname_ = const_cast< ::std::string*>(&_default_java_outer_classname_);
+ java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
java_multiple_files_ = false;
+ java_generate_equals_and_hash_ = false;
+ java_string_check_utf8_ = false;
optimize_for_ = 1;
- cc_generic_services_ = true;
- java_generic_services_ = true;
- py_generic_services_ = true;
+ go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ cc_generic_services_ = false;
+ java_generic_services_ = false;
+ py_generic_services_ = false;
+ deprecated_ = false;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
FileOptions::~FileOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FileOptions)
SharedDtor();
}
void FileOptions::SharedDtor() {
- if (java_package_ != &_default_java_package_) {
+ if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete java_package_;
}
- if (java_outer_classname_ != &_default_java_outer_classname_) {
+ if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete java_outer_classname_;
}
+ if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete go_package_;
+ }
if (this != default_instance_) {
}
}
@@ -4212,7 +4956,8 @@ const ::google::protobuf::Descriptor* FileOptions::descriptor() {
}
const FileOptions& FileOptions::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
FileOptions* FileOptions::default_instance_ = NULL;
@@ -4223,23 +4968,40 @@ FileOptions* FileOptions::New() const {
void FileOptions::Clear() {
_extensions_.Clear();
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (java_package_ != &_default_java_package_) {
+#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
+ &reinterpret_cast<FileOptions*>(16)->f) - \
+ reinterpret_cast<char*>(16))
+
+#define ZR_(first, last) do { \
+ size_t f = OFFSET_OF_FIELD_(first); \
+ size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
+ ::memset(&first, 0, n); \
+ } while (0)
+
+ if (_has_bits_[0 / 32] & 255) {
+ ZR_(java_multiple_files_, cc_generic_services_);
+ if (has_java_package()) {
+ if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
java_package_->clear();
}
}
- if (_has_bit(1)) {
- if (java_outer_classname_ != &_default_java_outer_classname_) {
+ if (has_java_outer_classname()) {
+ if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
java_outer_classname_->clear();
}
}
- java_multiple_files_ = false;
optimize_for_ = 1;
- cc_generic_services_ = true;
- java_generic_services_ = true;
- py_generic_services_ = true;
+ if (has_go_package()) {
+ if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ go_package_->clear();
+ }
+ }
}
+ ZR_(java_generic_services_, deprecated_);
+
+#undef OFFSET_OF_FIELD_
+#undef ZR_
+
uninterpreted_option_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
mutable_unknown_fields()->Clear();
@@ -4247,47 +5009,50 @@ void FileOptions::Clear() {
bool FileOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.FileOptions)
+ 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)) {
// optional string java_package = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_java_package()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->java_package().data(), this->java_package().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "java_package");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(66)) goto parse_java_outer_classname;
break;
}
-
+
// optional string java_outer_classname = 8;
case 8: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 66) {
parse_java_outer_classname:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_java_outer_classname()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->java_outer_classname().data(), this->java_outer_classname().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "java_outer_classname");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(72)) goto parse_optimize_for;
break;
}
-
+
// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
case 9: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 72) {
parse_optimize_for:
int value;
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
@@ -4299,96 +5064,154 @@ bool FileOptions::MergePartialFromCodedStream(
mutable_unknown_fields()->AddVarint(9, value);
}
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(80)) goto parse_java_multiple_files;
break;
}
-
+
// optional bool java_multiple_files = 10 [default = false];
case 10: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 80) {
parse_java_multiple_files:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &java_multiple_files_)));
- _set_bit(2);
+ set_has_java_multiple_files();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(90)) goto parse_go_package;
+ break;
+ }
+
+ // optional string go_package = 11;
+ case 11: {
+ if (tag == 90) {
+ parse_go_package:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_go_package()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->go_package().data(), this->go_package().length(),
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "go_package");
+ } else {
+ goto handle_unusual;
}
if (input->ExpectTag(128)) goto parse_cc_generic_services;
break;
}
-
- // optional bool cc_generic_services = 16 [default = true];
+
+ // optional bool cc_generic_services = 16 [default = false];
case 16: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 128) {
parse_cc_generic_services:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &cc_generic_services_)));
- _set_bit(4);
+ set_has_cc_generic_services();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(136)) goto parse_java_generic_services;
break;
}
-
- // optional bool java_generic_services = 17 [default = true];
+
+ // optional bool java_generic_services = 17 [default = false];
case 17: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 136) {
parse_java_generic_services:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &java_generic_services_)));
- _set_bit(5);
+ set_has_java_generic_services();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(144)) goto parse_py_generic_services;
break;
}
-
- // optional bool py_generic_services = 18 [default = true];
+
+ // optional bool py_generic_services = 18 [default = false];
case 18: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 144) {
parse_py_generic_services:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &py_generic_services_)));
- _set_bit(6);
+ set_has_py_generic_services();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(160)) goto parse_java_generate_equals_and_hash;
+ break;
+ }
+
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ case 20: {
+ if (tag == 160) {
+ parse_java_generate_equals_and_hash:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &java_generate_equals_and_hash_)));
+ set_has_java_generate_equals_and_hash();
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(184)) goto parse_deprecated;
+ break;
+ }
+
+ // optional bool deprecated = 23 [default = false];
+ case 23: {
+ if (tag == 184) {
+ parse_deprecated:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &deprecated_)));
+ set_has_deprecated();
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(216)) goto parse_java_string_check_utf8;
+ break;
+ }
+
+ // optional bool java_string_check_utf8 = 27 [default = false];
+ case 27: {
+ if (tag == 216) {
+ parse_java_string_check_utf8:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &java_string_check_utf8_)));
+ set_has_java_string_check_utf8();
+ } else {
+ goto handle_unusual;
}
if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
break;
}
-
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
case 999: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 7994) {
parse_uninterpreted_option:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_uninterpreted_option()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
if ((8000u <= tag)) {
DO_(_extensions_.ParseField(tag, input, default_instance_,
@@ -4401,141 +5224,205 @@ bool FileOptions::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.FileOptions)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.FileOptions)
+ return false;
#undef DO_
}
void FileOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.FileOptions)
// optional string java_package = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_java_package()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->java_package().data(), this->java_package().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "java_package");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->java_package(), output);
}
-
+
// optional string java_outer_classname = 8;
- if (_has_bit(1)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_java_outer_classname()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->java_outer_classname().data(), this->java_outer_classname().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "java_outer_classname");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
8, this->java_outer_classname(), output);
}
-
+
// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
- if (_has_bit(3)) {
+ if (has_optimize_for()) {
::google::protobuf::internal::WireFormatLite::WriteEnum(
9, this->optimize_for(), output);
}
-
+
// optional bool java_multiple_files = 10 [default = false];
- if (_has_bit(2)) {
+ if (has_java_multiple_files()) {
::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output);
}
-
- // optional bool cc_generic_services = 16 [default = true];
- if (_has_bit(4)) {
+
+ // optional string go_package = 11;
+ if (has_go_package()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->go_package().data(), this->go_package().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "go_package");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+ 11, this->go_package(), output);
+ }
+
+ // optional bool cc_generic_services = 16 [default = false];
+ if (has_cc_generic_services()) {
::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output);
}
-
- // optional bool java_generic_services = 17 [default = true];
- if (_has_bit(5)) {
+
+ // optional bool java_generic_services = 17 [default = false];
+ if (has_java_generic_services()) {
::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output);
}
-
- // optional bool py_generic_services = 18 [default = true];
- if (_has_bit(6)) {
+
+ // optional bool py_generic_services = 18 [default = false];
+ if (has_py_generic_services()) {
::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output);
}
-
+
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ if (has_java_generate_equals_and_hash()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(20, this->java_generate_equals_and_hash(), output);
+ }
+
+ // optional bool deprecated = 23 [default = false];
+ if (has_deprecated()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(23, this->deprecated(), output);
+ }
+
+ // optional bool java_string_check_utf8 = 27 [default = false];
+ if (has_java_string_check_utf8()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(27, this->java_string_check_utf8(), output);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
999, this->uninterpreted_option(i), output);
}
-
+
// Extension range [1000, 536870912)
_extensions_.SerializeWithCachedSizes(
1000, 536870912, output);
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.FileOptions)
}
::google::protobuf::uint8* FileOptions::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileOptions)
// optional string java_package = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_java_package()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->java_package().data(), this->java_package().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "java_package");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
1, this->java_package(), target);
}
-
+
// optional string java_outer_classname = 8;
- if (_has_bit(1)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_java_outer_classname()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->java_outer_classname().data(), this->java_outer_classname().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "java_outer_classname");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
8, this->java_outer_classname(), target);
}
-
+
// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
- if (_has_bit(3)) {
+ if (has_optimize_for()) {
target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
9, this->optimize_for(), target);
}
-
+
// optional bool java_multiple_files = 10 [default = false];
- if (_has_bit(2)) {
+ if (has_java_multiple_files()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target);
}
-
- // optional bool cc_generic_services = 16 [default = true];
- if (_has_bit(4)) {
+
+ // optional string go_package = 11;
+ if (has_go_package()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->go_package().data(), this->go_package().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "go_package");
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 11, this->go_package(), target);
+ }
+
+ // optional bool cc_generic_services = 16 [default = false];
+ if (has_cc_generic_services()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target);
}
-
- // optional bool java_generic_services = 17 [default = true];
- if (_has_bit(5)) {
+
+ // optional bool java_generic_services = 17 [default = false];
+ if (has_java_generic_services()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target);
}
-
- // optional bool py_generic_services = 18 [default = true];
- if (_has_bit(6)) {
+
+ // optional bool py_generic_services = 18 [default = false];
+ if (has_py_generic_services()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target);
}
-
+
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ if (has_java_generate_equals_and_hash()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(20, this->java_generate_equals_and_hash(), target);
+ }
+
+ // optional bool deprecated = 23 [default = false];
+ if (has_deprecated()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(23, this->deprecated(), target);
+ }
+
+ // optional bool java_string_check_utf8 = 27 [default = false];
+ if (has_java_string_check_utf8()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(27, this->java_string_check_utf8(), target);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
999, this->uninterpreted_option(i), target);
}
-
+
// Extension range [1000, 536870912)
target = _extensions_.SerializeWithCachedSizesToArray(
1000, 536870912, target);
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileOptions)
return target;
}
int FileOptions::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// optional string java_package = 1;
if (has_java_package()) {
@@ -4543,40 +5430,64 @@ int FileOptions::ByteSize() const {
::google::protobuf::internal::WireFormatLite::StringSize(
this->java_package());
}
-
+
// optional string java_outer_classname = 8;
if (has_java_outer_classname()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->java_outer_classname());
}
-
+
// optional bool java_multiple_files = 10 [default = false];
if (has_java_multiple_files()) {
total_size += 1 + 1;
}
-
+
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ if (has_java_generate_equals_and_hash()) {
+ total_size += 2 + 1;
+ }
+
+ // optional bool java_string_check_utf8 = 27 [default = false];
+ if (has_java_string_check_utf8()) {
+ total_size += 2 + 1;
+ }
+
// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
if (has_optimize_for()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::EnumSize(this->optimize_for());
}
-
- // optional bool cc_generic_services = 16 [default = true];
+
+ // optional string go_package = 11;
+ if (has_go_package()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->go_package());
+ }
+
+ // optional bool cc_generic_services = 16 [default = false];
if (has_cc_generic_services()) {
total_size += 2 + 1;
}
-
- // optional bool java_generic_services = 17 [default = true];
+
+ }
+ if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ // optional bool java_generic_services = 17 [default = false];
if (has_java_generic_services()) {
total_size += 2 + 1;
}
-
- // optional bool py_generic_services = 18 [default = true];
+
+ // optional bool py_generic_services = 18 [default = false];
if (has_py_generic_services()) {
total_size += 2 + 1;
}
-
+
+ // optional bool deprecated = 23 [default = false];
+ if (has_deprecated()) {
+ total_size += 2 + 1;
+ }
+
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
total_size += 2 * this->uninterpreted_option_size();
@@ -4585,9 +5496,9 @@ int FileOptions::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->uninterpreted_option(i));
}
-
+
total_size += _extensions_.ByteSize();
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -4615,27 +5526,41 @@ void FileOptions::MergeFrom(const FileOptions& from) {
GOOGLE_CHECK_NE(&from, this);
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_java_package()) {
set_java_package(from.java_package());
}
- if (from._has_bit(1)) {
+ if (from.has_java_outer_classname()) {
set_java_outer_classname(from.java_outer_classname());
}
- if (from._has_bit(2)) {
+ if (from.has_java_multiple_files()) {
set_java_multiple_files(from.java_multiple_files());
}
- if (from._has_bit(3)) {
+ if (from.has_java_generate_equals_and_hash()) {
+ set_java_generate_equals_and_hash(from.java_generate_equals_and_hash());
+ }
+ if (from.has_java_string_check_utf8()) {
+ set_java_string_check_utf8(from.java_string_check_utf8());
+ }
+ if (from.has_optimize_for()) {
set_optimize_for(from.optimize_for());
}
- if (from._has_bit(4)) {
+ if (from.has_go_package()) {
+ set_go_package(from.go_package());
+ }
+ if (from.has_cc_generic_services()) {
set_cc_generic_services(from.cc_generic_services());
}
- if (from._has_bit(5)) {
+ }
+ if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ if (from.has_java_generic_services()) {
set_java_generic_services(from.java_generic_services());
}
- if (from._has_bit(6)) {
+ if (from.has_py_generic_services()) {
set_py_generic_services(from.py_generic_services());
}
+ if (from.has_deprecated()) {
+ set_deprecated(from.deprecated());
+ }
}
_extensions_.MergeFrom(from._extensions_);
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
@@ -4654,11 +5579,9 @@ void FileOptions::CopyFrom(const FileOptions& from) {
}
bool FileOptions::IsInitialized() const {
-
- for (int i = 0; i < uninterpreted_option_size(); i++) {
- if (!this->uninterpreted_option(i).IsInitialized()) return false;
- }
-
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
if (!_extensions_.IsInitialized()) return false; return true;
}
@@ -4667,10 +5590,14 @@ void FileOptions::Swap(FileOptions* other) {
std::swap(java_package_, other->java_package_);
std::swap(java_outer_classname_, other->java_outer_classname_);
std::swap(java_multiple_files_, other->java_multiple_files_);
+ std::swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_);
+ std::swap(java_string_check_utf8_, other->java_string_check_utf8_);
std::swap(optimize_for_, other->optimize_for_);
+ std::swap(go_package_, other->go_package_);
std::swap(cc_generic_services_, other->cc_generic_services_);
std::swap(java_generic_services_, other->java_generic_services_);
std::swap(py_generic_services_, other->py_generic_services_);
+ std::swap(deprecated_, other->deprecated_);
uninterpreted_option_.Swap(&other->uninterpreted_option_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
@@ -4693,12 +5620,14 @@ void FileOptions::Swap(FileOptions* other) {
#ifndef _MSC_VER
const int MessageOptions::kMessageSetWireFormatFieldNumber;
const int MessageOptions::kNoStandardDescriptorAccessorFieldNumber;
+const int MessageOptions::kDeprecatedFieldNumber;
const int MessageOptions::kUninterpretedOptionFieldNumber;
#endif // !_MSC_VER
MessageOptions::MessageOptions()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.MessageOptions)
}
void MessageOptions::InitAsDefaultInstance() {
@@ -4708,16 +5637,19 @@ MessageOptions::MessageOptions(const MessageOptions& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.MessageOptions)
}
void MessageOptions::SharedCtor() {
_cached_size_ = 0;
message_set_wire_format_ = false;
no_standard_descriptor_accessor_ = false;
+ deprecated_ = false;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
MessageOptions::~MessageOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.MessageOptions)
SharedDtor();
}
@@ -4737,7 +5669,8 @@ const ::google::protobuf::Descriptor* MessageOptions::descriptor() {
}
const MessageOptions& MessageOptions::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
MessageOptions* MessageOptions::default_instance_ = NULL;
@@ -4748,10 +5681,21 @@ MessageOptions* MessageOptions::New() const {
void MessageOptions::Clear() {
_extensions_.Clear();
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- message_set_wire_format_ = false;
- no_standard_descriptor_accessor_ = false;
- }
+#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
+ &reinterpret_cast<MessageOptions*>(16)->f) - \
+ reinterpret_cast<char*>(16))
+
+#define ZR_(first, last) do { \
+ size_t f = OFFSET_OF_FIELD_(first); \
+ size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
+ ::memset(&first, 0, n); \
+ } while (0)
+
+ ZR_(message_set_wire_format_, deprecated_);
+
+#undef OFFSET_OF_FIELD_
+#undef ZR_
+
uninterpreted_option_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
mutable_unknown_fields()->Clear();
@@ -4759,61 +5703,78 @@ void MessageOptions::Clear() {
bool MessageOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.MessageOptions)
+ 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)) {
// optional bool message_set_wire_format = 1 [default = false];
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 8) {
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &message_set_wire_format_)));
- _set_bit(0);
+ set_has_message_set_wire_format();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(16)) goto parse_no_standard_descriptor_accessor;
break;
}
-
+
// optional bool no_standard_descriptor_accessor = 2 [default = false];
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 16) {
parse_no_standard_descriptor_accessor:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &no_standard_descriptor_accessor_)));
- _set_bit(1);
+ set_has_no_standard_descriptor_accessor();
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(24)) goto parse_deprecated;
+ break;
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ case 3: {
+ if (tag == 24) {
+ parse_deprecated:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &deprecated_)));
+ set_has_deprecated();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
break;
}
-
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
case 999: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 7994) {
parse_uninterpreted_option:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_uninterpreted_option()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
if ((8000u <= tag)) {
DO_(_extensions_.ParseField(tag, input, default_instance_,
@@ -4826,82 +5787,106 @@ bool MessageOptions::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.MessageOptions)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.MessageOptions)
+ return false;
#undef DO_
}
void MessageOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.MessageOptions)
// optional bool message_set_wire_format = 1 [default = false];
- if (_has_bit(0)) {
+ if (has_message_set_wire_format()) {
::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output);
}
-
+
// optional bool no_standard_descriptor_accessor = 2 [default = false];
- if (_has_bit(1)) {
+ if (has_no_standard_descriptor_accessor()) {
::google::protobuf::internal::WireFormatLite::WriteBool(2, this->no_standard_descriptor_accessor(), output);
}
-
+
+ // optional bool deprecated = 3 [default = false];
+ if (has_deprecated()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
999, this->uninterpreted_option(i), output);
}
-
+
// Extension range [1000, 536870912)
_extensions_.SerializeWithCachedSizes(
1000, 536870912, output);
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.MessageOptions)
}
::google::protobuf::uint8* MessageOptions::SerializeWithCachedSizesToArray(
::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_bit(0)) {
+ if (has_message_set_wire_format()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->message_set_wire_format(), target);
}
-
+
// optional bool no_standard_descriptor_accessor = 2 [default = false];
- if (_has_bit(1)) {
+ if (has_no_standard_descriptor_accessor()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->no_standard_descriptor_accessor(), target);
}
-
+
+ // optional bool deprecated = 3 [default = false];
+ if (has_deprecated()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
999, this->uninterpreted_option(i), target);
}
-
+
// Extension range [1000, 536870912)
target = _extensions_.SerializeWithCachedSizesToArray(
1000, 536870912, target);
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MessageOptions)
return target;
}
int MessageOptions::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// optional bool message_set_wire_format = 1 [default = false];
if (has_message_set_wire_format()) {
total_size += 1 + 1;
}
-
+
// optional bool no_standard_descriptor_accessor = 2 [default = false];
if (has_no_standard_descriptor_accessor()) {
total_size += 1 + 1;
}
-
+
+ // optional bool deprecated = 3 [default = false];
+ if (has_deprecated()) {
+ total_size += 1 + 1;
+ }
+
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
total_size += 2 * this->uninterpreted_option_size();
@@ -4910,9 +5895,9 @@ int MessageOptions::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->uninterpreted_option(i));
}
-
+
total_size += _extensions_.ByteSize();
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -4940,12 +5925,15 @@ void MessageOptions::MergeFrom(const MessageOptions& from) {
GOOGLE_CHECK_NE(&from, this);
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_message_set_wire_format()) {
set_message_set_wire_format(from.message_set_wire_format());
}
- if (from._has_bit(1)) {
+ if (from.has_no_standard_descriptor_accessor()) {
set_no_standard_descriptor_accessor(from.no_standard_descriptor_accessor());
}
+ if (from.has_deprecated()) {
+ set_deprecated(from.deprecated());
+ }
}
_extensions_.MergeFrom(from._extensions_);
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
@@ -4964,11 +5952,9 @@ void MessageOptions::CopyFrom(const MessageOptions& from) {
}
bool MessageOptions::IsInitialized() const {
-
- for (int i = 0; i < uninterpreted_option_size(); i++) {
- if (!this->uninterpreted_option(i).IsInitialized()) return false;
- }
-
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
if (!_extensions_.IsInitialized()) return false; return true;
}
@@ -4976,6 +5962,7 @@ void MessageOptions::Swap(MessageOptions* other) {
if (other != this) {
std::swap(message_set_wire_format_, other->message_set_wire_format_);
std::swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_);
+ std::swap(deprecated_, other->deprecated_);
uninterpreted_option_.Swap(&other->uninterpreted_option_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
@@ -5018,18 +6005,20 @@ const FieldOptions_CType FieldOptions::CType_MIN;
const FieldOptions_CType FieldOptions::CType_MAX;
const int FieldOptions::CType_ARRAYSIZE;
#endif // _MSC_VER
-const ::std::string FieldOptions::_default_experimental_map_key_;
#ifndef _MSC_VER
const int FieldOptions::kCtypeFieldNumber;
const int FieldOptions::kPackedFieldNumber;
+const int FieldOptions::kLazyFieldNumber;
const int FieldOptions::kDeprecatedFieldNumber;
const int FieldOptions::kExperimentalMapKeyFieldNumber;
+const int FieldOptions::kWeakFieldNumber;
const int FieldOptions::kUninterpretedOptionFieldNumber;
#endif // !_MSC_VER
FieldOptions::FieldOptions()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.FieldOptions)
}
void FieldOptions::InitAsDefaultInstance() {
@@ -5039,23 +6028,28 @@ FieldOptions::FieldOptions(const FieldOptions& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldOptions)
}
void FieldOptions::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
ctype_ = 0;
packed_ = false;
+ lazy_ = false;
deprecated_ = false;
- experimental_map_key_ = const_cast< ::std::string*>(&_default_experimental_map_key_);
+ experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ weak_ = false;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
FieldOptions::~FieldOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FieldOptions)
SharedDtor();
}
void FieldOptions::SharedDtor() {
- if (experimental_map_key_ != &_default_experimental_map_key_) {
+ if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete experimental_map_key_;
}
if (this != default_instance_) {
@@ -5073,7 +6067,8 @@ const ::google::protobuf::Descriptor* FieldOptions::descriptor() {
}
const FieldOptions& FieldOptions::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
FieldOptions* FieldOptions::default_instance_ = NULL;
@@ -5084,16 +6079,28 @@ FieldOptions* FieldOptions::New() const {
void FieldOptions::Clear() {
_extensions_.Clear();
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- ctype_ = 0;
- packed_ = false;
- deprecated_ = false;
- if (_has_bit(3)) {
- if (experimental_map_key_ != &_default_experimental_map_key_) {
+#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
+ &reinterpret_cast<FieldOptions*>(16)->f) - \
+ reinterpret_cast<char*>(16))
+
+#define ZR_(first, last) do { \
+ size_t f = OFFSET_OF_FIELD_(first); \
+ size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
+ ::memset(&first, 0, n); \
+ } while (0)
+
+ if (_has_bits_[0 / 32] & 63) {
+ ZR_(ctype_, weak_);
+ if (has_experimental_map_key()) {
+ if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
experimental_map_key_->clear();
}
}
}
+
+#undef OFFSET_OF_FIELD_
+#undef ZR_
+
uninterpreted_option_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
mutable_unknown_fields()->Clear();
@@ -5101,14 +6108,17 @@ void FieldOptions::Clear() {
bool FieldOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.FieldOptions)
+ 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)) {
// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 8) {
int value;
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -5119,81 +6129,109 @@ bool FieldOptions::MergePartialFromCodedStream(
mutable_unknown_fields()->AddVarint(1, value);
}
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(16)) goto parse_packed;
break;
}
-
+
// optional bool packed = 2;
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 16) {
parse_packed:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &packed_)));
- _set_bit(1);
+ set_has_packed();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(24)) goto parse_deprecated;
break;
}
-
+
// optional bool deprecated = 3 [default = false];
case 3: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 24) {
parse_deprecated:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &deprecated_)));
- _set_bit(2);
+ set_has_deprecated();
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(40)) goto parse_lazy;
+ break;
+ }
+
+ // optional bool lazy = 5 [default = false];
+ case 5: {
+ if (tag == 40) {
+ parse_lazy:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &lazy_)));
+ set_has_lazy();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(74)) goto parse_experimental_map_key;
break;
}
-
+
// optional string experimental_map_key = 9;
case 9: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 74) {
parse_experimental_map_key:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_experimental_map_key()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->experimental_map_key().data(), this->experimental_map_key().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "experimental_map_key");
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(80)) goto parse_weak;
+ break;
+ }
+
+ // optional bool weak = 10 [default = false];
+ case 10: {
+ if (tag == 80) {
+ parse_weak:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &weak_)));
+ set_has_weak();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
break;
}
-
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
case 999: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 7994) {
parse_uninterpreted_option:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_uninterpreted_option()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
if ((8000u <= tag)) {
DO_(_extensions_.ParseField(tag, input, default_instance_,
@@ -5206,126 +6244,167 @@ bool FieldOptions::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.FieldOptions)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.FieldOptions)
+ return false;
#undef DO_
}
void FieldOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.FieldOptions)
// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
- if (_has_bit(0)) {
+ if (has_ctype()) {
::google::protobuf::internal::WireFormatLite::WriteEnum(
1, this->ctype(), output);
}
-
+
// optional bool packed = 2;
- if (_has_bit(1)) {
+ if (has_packed()) {
::google::protobuf::internal::WireFormatLite::WriteBool(2, this->packed(), output);
}
-
+
// optional bool deprecated = 3 [default = false];
- if (_has_bit(2)) {
+ if (has_deprecated()) {
::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
}
-
+
+ // optional bool lazy = 5 [default = false];
+ if (has_lazy()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->lazy(), output);
+ }
+
// optional string experimental_map_key = 9;
- if (_has_bit(3)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_experimental_map_key()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->experimental_map_key().data(), this->experimental_map_key().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "experimental_map_key");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
9, this->experimental_map_key(), output);
}
-
+
+ // optional bool weak = 10 [default = false];
+ if (has_weak()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->weak(), output);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
999, this->uninterpreted_option(i), output);
}
-
+
// Extension range [1000, 536870912)
_extensions_.SerializeWithCachedSizes(
1000, 536870912, output);
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.FieldOptions)
}
::google::protobuf::uint8* FieldOptions::SerializeWithCachedSizesToArray(
::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_bit(0)) {
+ if (has_ctype()) {
target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
1, this->ctype(), target);
}
-
+
// optional bool packed = 2;
- if (_has_bit(1)) {
+ if (has_packed()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->packed(), target);
}
-
+
// optional bool deprecated = 3 [default = false];
- if (_has_bit(2)) {
+ if (has_deprecated()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
}
-
+
+ // optional bool lazy = 5 [default = false];
+ if (has_lazy()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->lazy(), target);
+ }
+
// optional string experimental_map_key = 9;
- if (_has_bit(3)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_experimental_map_key()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->experimental_map_key().data(), this->experimental_map_key().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "experimental_map_key");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
9, this->experimental_map_key(), target);
}
-
+
+ // optional bool weak = 10 [default = false];
+ if (has_weak()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->weak(), target);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
999, this->uninterpreted_option(i), target);
}
-
+
// Extension range [1000, 536870912)
target = _extensions_.SerializeWithCachedSizesToArray(
1000, 536870912, target);
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldOptions)
return target;
}
int FieldOptions::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
if (has_ctype()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::EnumSize(this->ctype());
}
-
+
// optional bool packed = 2;
if (has_packed()) {
total_size += 1 + 1;
}
-
+
+ // optional bool lazy = 5 [default = false];
+ if (has_lazy()) {
+ total_size += 1 + 1;
+ }
+
// optional bool deprecated = 3 [default = false];
if (has_deprecated()) {
total_size += 1 + 1;
}
-
+
// optional string experimental_map_key = 9;
if (has_experimental_map_key()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->experimental_map_key());
}
-
+
+ // optional bool weak = 10 [default = false];
+ if (has_weak()) {
+ total_size += 1 + 1;
+ }
+
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
total_size += 2 * this->uninterpreted_option_size();
@@ -5334,9 +6413,9 @@ int FieldOptions::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->uninterpreted_option(i));
}
-
+
total_size += _extensions_.ByteSize();
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -5364,18 +6443,24 @@ void FieldOptions::MergeFrom(const FieldOptions& from) {
GOOGLE_CHECK_NE(&from, this);
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_ctype()) {
set_ctype(from.ctype());
}
- if (from._has_bit(1)) {
+ if (from.has_packed()) {
set_packed(from.packed());
}
- if (from._has_bit(2)) {
+ if (from.has_lazy()) {
+ set_lazy(from.lazy());
+ }
+ if (from.has_deprecated()) {
set_deprecated(from.deprecated());
}
- if (from._has_bit(3)) {
+ if (from.has_experimental_map_key()) {
set_experimental_map_key(from.experimental_map_key());
}
+ if (from.has_weak()) {
+ set_weak(from.weak());
+ }
}
_extensions_.MergeFrom(from._extensions_);
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
@@ -5394,11 +6479,9 @@ void FieldOptions::CopyFrom(const FieldOptions& from) {
}
bool FieldOptions::IsInitialized() const {
-
- for (int i = 0; i < uninterpreted_option_size(); i++) {
- if (!this->uninterpreted_option(i).IsInitialized()) return false;
- }
-
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
if (!_extensions_.IsInitialized()) return false; return true;
}
@@ -5406,8 +6489,10 @@ void FieldOptions::Swap(FieldOptions* other) {
if (other != this) {
std::swap(ctype_, other->ctype_);
std::swap(packed_, other->packed_);
+ std::swap(lazy_, other->lazy_);
std::swap(deprecated_, other->deprecated_);
std::swap(experimental_map_key_, other->experimental_map_key_);
+ std::swap(weak_, other->weak_);
uninterpreted_option_.Swap(&other->uninterpreted_option_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
@@ -5428,12 +6513,15 @@ void FieldOptions::Swap(FieldOptions* other) {
// ===================================================================
#ifndef _MSC_VER
+const int EnumOptions::kAllowAliasFieldNumber;
+const int EnumOptions::kDeprecatedFieldNumber;
const int EnumOptions::kUninterpretedOptionFieldNumber;
#endif // !_MSC_VER
EnumOptions::EnumOptions()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.EnumOptions)
}
void EnumOptions::InitAsDefaultInstance() {
@@ -5443,14 +6531,18 @@ EnumOptions::EnumOptions(const EnumOptions& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumOptions)
}
void EnumOptions::SharedCtor() {
_cached_size_ = 0;
+ allow_alias_ = false;
+ deprecated_ = false;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
EnumOptions::~EnumOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumOptions)
SharedDtor();
}
@@ -5470,7 +6562,8 @@ const ::google::protobuf::Descriptor* EnumOptions::descriptor() {
}
const EnumOptions& EnumOptions::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
EnumOptions* EnumOptions::default_instance_ = NULL;
@@ -5481,6 +6574,21 @@ EnumOptions* EnumOptions::New() const {
void EnumOptions::Clear() {
_extensions_.Clear();
+#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
+ &reinterpret_cast<EnumOptions*>(16)->f) - \
+ reinterpret_cast<char*>(16))
+
+#define ZR_(first, last) do { \
+ size_t f = OFFSET_OF_FIELD_(first); \
+ size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
+ ::memset(&first, 0, n); \
+ } while (0)
+
+ ZR_(allow_alias_, deprecated_);
+
+#undef OFFSET_OF_FIELD_
+#undef ZR_
+
uninterpreted_option_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
mutable_unknown_fields()->Clear();
@@ -5488,30 +6596,63 @@ void EnumOptions::Clear() {
bool EnumOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.EnumOptions)
+ 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)) {
+ // optional bool allow_alias = 2;
+ case 2: {
+ if (tag == 16) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &allow_alias_)));
+ set_has_allow_alias();
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(24)) goto parse_deprecated;
+ break;
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ case 3: {
+ if (tag == 24) {
+ parse_deprecated:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &deprecated_)));
+ set_has_deprecated();
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ break;
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
case 999: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 7994) {
parse_uninterpreted_option:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_uninterpreted_option()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
if ((8000u <= tag)) {
DO_(_extensions_.ParseField(tag, input, default_instance_,
@@ -5524,51 +6665,92 @@ bool EnumOptions::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.EnumOptions)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.EnumOptions)
+ return false;
#undef DO_
}
void EnumOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.EnumOptions)
+ // optional bool allow_alias = 2;
+ if (has_allow_alias()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->allow_alias(), output);
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (has_deprecated()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
999, this->uninterpreted_option(i), output);
}
-
+
// Extension range [1000, 536870912)
_extensions_.SerializeWithCachedSizes(
1000, 536870912, output);
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.EnumOptions)
}
::google::protobuf::uint8* EnumOptions::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumOptions)
+ // optional bool allow_alias = 2;
+ if (has_allow_alias()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->allow_alias(), target);
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (has_deprecated()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
999, this->uninterpreted_option(i), target);
}
-
+
// Extension range [1000, 536870912)
target = _extensions_.SerializeWithCachedSizesToArray(
1000, 536870912, target);
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumOptions)
return target;
}
int EnumOptions::ByteSize() const {
int total_size = 0;
-
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional bool allow_alias = 2;
+ if (has_allow_alias()) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (has_deprecated()) {
+ total_size += 1 + 1;
+ }
+
+ }
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
total_size += 2 * this->uninterpreted_option_size();
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
@@ -5576,9 +6758,9 @@ int EnumOptions::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->uninterpreted_option(i));
}
-
+
total_size += _extensions_.ByteSize();
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -5605,6 +6787,14 @@ void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) {
void EnumOptions::MergeFrom(const EnumOptions& from) {
GOOGLE_CHECK_NE(&from, this);
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_allow_alias()) {
+ set_allow_alias(from.allow_alias());
+ }
+ if (from.has_deprecated()) {
+ set_deprecated(from.deprecated());
+ }
+ }
_extensions_.MergeFrom(from._extensions_);
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}
@@ -5622,16 +6812,16 @@ void EnumOptions::CopyFrom(const EnumOptions& from) {
}
bool EnumOptions::IsInitialized() const {
-
- for (int i = 0; i < uninterpreted_option_size(); i++) {
- if (!this->uninterpreted_option(i).IsInitialized()) return false;
- }
-
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
if (!_extensions_.IsInitialized()) return false; return true;
}
void EnumOptions::Swap(EnumOptions* other) {
if (other != this) {
+ std::swap(allow_alias_, other->allow_alias_);
+ std::swap(deprecated_, other->deprecated_);
uninterpreted_option_.Swap(&other->uninterpreted_option_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
@@ -5652,12 +6842,14 @@ void EnumOptions::Swap(EnumOptions* other) {
// ===================================================================
#ifndef _MSC_VER
+const int EnumValueOptions::kDeprecatedFieldNumber;
const int EnumValueOptions::kUninterpretedOptionFieldNumber;
#endif // !_MSC_VER
EnumValueOptions::EnumValueOptions()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.EnumValueOptions)
}
void EnumValueOptions::InitAsDefaultInstance() {
@@ -5667,14 +6859,17 @@ EnumValueOptions::EnumValueOptions(const EnumValueOptions& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueOptions)
}
void EnumValueOptions::SharedCtor() {
_cached_size_ = 0;
+ deprecated_ = false;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
EnumValueOptions::~EnumValueOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumValueOptions)
SharedDtor();
}
@@ -5694,7 +6889,8 @@ const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() {
}
const EnumValueOptions& EnumValueOptions::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
EnumValueOptions* EnumValueOptions::default_instance_ = NULL;
@@ -5705,6 +6901,7 @@ EnumValueOptions* EnumValueOptions::New() const {
void EnumValueOptions::Clear() {
_extensions_.Clear();
+ deprecated_ = false;
uninterpreted_option_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
mutable_unknown_fields()->Clear();
@@ -5712,30 +6909,48 @@ void EnumValueOptions::Clear() {
bool EnumValueOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.EnumValueOptions)
+ 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)) {
+ // optional bool deprecated = 1 [default = false];
+ case 1: {
+ if (tag == 8) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &deprecated_)));
+ set_has_deprecated();
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ break;
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
case 999: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 7994) {
parse_uninterpreted_option:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_uninterpreted_option()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
if ((8000u <= tag)) {
DO_(_extensions_.ParseField(tag, input, default_instance_,
@@ -5748,51 +6963,77 @@ bool EnumValueOptions::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.EnumValueOptions)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.EnumValueOptions)
+ return false;
#undef DO_
}
void EnumValueOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValueOptions)
+ // optional bool deprecated = 1 [default = false];
+ if (has_deprecated()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->deprecated(), output);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
999, this->uninterpreted_option(i), output);
}
-
+
// Extension range [1000, 536870912)
_extensions_.SerializeWithCachedSizes(
1000, 536870912, output);
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueOptions)
}
::google::protobuf::uint8* EnumValueOptions::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueOptions)
+ // optional bool deprecated = 1 [default = false];
+ if (has_deprecated()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->deprecated(), target);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
999, this->uninterpreted_option(i), target);
}
-
+
// Extension range [1000, 536870912)
target = _extensions_.SerializeWithCachedSizesToArray(
1000, 536870912, target);
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueOptions)
return target;
}
int EnumValueOptions::ByteSize() const {
int total_size = 0;
-
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional bool deprecated = 1 [default = false];
+ if (has_deprecated()) {
+ total_size += 1 + 1;
+ }
+
+ }
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
total_size += 2 * this->uninterpreted_option_size();
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
@@ -5800,9 +7041,9 @@ int EnumValueOptions::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->uninterpreted_option(i));
}
-
+
total_size += _extensions_.ByteSize();
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -5829,6 +7070,11 @@ void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) {
void EnumValueOptions::MergeFrom(const EnumValueOptions& from) {
GOOGLE_CHECK_NE(&from, this);
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_deprecated()) {
+ set_deprecated(from.deprecated());
+ }
+ }
_extensions_.MergeFrom(from._extensions_);
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}
@@ -5846,16 +7092,15 @@ void EnumValueOptions::CopyFrom(const EnumValueOptions& from) {
}
bool EnumValueOptions::IsInitialized() const {
-
- for (int i = 0; i < uninterpreted_option_size(); i++) {
- if (!this->uninterpreted_option(i).IsInitialized()) return false;
- }
-
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
if (!_extensions_.IsInitialized()) return false; return true;
}
void EnumValueOptions::Swap(EnumValueOptions* other) {
if (other != this) {
+ std::swap(deprecated_, other->deprecated_);
uninterpreted_option_.Swap(&other->uninterpreted_option_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
@@ -5876,12 +7121,14 @@ void EnumValueOptions::Swap(EnumValueOptions* other) {
// ===================================================================
#ifndef _MSC_VER
+const int ServiceOptions::kDeprecatedFieldNumber;
const int ServiceOptions::kUninterpretedOptionFieldNumber;
#endif // !_MSC_VER
ServiceOptions::ServiceOptions()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.ServiceOptions)
}
void ServiceOptions::InitAsDefaultInstance() {
@@ -5891,14 +7138,17 @@ ServiceOptions::ServiceOptions(const ServiceOptions& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceOptions)
}
void ServiceOptions::SharedCtor() {
_cached_size_ = 0;
+ deprecated_ = false;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
ServiceOptions::~ServiceOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.ServiceOptions)
SharedDtor();
}
@@ -5918,7 +7168,8 @@ const ::google::protobuf::Descriptor* ServiceOptions::descriptor() {
}
const ServiceOptions& ServiceOptions::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
ServiceOptions* ServiceOptions::default_instance_ = NULL;
@@ -5929,6 +7180,7 @@ ServiceOptions* ServiceOptions::New() const {
void ServiceOptions::Clear() {
_extensions_.Clear();
+ deprecated_ = false;
uninterpreted_option_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
mutable_unknown_fields()->Clear();
@@ -5936,30 +7188,48 @@ void ServiceOptions::Clear() {
bool ServiceOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.ServiceOptions)
+ 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)) {
+ // optional bool deprecated = 33 [default = false];
+ case 33: {
+ if (tag == 264) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &deprecated_)));
+ set_has_deprecated();
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ break;
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
case 999: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 7994) {
parse_uninterpreted_option:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_uninterpreted_option()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
if ((8000u <= tag)) {
DO_(_extensions_.ParseField(tag, input, default_instance_,
@@ -5972,51 +7242,77 @@ bool ServiceOptions::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.ServiceOptions)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.ServiceOptions)
+ return false;
#undef DO_
}
void ServiceOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.ServiceOptions)
+ // optional bool deprecated = 33 [default = false];
+ if (has_deprecated()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(33, this->deprecated(), output);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
999, this->uninterpreted_option(i), output);
}
-
+
// Extension range [1000, 536870912)
_extensions_.SerializeWithCachedSizes(
1000, 536870912, output);
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.ServiceOptions)
}
::google::protobuf::uint8* ServiceOptions::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceOptions)
+ // optional bool deprecated = 33 [default = false];
+ if (has_deprecated()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(33, this->deprecated(), target);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
999, this->uninterpreted_option(i), target);
}
-
+
// Extension range [1000, 536870912)
target = _extensions_.SerializeWithCachedSizesToArray(
1000, 536870912, target);
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceOptions)
return target;
}
int ServiceOptions::ByteSize() const {
int total_size = 0;
-
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional bool deprecated = 33 [default = false];
+ if (has_deprecated()) {
+ total_size += 2 + 1;
+ }
+
+ }
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
total_size += 2 * this->uninterpreted_option_size();
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
@@ -6024,9 +7320,9 @@ int ServiceOptions::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->uninterpreted_option(i));
}
-
+
total_size += _extensions_.ByteSize();
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -6053,6 +7349,11 @@ void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) {
void ServiceOptions::MergeFrom(const ServiceOptions& from) {
GOOGLE_CHECK_NE(&from, this);
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_deprecated()) {
+ set_deprecated(from.deprecated());
+ }
+ }
_extensions_.MergeFrom(from._extensions_);
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}
@@ -6070,16 +7371,15 @@ void ServiceOptions::CopyFrom(const ServiceOptions& from) {
}
bool ServiceOptions::IsInitialized() const {
-
- for (int i = 0; i < uninterpreted_option_size(); i++) {
- if (!this->uninterpreted_option(i).IsInitialized()) return false;
- }
-
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
if (!_extensions_.IsInitialized()) return false; return true;
}
void ServiceOptions::Swap(ServiceOptions* other) {
if (other != this) {
+ std::swap(deprecated_, other->deprecated_);
uninterpreted_option_.Swap(&other->uninterpreted_option_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
@@ -6100,12 +7400,14 @@ void ServiceOptions::Swap(ServiceOptions* other) {
// ===================================================================
#ifndef _MSC_VER
+const int MethodOptions::kDeprecatedFieldNumber;
const int MethodOptions::kUninterpretedOptionFieldNumber;
#endif // !_MSC_VER
MethodOptions::MethodOptions()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.MethodOptions)
}
void MethodOptions::InitAsDefaultInstance() {
@@ -6115,14 +7417,17 @@ MethodOptions::MethodOptions(const MethodOptions& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodOptions)
}
void MethodOptions::SharedCtor() {
_cached_size_ = 0;
+ deprecated_ = false;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
MethodOptions::~MethodOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.MethodOptions)
SharedDtor();
}
@@ -6142,7 +7447,8 @@ const ::google::protobuf::Descriptor* MethodOptions::descriptor() {
}
const MethodOptions& MethodOptions::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
MethodOptions* MethodOptions::default_instance_ = NULL;
@@ -6153,6 +7459,7 @@ MethodOptions* MethodOptions::New() const {
void MethodOptions::Clear() {
_extensions_.Clear();
+ deprecated_ = false;
uninterpreted_option_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
mutable_unknown_fields()->Clear();
@@ -6160,30 +7467,48 @@ void MethodOptions::Clear() {
bool MethodOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.MethodOptions)
+ 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)) {
+ // optional bool deprecated = 33 [default = false];
+ case 33: {
+ if (tag == 264) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &deprecated_)));
+ set_has_deprecated();
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ break;
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
case 999: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 7994) {
parse_uninterpreted_option:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_uninterpreted_option()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
if ((8000u <= tag)) {
DO_(_extensions_.ParseField(tag, input, default_instance_,
@@ -6196,51 +7521,77 @@ bool MethodOptions::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.MethodOptions)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.MethodOptions)
+ return false;
#undef DO_
}
void MethodOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.MethodOptions)
+ // optional bool deprecated = 33 [default = false];
+ if (has_deprecated()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(33, this->deprecated(), output);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
999, this->uninterpreted_option(i), output);
}
-
+
// Extension range [1000, 536870912)
_extensions_.SerializeWithCachedSizes(
1000, 536870912, output);
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.MethodOptions)
}
::google::protobuf::uint8* MethodOptions::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodOptions)
+ // optional bool deprecated = 33 [default = false];
+ if (has_deprecated()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(33, this->deprecated(), target);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
999, this->uninterpreted_option(i), target);
}
-
+
// Extension range [1000, 536870912)
target = _extensions_.SerializeWithCachedSizesToArray(
1000, 536870912, target);
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodOptions)
return target;
}
int MethodOptions::ByteSize() const {
int total_size = 0;
-
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional bool deprecated = 33 [default = false];
+ if (has_deprecated()) {
+ total_size += 2 + 1;
+ }
+
+ }
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
total_size += 2 * this->uninterpreted_option_size();
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
@@ -6248,9 +7599,9 @@ int MethodOptions::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->uninterpreted_option(i));
}
-
+
total_size += _extensions_.ByteSize();
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -6277,6 +7628,11 @@ void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) {
void MethodOptions::MergeFrom(const MethodOptions& from) {
GOOGLE_CHECK_NE(&from, this);
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_deprecated()) {
+ set_deprecated(from.deprecated());
+ }
+ }
_extensions_.MergeFrom(from._extensions_);
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}
@@ -6294,16 +7650,15 @@ void MethodOptions::CopyFrom(const MethodOptions& from) {
}
bool MethodOptions::IsInitialized() const {
-
- for (int i = 0; i < uninterpreted_option_size(); i++) {
- if (!this->uninterpreted_option(i).IsInitialized()) return false;
- }
-
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
if (!_extensions_.IsInitialized()) return false; return true;
}
void MethodOptions::Swap(MethodOptions* other) {
if (other != this) {
+ std::swap(deprecated_, other->deprecated_);
uninterpreted_option_.Swap(&other->uninterpreted_option_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
@@ -6323,7 +7678,6 @@ void MethodOptions::Swap(MethodOptions* other) {
// ===================================================================
-const ::std::string UninterpretedOption_NamePart::_default_name_part_;
#ifndef _MSC_VER
const int UninterpretedOption_NamePart::kNamePartFieldNumber;
const int UninterpretedOption_NamePart::kIsExtensionFieldNumber;
@@ -6332,6 +7686,7 @@ const int UninterpretedOption_NamePart::kIsExtensionFieldNumber;
UninterpretedOption_NamePart::UninterpretedOption_NamePart()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption.NamePart)
}
void UninterpretedOption_NamePart::InitAsDefaultInstance() {
@@ -6341,21 +7696,24 @@ UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOp
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption.NamePart)
}
void UninterpretedOption_NamePart::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
- name_part_ = const_cast< ::std::string*>(&_default_name_part_);
+ name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
is_extension_ = false;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
UninterpretedOption_NamePart::~UninterpretedOption_NamePart() {
+ // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption.NamePart)
SharedDtor();
}
void UninterpretedOption_NamePart::SharedDtor() {
- if (name_part_ != &_default_name_part_) {
+ if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete name_part_;
}
if (this != default_instance_) {
@@ -6373,7 +7731,8 @@ const ::google::protobuf::Descriptor* UninterpretedOption_NamePart::descriptor()
}
const UninterpretedOption_NamePart& UninterpretedOption_NamePart::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
UninterpretedOption_NamePart* UninterpretedOption_NamePart::default_instance_ = NULL;
@@ -6383,9 +7742,9 @@ UninterpretedOption_NamePart* UninterpretedOption_NamePart::New() const {
}
void UninterpretedOption_NamePart::Clear() {
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_part_ != &_default_name_part_) {
+ if (_has_bits_[0 / 32] & 3) {
+ if (has_name_part()) {
+ if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_part_->clear();
}
}
@@ -6397,47 +7756,51 @@ void UninterpretedOption_NamePart::Clear() {
bool UninterpretedOption_NamePart::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.UninterpretedOption.NamePart)
+ 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)) {
// required string name_part = 1;
case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name_part()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name_part().data(), this->name_part().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "name_part");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(16)) goto parse_is_extension;
break;
}
-
+
// required bool is_extension = 2;
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 16) {
parse_is_extension:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &is_extension_)));
- _set_bit(1);
+ set_has_is_extension();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectAtEnd()) goto success;
break;
}
-
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -6445,59 +7808,70 @@ bool UninterpretedOption_NamePart::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.UninterpretedOption.NamePart)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.UninterpretedOption.NamePart)
+ return false;
#undef DO_
}
void UninterpretedOption_NamePart::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.UninterpretedOption.NamePart)
// required string name_part = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name_part()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name_part().data(), this->name_part().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name_part");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name_part(), output);
}
-
+
// required bool is_extension = 2;
- if (_has_bit(1)) {
+ if (has_is_extension()) {
::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_extension(), output);
}
-
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption.NamePart)
}
::google::protobuf::uint8* UninterpretedOption_NamePart::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption.NamePart)
// required string name_part = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_name_part()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->name_part().data(), this->name_part().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "name_part");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
1, this->name_part(), target);
}
-
+
// required bool is_extension = 2;
- if (_has_bit(1)) {
+ if (has_is_extension()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_extension(), target);
}
-
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption.NamePart)
return target;
}
int UninterpretedOption_NamePart::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// required string name_part = 1;
if (has_name_part()) {
@@ -6505,12 +7879,12 @@ int UninterpretedOption_NamePart::ByteSize() const {
::google::protobuf::internal::WireFormatLite::StringSize(
this->name_part());
}
-
+
// required bool is_extension = 2;
if (has_is_extension()) {
total_size += 1 + 1;
}
-
+
}
if (!unknown_fields().empty()) {
total_size +=
@@ -6538,10 +7912,10 @@ void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message&
void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name_part()) {
set_name_part(from.name_part());
}
- if (from._has_bit(1)) {
+ if (from.has_is_extension()) {
set_is_extension(from.is_extension());
}
}
@@ -6562,7 +7936,7 @@ void UninterpretedOption_NamePart::CopyFrom(const UninterpretedOption_NamePart&
bool UninterpretedOption_NamePart::IsInitialized() const {
if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;
-
+
return true;
}
@@ -6587,8 +7961,6 @@ void UninterpretedOption_NamePart::Swap(UninterpretedOption_NamePart* other) {
// -------------------------------------------------------------------
-const ::std::string UninterpretedOption::_default_identifier_value_;
-const ::std::string UninterpretedOption::_default_string_value_;
#ifndef _MSC_VER
const int UninterpretedOption::kNameFieldNumber;
const int UninterpretedOption::kIdentifierValueFieldNumber;
@@ -6596,11 +7968,13 @@ const int UninterpretedOption::kPositiveIntValueFieldNumber;
const int UninterpretedOption::kNegativeIntValueFieldNumber;
const int UninterpretedOption::kDoubleValueFieldNumber;
const int UninterpretedOption::kStringValueFieldNumber;
+const int UninterpretedOption::kAggregateValueFieldNumber;
#endif // !_MSC_VER
UninterpretedOption::UninterpretedOption()
: ::google::protobuf::Message() {
SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption)
}
void UninterpretedOption::InitAsDefaultInstance() {
@@ -6610,29 +7984,36 @@ UninterpretedOption::UninterpretedOption(const UninterpretedOption& from)
: ::google::protobuf::Message() {
SharedCtor();
MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption)
}
void UninterpretedOption::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
- identifier_value_ = const_cast< ::std::string*>(&_default_identifier_value_);
+ identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
positive_int_value_ = GOOGLE_ULONGLONG(0);
negative_int_value_ = GOOGLE_LONGLONG(0);
double_value_ = 0;
- string_value_ = const_cast< ::std::string*>(&_default_string_value_);
+ string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
UninterpretedOption::~UninterpretedOption() {
+ // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption)
SharedDtor();
}
void UninterpretedOption::SharedDtor() {
- if (identifier_value_ != &_default_identifier_value_) {
+ if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete identifier_value_;
}
- if (string_value_ != &_default_string_value_) {
+ if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
delete string_value_;
}
+ if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete aggregate_value_;
+ }
if (this != default_instance_) {
}
}
@@ -6648,7 +8029,8 @@ const ::google::protobuf::Descriptor* UninterpretedOption::descriptor() {
}
const UninterpretedOption& UninterpretedOption::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
}
UninterpretedOption* UninterpretedOption::default_instance_ = NULL;
@@ -6658,21 +8040,38 @@ UninterpretedOption* UninterpretedOption::New() const {
}
void UninterpretedOption::Clear() {
- if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
- if (_has_bit(1)) {
- if (identifier_value_ != &_default_identifier_value_) {
+#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
+ &reinterpret_cast<UninterpretedOption*>(16)->f) - \
+ reinterpret_cast<char*>(16))
+
+#define ZR_(first, last) do { \
+ size_t f = OFFSET_OF_FIELD_(first); \
+ size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
+ ::memset(&first, 0, n); \
+ } while (0)
+
+ if (_has_bits_[0 / 32] & 126) {
+ ZR_(positive_int_value_, double_value_);
+ if (has_identifier_value()) {
+ if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
identifier_value_->clear();
}
}
- positive_int_value_ = GOOGLE_ULONGLONG(0);
- negative_int_value_ = GOOGLE_LONGLONG(0);
- double_value_ = 0;
- if (_has_bit(5)) {
- if (string_value_ != &_default_string_value_) {
+ if (has_string_value()) {
+ if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
string_value_->clear();
}
}
+ if (has_aggregate_value()) {
+ if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ aggregate_value_->clear();
+ }
+ }
}
+
+#undef OFFSET_OF_FIELD_
+#undef ZR_
+
name_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
mutable_unknown_fields()->Clear();
@@ -6680,109 +8079,126 @@ void UninterpretedOption::Clear() {
bool UninterpretedOption::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
+ // @@protoc_insertion_point(parse_start:google.protobuf.UninterpretedOption)
+ 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.UninterpretedOption.NamePart name = 2;
case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 18) {
parse_name:
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, add_name()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(18)) goto parse_name;
if (input->ExpectTag(26)) goto parse_identifier_value;
break;
}
-
+
// optional string identifier_value = 3;
case 3: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 26) {
parse_identifier_value:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_identifier_value()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->identifier_value().data(), this->identifier_value().length(),
- ::google::protobuf::internal::WireFormat::PARSE);
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "identifier_value");
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(32)) goto parse_positive_int_value;
break;
}
-
+
// optional uint64 positive_int_value = 4;
case 4: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 32) {
parse_positive_int_value:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
input, &positive_int_value_)));
- _set_bit(2);
+ set_has_positive_int_value();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(40)) goto parse_negative_int_value;
break;
}
-
+
// optional int64 negative_int_value = 5;
case 5: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ if (tag == 40) {
parse_negative_int_value:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
input, &negative_int_value_)));
- _set_bit(3);
+ set_has_negative_int_value();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(49)) goto parse_double_value;
break;
}
-
+
// optional double double_value = 6;
case 6: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) {
+ if (tag == 49) {
parse_double_value:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
input, &double_value_)));
- _set_bit(4);
+ set_has_double_value();
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
if (input->ExpectTag(58)) goto parse_string_value;
break;
}
-
+
// optional bytes string_value = 7;
case 7: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ if (tag == 58) {
parse_string_value:
DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
input, this->mutable_string_value()));
} else {
- goto handle_uninterpreted;
+ goto handle_unusual;
}
- if (input->ExpectAtEnd()) return true;
+ if (input->ExpectTag(66)) goto parse_aggregate_value;
break;
}
-
+
+ // optional string aggregate_value = 8;
+ case 8: {
+ if (tag == 66) {
+ parse_aggregate_value:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_aggregate_value()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->aggregate_value().data(), this->aggregate_value().length(),
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "aggregate_value");
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectAtEnd()) goto success;
+ break;
+ }
+
default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
+ goto success;
}
DO_(::google::protobuf::internal::WireFormat::SkipField(
input, tag, mutable_unknown_fields()));
@@ -6790,105 +8206,137 @@ bool UninterpretedOption::MergePartialFromCodedStream(
}
}
}
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.UninterpretedOption)
return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.UninterpretedOption)
+ return false;
#undef DO_
}
void UninterpretedOption::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.UninterpretedOption)
// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
for (int i = 0; i < this->name_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
2, this->name(i), output);
}
-
+
// optional string identifier_value = 3;
- if (_has_bit(1)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_identifier_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->identifier_value().data(), this->identifier_value().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
- ::google::protobuf::internal::WireFormatLite::WriteString(
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "identifier_value");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
3, this->identifier_value(), output);
}
-
+
// optional uint64 positive_int_value = 4;
- if (_has_bit(2)) {
+ if (has_positive_int_value()) {
::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->positive_int_value(), output);
}
-
+
// optional int64 negative_int_value = 5;
- if (_has_bit(3)) {
+ if (has_negative_int_value()) {
::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->negative_int_value(), output);
}
-
+
// optional double double_value = 6;
- if (_has_bit(4)) {
+ if (has_double_value()) {
::google::protobuf::internal::WireFormatLite::WriteDouble(6, this->double_value(), output);
}
-
+
// optional bytes string_value = 7;
- if (_has_bit(5)) {
- ::google::protobuf::internal::WireFormatLite::WriteBytes(
+ if (has_string_value()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
7, this->string_value(), output);
}
-
+
+ // optional string aggregate_value = 8;
+ if (has_aggregate_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->aggregate_value().data(), this->aggregate_value().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "aggregate_value");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+ 8, this->aggregate_value(), output);
+ }
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
}
+ // @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption)
}
::google::protobuf::uint8* UninterpretedOption::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption)
// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
for (int i = 0; i < this->name_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
2, this->name(i), target);
}
-
+
// optional string identifier_value = 3;
- if (_has_bit(1)) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ if (has_identifier_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
this->identifier_value().data(), this->identifier_value().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "identifier_value");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
3, this->identifier_value(), target);
}
-
+
// optional uint64 positive_int_value = 4;
- if (_has_bit(2)) {
+ if (has_positive_int_value()) {
target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->positive_int_value(), target);
}
-
+
// optional int64 negative_int_value = 5;
- if (_has_bit(3)) {
+ if (has_negative_int_value()) {
target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->negative_int_value(), target);
}
-
+
// optional double double_value = 6;
- if (_has_bit(4)) {
+ if (has_double_value()) {
target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(6, this->double_value(), target);
}
-
+
// optional bytes string_value = 7;
- if (_has_bit(5)) {
+ if (has_string_value()) {
target =
::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
7, this->string_value(), target);
}
-
+
+ // optional string aggregate_value = 8;
+ if (has_aggregate_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->aggregate_value().data(), this->aggregate_value().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "aggregate_value");
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 8, this->aggregate_value(), target);
+ }
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
}
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption)
return target;
}
int UninterpretedOption::ByteSize() const {
int total_size = 0;
-
+
if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
// optional string identifier_value = 3;
if (has_identifier_value()) {
@@ -6896,33 +8344,40 @@ int UninterpretedOption::ByteSize() const {
::google::protobuf::internal::WireFormatLite::StringSize(
this->identifier_value());
}
-
+
// optional uint64 positive_int_value = 4;
if (has_positive_int_value()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::UInt64Size(
this->positive_int_value());
}
-
+
// optional int64 negative_int_value = 5;
if (has_negative_int_value()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::Int64Size(
this->negative_int_value());
}
-
+
// optional double double_value = 6;
if (has_double_value()) {
total_size += 1 + 8;
}
-
+
// optional bytes string_value = 7;
if (has_string_value()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::BytesSize(
this->string_value());
}
-
+
+ // optional string aggregate_value = 8;
+ if (has_aggregate_value()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->aggregate_value());
+ }
+
}
// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
total_size += 1 * this->name_size();
@@ -6931,7 +8386,7 @@ int UninterpretedOption::ByteSize() const {
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
this->name(i));
}
-
+
if (!unknown_fields().empty()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -6959,21 +8414,24 @@ void UninterpretedOption::MergeFrom(const UninterpretedOption& from) {
GOOGLE_CHECK_NE(&from, this);
name_.MergeFrom(from.name_);
if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
- if (from._has_bit(1)) {
+ if (from.has_identifier_value()) {
set_identifier_value(from.identifier_value());
}
- if (from._has_bit(2)) {
+ if (from.has_positive_int_value()) {
set_positive_int_value(from.positive_int_value());
}
- if (from._has_bit(3)) {
+ if (from.has_negative_int_value()) {
set_negative_int_value(from.negative_int_value());
}
- if (from._has_bit(4)) {
+ if (from.has_double_value()) {
set_double_value(from.double_value());
}
- if (from._has_bit(5)) {
+ if (from.has_string_value()) {
set_string_value(from.string_value());
}
+ if (from.has_aggregate_value()) {
+ set_aggregate_value(from.aggregate_value());
+ }
}
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}
@@ -6991,10 +8449,8 @@ void UninterpretedOption::CopyFrom(const UninterpretedOption& from) {
}
bool UninterpretedOption::IsInitialized() const {
-
- for (int i = 0; i < name_size(); i++) {
- if (!this->name(i).IsInitialized()) return false;
- }
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->name())) return false;
return true;
}
@@ -7006,6 +8462,7 @@ void UninterpretedOption::Swap(UninterpretedOption* other) {
std::swap(negative_int_value_, other->negative_int_value_);
std::swap(double_value_, other->double_value_);
std::swap(string_value_, other->string_value_);
+ std::swap(aggregate_value_, other->aggregate_value_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
std::swap(_cached_size_, other->_cached_size_);
@@ -7021,6 +8478,655 @@ void UninterpretedOption::Swap(UninterpretedOption* other) {
}
+// ===================================================================
+
+#ifndef _MSC_VER
+const int SourceCodeInfo_Location::kPathFieldNumber;
+const int SourceCodeInfo_Location::kSpanFieldNumber;
+const int SourceCodeInfo_Location::kLeadingCommentsFieldNumber;
+const int SourceCodeInfo_Location::kTrailingCommentsFieldNumber;
+#endif // !_MSC_VER
+
+SourceCodeInfo_Location::SourceCodeInfo_Location()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo.Location)
+}
+
+void SourceCodeInfo_Location::InitAsDefaultInstance() {
+}
+
+SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo.Location)
+}
+
+void SourceCodeInfo_Location::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
+ _cached_size_ = 0;
+ leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+SourceCodeInfo_Location::~SourceCodeInfo_Location() {
+ // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo.Location)
+ SharedDtor();
+}
+
+void SourceCodeInfo_Location::SharedDtor() {
+ if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete leading_comments_;
+ }
+ if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete trailing_comments_;
+ }
+ if (this != default_instance_) {
+ }
+}
+
+void SourceCodeInfo_Location::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* SourceCodeInfo_Location::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return SourceCodeInfo_Location_descriptor_;
+}
+
+const SourceCodeInfo_Location& SourceCodeInfo_Location::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+SourceCodeInfo_Location* SourceCodeInfo_Location::default_instance_ = NULL;
+
+SourceCodeInfo_Location* SourceCodeInfo_Location::New() const {
+ return new SourceCodeInfo_Location;
+}
+
+void SourceCodeInfo_Location::Clear() {
+ if (_has_bits_[0 / 32] & 12) {
+ if (has_leading_comments()) {
+ if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ leading_comments_->clear();
+ }
+ }
+ if (has_trailing_comments()) {
+ if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ trailing_comments_->clear();
+ }
+ }
+ }
+ path_.Clear();
+ span_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool SourceCodeInfo_Location::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:google.protobuf.SourceCodeInfo.Location)
+ 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_span;
+ break;
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ case 2: {
+ if (tag == 18) {
+ parse_span:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, this->mutable_span())));
+ } else if (tag == 16) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ 1, 18, input, this->mutable_span())));
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(26)) goto parse_leading_comments;
+ break;
+ }
+
+ // optional string leading_comments = 3;
+ case 3: {
+ if (tag == 26) {
+ parse_leading_comments:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_leading_comments()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->leading_comments().data(), this->leading_comments().length(),
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "leading_comments");
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(34)) goto parse_trailing_comments;
+ break;
+ }
+
+ // optional string trailing_comments = 4;
+ case 4: {
+ if (tag == 34) {
+ parse_trailing_comments:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_trailing_comments()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->trailing_comments().data(), this->trailing_comments().length(),
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "trailing_comments");
+ } 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.SourceCodeInfo.Location)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.SourceCodeInfo.Location)
+ return false;
+#undef DO_
+}
+
+void SourceCodeInfo_Location::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.SourceCodeInfo.Location)
+ // 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);
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ if (this->span_size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+ output->WriteVarint32(_span_cached_byte_size_);
+ }
+ for (int i = 0; i < this->span_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
+ this->span(i), output);
+ }
+
+ // optional string leading_comments = 3;
+ if (has_leading_comments()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->leading_comments().data(), this->leading_comments().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "leading_comments");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+ 3, this->leading_comments(), output);
+ }
+
+ // optional string trailing_comments = 4;
+ if (has_trailing_comments()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->trailing_comments().data(), this->trailing_comments().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "trailing_comments");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+ 4, this->trailing_comments(), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+ // @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo.Location)
+}
+
+::google::protobuf::uint8* SourceCodeInfo_Location::SerializeWithCachedSizesToArray(
+ ::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) {
+ 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);
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ if (this->span_size() > 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+ 2,
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ target);
+ target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+ _span_cached_byte_size_, target);
+ }
+ for (int i = 0; i < this->span_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteInt32NoTagToArray(this->span(i), target);
+ }
+
+ // optional string leading_comments = 3;
+ if (has_leading_comments()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->leading_comments().data(), this->leading_comments().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "leading_comments");
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 3, this->leading_comments(), target);
+ }
+
+ // optional string trailing_comments = 4;
+ if (has_trailing_comments()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->trailing_comments().data(), this->trailing_comments().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "trailing_comments");
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 4, this->trailing_comments(), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo.Location)
+ return target;
+}
+
+int SourceCodeInfo_Location::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[2 / 32] & (0xffu << (2 % 32))) {
+ // optional string leading_comments = 3;
+ if (has_leading_comments()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->leading_comments());
+ }
+
+ // optional string trailing_comments = 4;
+ if (has_trailing_comments()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->trailing_comments());
+ }
+
+ }
+ // 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;
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ {
+ int data_size = 0;
+ for (int i = 0; i < this->span_size(); i++) {
+ data_size += ::google::protobuf::internal::WireFormatLite::
+ Int32Size(this->span(i));
+ }
+ if (data_size > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _span_cached_byte_size_ = data_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ total_size += data_size;
+ }
+
+ if (!unknown_fields().empty()) {
+ 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 SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const SourceCodeInfo_Location* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo_Location*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ path_.MergeFrom(from.path_);
+ span_.MergeFrom(from.span_);
+ if (from._has_bits_[2 / 32] & (0xffu << (2 % 32))) {
+ if (from.has_leading_comments()) {
+ set_leading_comments(from.leading_comments());
+ }
+ if (from.has_trailing_comments()) {
+ set_trailing_comments(from.trailing_comments());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void SourceCodeInfo_Location::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void SourceCodeInfo_Location::CopyFrom(const SourceCodeInfo_Location& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool SourceCodeInfo_Location::IsInitialized() const {
+
+ return true;
+}
+
+void SourceCodeInfo_Location::Swap(SourceCodeInfo_Location* other) {
+ if (other != this) {
+ path_.Swap(&other->path_);
+ span_.Swap(&other->span_);
+ std::swap(leading_comments_, other->leading_comments_);
+ std::swap(trailing_comments_, other->trailing_comments_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = SourceCodeInfo_Location_descriptor_;
+ metadata.reflection = SourceCodeInfo_Location_reflection_;
+ return metadata;
+}
+
+
+// -------------------------------------------------------------------
+
+#ifndef _MSC_VER
+const int SourceCodeInfo::kLocationFieldNumber;
+#endif // !_MSC_VER
+
+SourceCodeInfo::SourceCodeInfo()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo)
+}
+
+void SourceCodeInfo::InitAsDefaultInstance() {
+}
+
+SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo)
+}
+
+void SourceCodeInfo::SharedCtor() {
+ _cached_size_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+SourceCodeInfo::~SourceCodeInfo() {
+ // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo)
+ SharedDtor();
+}
+
+void SourceCodeInfo::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void SourceCodeInfo::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* SourceCodeInfo::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return SourceCodeInfo_descriptor_;
+}
+
+const SourceCodeInfo& SourceCodeInfo::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+SourceCodeInfo* SourceCodeInfo::default_instance_ = NULL;
+
+SourceCodeInfo* SourceCodeInfo::New() const {
+ return new SourceCodeInfo;
+}
+
+void SourceCodeInfo::Clear() {
+ location_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool SourceCodeInfo::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:google.protobuf.SourceCodeInfo)
+ 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.SourceCodeInfo.Location location = 1;
+ case 1: {
+ if (tag == 10) {
+ parse_location:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_location()));
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(10)) goto parse_location;
+ 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.SourceCodeInfo)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.SourceCodeInfo)
+ return false;
+#undef DO_
+}
+
+void SourceCodeInfo::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.SourceCodeInfo)
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ for (int i = 0; i < this->location_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 1, this->location(i), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+ // @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo)
+}
+
+::google::protobuf::uint8* SourceCodeInfo::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo)
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ for (int i = 0; i < this->location_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 1, this->location(i), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo)
+ return target;
+}
+
+int SourceCodeInfo::ByteSize() const {
+ int total_size = 0;
+
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ total_size += 1 * this->location_size();
+ for (int i = 0; i < this->location_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->location(i));
+ }
+
+ if (!unknown_fields().empty()) {
+ 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 SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const SourceCodeInfo* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ location_.MergeFrom(from.location_);
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void SourceCodeInfo::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void SourceCodeInfo::CopyFrom(const SourceCodeInfo& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool SourceCodeInfo::IsInitialized() const {
+
+ return true;
+}
+
+void SourceCodeInfo::Swap(SourceCodeInfo* other) {
+ if (other != this) {
+ location_.Swap(&other->location_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = SourceCodeInfo_descriptor_;
+ metadata.reflection = SourceCodeInfo_reflection_;
+ return metadata;
+}
+
+
// @@protoc_insertion_point(namespace_scope)
} // namespace protobuf
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 2743b6f..4552181 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -8,21 +8,23 @@
#include <google/protobuf/stubs/common.h>
-#if GOOGLE_PROTOBUF_VERSION < 2003000
+#if GOOGLE_PROTOBUF_VERSION < 2006000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
-#if 2003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
-#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/generated_enum_reflection.h>
+#include <google/protobuf/unknown_field_set.h>
// @@protoc_insertion_point(includes)
namespace google {
@@ -38,6 +40,7 @@ class FileDescriptorProto;
class DescriptorProto;
class DescriptorProto_ExtensionRange;
class FieldDescriptorProto;
+class OneofDescriptorProto;
class EnumDescriptorProto;
class EnumValueDescriptorProto;
class ServiceDescriptorProto;
@@ -51,6 +54,8 @@ class ServiceOptions;
class MethodOptions;
class UninterpretedOption;
class UninterpretedOption_NamePart;
+class SourceCodeInfo;
+class SourceCodeInfo_Location;
enum FieldDescriptorProto_Type {
FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
@@ -153,29 +158,29 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message
public:
FileDescriptorSet();
virtual ~FileDescriptorSet();
-
+
FileDescriptorSet(const FileDescriptorSet& from);
-
+
inline FileDescriptorSet& operator=(const FileDescriptorSet& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const FileDescriptorSet& default_instance();
-
+
void Swap(FileDescriptorSet* other);
-
+
// implements Message ----------------------------------------------
-
+
FileDescriptorSet* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -183,7 +188,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message
void MergeFrom(const FileDescriptorSet& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -196,13 +201,12 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
// repeated .google.protobuf.FileDescriptorProto file = 1;
inline int file_size() const;
inline void clear_file();
@@ -214,30 +218,19 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message
file() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
mutable_file();
-
+
// @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet)
private:
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_;
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();
-
- ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static FileDescriptorSet* default_instance_;
};
@@ -247,29 +240,29 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
public:
FileDescriptorProto();
virtual ~FileDescriptorProto();
-
+
FileDescriptorProto(const FileDescriptorProto& from);
-
+
inline FileDescriptorProto& operator=(const FileDescriptorProto& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const FileDescriptorProto& default_instance();
-
+
void Swap(FileDescriptorProto* other);
-
+
// implements Message ----------------------------------------------
-
+
FileDescriptorProto* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -277,7 +270,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
void MergeFrom(const FileDescriptorProto& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -290,13 +283,12 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
// optional string name = 1;
inline bool has_name() const;
inline void clear_name();
@@ -306,7 +298,9 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
-
+ inline ::std::string* release_name();
+ inline void set_allocated_name(::std::string* name);
+
// optional string package = 2;
inline bool has_package() const;
inline void clear_package();
@@ -316,7 +310,9 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
inline void set_package(const char* value);
inline void set_package(const char* value, size_t size);
inline ::std::string* mutable_package();
-
+ inline ::std::string* release_package();
+ inline void set_allocated_package(::std::string* package);
+
// repeated string dependency = 3;
inline int dependency_size() const;
inline void clear_dependency();
@@ -332,7 +328,31 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
inline void add_dependency(const char* value, size_t size);
inline const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const;
inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency();
-
+
+ // repeated int32 public_dependency = 10;
+ inline int public_dependency_size() const;
+ inline void clear_public_dependency();
+ static const int kPublicDependencyFieldNumber = 10;
+ inline ::google::protobuf::int32 public_dependency(int index) const;
+ inline void set_public_dependency(int index, ::google::protobuf::int32 value);
+ inline void add_public_dependency(::google::protobuf::int32 value);
+ inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+ public_dependency() const;
+ inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+ mutable_public_dependency();
+
+ // repeated int32 weak_dependency = 11;
+ inline int weak_dependency_size() const;
+ inline void clear_weak_dependency();
+ static const int kWeakDependencyFieldNumber = 11;
+ inline ::google::protobuf::int32 weak_dependency(int index) const;
+ inline void set_weak_dependency(int index, ::google::protobuf::int32 value);
+ inline void add_weak_dependency(::google::protobuf::int32 value);
+ inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+ weak_dependency() const;
+ inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+ mutable_weak_dependency();
+
// repeated .google.protobuf.DescriptorProto message_type = 4;
inline int message_type_size() const;
inline void clear_message_type();
@@ -344,7 +364,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
message_type() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
mutable_message_type();
-
+
// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
inline int enum_type_size() const;
inline void clear_enum_type();
@@ -356,7 +376,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
enum_type() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
mutable_enum_type();
-
+
// repeated .google.protobuf.ServiceDescriptorProto service = 6;
inline int service_size() const;
inline void clear_service();
@@ -368,7 +388,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
service() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
mutable_service();
-
+
// repeated .google.protobuf.FieldDescriptorProto extension = 7;
inline int extension_size() const;
inline void clear_extension();
@@ -380,46 +400,55 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
extension() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
mutable_extension();
-
+
// optional .google.protobuf.FileOptions options = 8;
inline bool has_options() const;
inline void clear_options();
static const int kOptionsFieldNumber = 8;
inline const ::google::protobuf::FileOptions& options() const;
inline ::google::protobuf::FileOptions* mutable_options();
-
+ inline ::google::protobuf::FileOptions* release_options();
+ inline void set_allocated_options(::google::protobuf::FileOptions* options);
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ inline bool has_source_code_info() const;
+ inline void clear_source_code_info();
+ static const int kSourceCodeInfoFieldNumber = 9;
+ inline const ::google::protobuf::SourceCodeInfo& source_code_info() const;
+ inline ::google::protobuf::SourceCodeInfo* mutable_source_code_info();
+ inline ::google::protobuf::SourceCodeInfo* release_source_code_info();
+ inline void set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info);
+
// @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_package();
+ inline void clear_has_package();
+ inline void set_has_options();
+ inline void clear_has_options();
+ inline void set_has_source_code_info();
+ inline void clear_has_source_code_info();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::std::string* name_;
- static const ::std::string _default_name_;
::std::string* package_;
- static const ::std::string _default_package_;
::google::protobuf::RepeatedPtrField< ::std::string> dependency_;
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 > public_dependency_;
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 > weak_dependency_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
::google::protobuf::FileOptions* options_;
+ ::google::protobuf::SourceCodeInfo* source_code_info_;
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();
-
- ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static FileDescriptorProto* default_instance_;
};
@@ -429,29 +458,29 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto
public:
DescriptorProto_ExtensionRange();
virtual ~DescriptorProto_ExtensionRange();
-
+
DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from);
-
+
inline DescriptorProto_ExtensionRange& operator=(const DescriptorProto_ExtensionRange& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const DescriptorProto_ExtensionRange& default_instance();
-
+
void Swap(DescriptorProto_ExtensionRange* other);
-
+
// implements Message ----------------------------------------------
-
+
DescriptorProto_ExtensionRange* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -459,7 +488,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto
void MergeFrom(const DescriptorProto_ExtensionRange& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -472,51 +501,43 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
// optional int32 start = 1;
inline bool has_start() const;
inline void clear_start();
static const int kStartFieldNumber = 1;
inline ::google::protobuf::int32 start() const;
inline void set_start(::google::protobuf::int32 value);
-
+
// optional int32 end = 2;
inline bool has_end() const;
inline void clear_end();
static const int kEndFieldNumber = 2;
inline ::google::protobuf::int32 end() const;
inline void set_end(::google::protobuf::int32 value);
-
+
// @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange)
private:
+ inline void set_has_start();
+ inline void clear_has_start();
+ inline void set_has_end();
+ inline void clear_has_end();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::google::protobuf::int32 start_;
::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();
-
- ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static DescriptorProto_ExtensionRange* default_instance_;
};
@@ -526,29 +547,29 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
public:
DescriptorProto();
virtual ~DescriptorProto();
-
+
DescriptorProto(const DescriptorProto& from);
-
+
inline DescriptorProto& operator=(const DescriptorProto& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const DescriptorProto& default_instance();
-
+
void Swap(DescriptorProto* other);
-
+
// implements Message ----------------------------------------------
-
+
DescriptorProto* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -556,7 +577,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
void MergeFrom(const DescriptorProto& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -569,15 +590,14 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
typedef DescriptorProto_ExtensionRange ExtensionRange;
-
+
// accessors -------------------------------------------------------
-
+
// optional string name = 1;
inline bool has_name() const;
inline void clear_name();
@@ -587,7 +607,9 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
-
+ inline ::std::string* release_name();
+ inline void set_allocated_name(::std::string* name);
+
// repeated .google.protobuf.FieldDescriptorProto field = 2;
inline int field_size() const;
inline void clear_field();
@@ -599,7 +621,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
field() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
mutable_field();
-
+
// repeated .google.protobuf.FieldDescriptorProto extension = 6;
inline int extension_size() const;
inline void clear_extension();
@@ -611,7 +633,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
extension() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
mutable_extension();
-
+
// repeated .google.protobuf.DescriptorProto nested_type = 3;
inline int nested_type_size() const;
inline void clear_nested_type();
@@ -623,7 +645,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
nested_type() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
mutable_nested_type();
-
+
// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
inline int enum_type_size() const;
inline void clear_enum_type();
@@ -635,7 +657,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
enum_type() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
mutable_enum_type();
-
+
// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
inline int extension_range_size() const;
inline void clear_extension_range();
@@ -647,44 +669,51 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
extension_range() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
mutable_extension_range();
-
+
+ // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+ inline int oneof_decl_size() const;
+ inline void clear_oneof_decl();
+ static const int kOneofDeclFieldNumber = 8;
+ inline const ::google::protobuf::OneofDescriptorProto& oneof_decl(int index) const;
+ inline ::google::protobuf::OneofDescriptorProto* mutable_oneof_decl(int index);
+ inline ::google::protobuf::OneofDescriptorProto* add_oneof_decl();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
+ oneof_decl() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
+ mutable_oneof_decl();
+
// optional .google.protobuf.MessageOptions options = 7;
inline bool has_options() const;
inline void clear_options();
static const int kOptionsFieldNumber = 7;
inline const ::google::protobuf::MessageOptions& options() const;
inline ::google::protobuf::MessageOptions* mutable_options();
-
+ inline ::google::protobuf::MessageOptions* release_options();
+ inline void set_allocated_options(::google::protobuf::MessageOptions* options);
+
// @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_options();
+ inline void clear_has_options();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::std::string* name_;
- static const ::std::string _default_name_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto > oneof_decl_;
::google::protobuf::MessageOptions* 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();
-
- ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static DescriptorProto* default_instance_;
};
@@ -694,29 +723,29 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
public:
FieldDescriptorProto();
virtual ~FieldDescriptorProto();
-
+
FieldDescriptorProto(const FieldDescriptorProto& from);
-
+
inline FieldDescriptorProto& operator=(const FieldDescriptorProto& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const FieldDescriptorProto& default_instance();
-
+
void Swap(FieldDescriptorProto* other);
-
+
// implements Message ----------------------------------------------
-
+
FieldDescriptorProto* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -724,7 +753,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
void MergeFrom(const FieldDescriptorProto& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -737,11 +766,10 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
typedef FieldDescriptorProto_Type Type;
static const Type TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
static const Type TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
@@ -781,7 +809,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
Type* value) {
return FieldDescriptorProto_Type_Parse(name, value);
}
-
+
typedef FieldDescriptorProto_Label Label;
static const Label LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
static const Label LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
@@ -806,9 +834,9 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
Label* value) {
return FieldDescriptorProto_Label_Parse(name, value);
}
-
+
// accessors -------------------------------------------------------
-
+
// optional string name = 1;
inline bool has_name() const;
inline void clear_name();
@@ -818,28 +846,30 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
-
+ inline ::std::string* release_name();
+ inline void set_allocated_name(::std::string* name);
+
// optional int32 number = 3;
inline bool has_number() const;
inline void clear_number();
static const int kNumberFieldNumber = 3;
inline ::google::protobuf::int32 number() const;
inline void set_number(::google::protobuf::int32 value);
-
+
// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
inline bool has_label() const;
inline void clear_label();
static const int kLabelFieldNumber = 4;
inline ::google::protobuf::FieldDescriptorProto_Label label() const;
inline void set_label(::google::protobuf::FieldDescriptorProto_Label value);
-
+
// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
inline bool has_type() const;
inline void clear_type();
static const int kTypeFieldNumber = 5;
inline ::google::protobuf::FieldDescriptorProto_Type type() const;
inline void set_type(::google::protobuf::FieldDescriptorProto_Type value);
-
+
// optional string type_name = 6;
inline bool has_type_name() const;
inline void clear_type_name();
@@ -849,7 +879,9 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
inline void set_type_name(const char* value);
inline void set_type_name(const char* value, size_t size);
inline ::std::string* mutable_type_name();
-
+ inline ::std::string* release_type_name();
+ inline void set_allocated_type_name(::std::string* type_name);
+
// optional string extendee = 2;
inline bool has_extendee() const;
inline void clear_extendee();
@@ -859,7 +891,9 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
inline void set_extendee(const char* value);
inline void set_extendee(const char* value, size_t size);
inline ::std::string* mutable_extendee();
-
+ inline ::std::string* release_extendee();
+ inline void set_allocated_extendee(::std::string* extendee);
+
// optional string default_value = 7;
inline bool has_default_value() const;
inline void clear_default_value();
@@ -869,50 +903,149 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
inline void set_default_value(const char* value);
inline void set_default_value(const char* value, size_t size);
inline ::std::string* mutable_default_value();
-
+ inline ::std::string* release_default_value();
+ inline void set_allocated_default_value(::std::string* default_value);
+
+ // optional int32 oneof_index = 9;
+ inline bool has_oneof_index() const;
+ inline void clear_oneof_index();
+ static const int kOneofIndexFieldNumber = 9;
+ inline ::google::protobuf::int32 oneof_index() const;
+ inline void set_oneof_index(::google::protobuf::int32 value);
+
// optional .google.protobuf.FieldOptions options = 8;
inline bool has_options() const;
inline void clear_options();
static const int kOptionsFieldNumber = 8;
inline const ::google::protobuf::FieldOptions& options() const;
inline ::google::protobuf::FieldOptions* mutable_options();
-
+ inline ::google::protobuf::FieldOptions* release_options();
+ inline void set_allocated_options(::google::protobuf::FieldOptions* options);
+
// @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_number();
+ inline void clear_has_number();
+ inline void set_has_label();
+ inline void clear_has_label();
+ inline void set_has_type();
+ inline void clear_has_type();
+ inline void set_has_type_name();
+ inline void clear_has_type_name();
+ inline void set_has_extendee();
+ inline void clear_has_extendee();
+ inline void set_has_default_value();
+ inline void clear_has_default_value();
+ inline void set_has_oneof_index();
+ inline void clear_has_oneof_index();
+ inline void set_has_options();
+ inline void clear_has_options();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::std::string* name_;
- static const ::std::string _default_name_;
::google::protobuf::int32 number_;
int label_;
- int type_;
::std::string* type_name_;
- static const ::std::string _default_type_name_;
::std::string* extendee_;
- static const ::std::string _default_extendee_;
+ int type_;
+ ::google::protobuf::int32 oneof_index_;
::std::string* default_value_;
- static const ::std::string _default_default_value_;
::google::protobuf::FieldOptions* 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();
-
- ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
+
+ void InitAsDefaultInstance();
+ static FieldDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Message {
+ public:
+ OneofDescriptorProto();
+ virtual ~OneofDescriptorProto();
+
+ OneofDescriptorProto(const OneofDescriptorProto& from);
+
+ inline OneofDescriptorProto& operator=(const OneofDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
}
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
}
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
}
-
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const OneofDescriptorProto& default_instance();
+
+ void Swap(OneofDescriptorProto* other);
+
+ // implements Message ----------------------------------------------
+
+ OneofDescriptorProto* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const OneofDescriptorProto& from);
+ void MergeFrom(const OneofDescriptorProto& 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* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // optional string name = 1;
+ inline bool has_name() const;
+ inline void clear_name();
+ static const int kNameFieldNumber = 1;
+ inline const ::std::string& name() const;
+ inline void set_name(const ::std::string& value);
+ inline void set_name(const char* value);
+ inline void set_name(const char* value, size_t size);
+ inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
+ inline void set_allocated_name(::std::string* name);
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto)
+ private:
+ inline void set_has_name();
+ inline void clear_has_name();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
+ mutable int _cached_size_;
+ ::std::string* name_;
+ 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 FieldDescriptorProto* default_instance_;
+ static OneofDescriptorProto* default_instance_;
};
// -------------------------------------------------------------------
@@ -920,29 +1053,29 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
public:
EnumDescriptorProto();
virtual ~EnumDescriptorProto();
-
+
EnumDescriptorProto(const EnumDescriptorProto& from);
-
+
inline EnumDescriptorProto& operator=(const EnumDescriptorProto& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const EnumDescriptorProto& default_instance();
-
+
void Swap(EnumDescriptorProto* other);
-
+
// implements Message ----------------------------------------------
-
+
EnumDescriptorProto* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -950,7 +1083,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
void MergeFrom(const EnumDescriptorProto& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -963,13 +1096,12 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
// optional string name = 1;
inline bool has_name() const;
inline void clear_name();
@@ -979,7 +1111,9 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
-
+ inline ::std::string* release_name();
+ inline void set_allocated_name(::std::string* name);
+
// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
inline int value_size() const;
inline void clear_value();
@@ -991,40 +1125,34 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
value() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
mutable_value();
-
+
// optional .google.protobuf.EnumOptions options = 3;
inline bool has_options() const;
inline void clear_options();
static const int kOptionsFieldNumber = 3;
inline const ::google::protobuf::EnumOptions& options() const;
inline ::google::protobuf::EnumOptions* mutable_options();
-
+ inline ::google::protobuf::EnumOptions* release_options();
+ inline void set_allocated_options(::google::protobuf::EnumOptions* options);
+
// @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_options();
+ inline void clear_has_options();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::std::string* name_;
- static const ::std::string _default_name_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_;
::google::protobuf::EnumOptions* 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();
-
- ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static EnumDescriptorProto* default_instance_;
};
@@ -1034,29 +1162,29 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M
public:
EnumValueDescriptorProto();
virtual ~EnumValueDescriptorProto();
-
+
EnumValueDescriptorProto(const EnumValueDescriptorProto& from);
-
+
inline EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const EnumValueDescriptorProto& default_instance();
-
+
void Swap(EnumValueDescriptorProto* other);
-
+
// implements Message ----------------------------------------------
-
+
EnumValueDescriptorProto* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -1064,7 +1192,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M
void MergeFrom(const EnumValueDescriptorProto& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -1077,13 +1205,12 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
// optional string name = 1;
inline bool has_name() const;
inline void clear_name();
@@ -1093,47 +1220,45 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
-
+ inline ::std::string* release_name();
+ inline void set_allocated_name(::std::string* name);
+
// optional int32 number = 2;
inline bool has_number() const;
inline void clear_number();
static const int kNumberFieldNumber = 2;
inline ::google::protobuf::int32 number() const;
inline void set_number(::google::protobuf::int32 value);
-
+
// optional .google.protobuf.EnumValueOptions options = 3;
inline bool has_options() const;
inline void clear_options();
static const int kOptionsFieldNumber = 3;
inline const ::google::protobuf::EnumValueOptions& options() const;
inline ::google::protobuf::EnumValueOptions* mutable_options();
-
+ inline ::google::protobuf::EnumValueOptions* release_options();
+ inline void set_allocated_options(::google::protobuf::EnumValueOptions* options);
+
// @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_number();
+ inline void clear_has_number();
+ inline void set_has_options();
+ inline void clear_has_options();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::std::string* name_;
- static const ::std::string _default_name_;
- ::google::protobuf::int32 number_;
::google::protobuf::EnumValueOptions* options_;
+ ::google::protobuf::int32 number_;
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();
-
- ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static EnumValueDescriptorProto* default_instance_;
};
@@ -1143,29 +1268,29 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
public:
ServiceDescriptorProto();
virtual ~ServiceDescriptorProto();
-
+
ServiceDescriptorProto(const ServiceDescriptorProto& from);
-
+
inline ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const ServiceDescriptorProto& default_instance();
-
+
void Swap(ServiceDescriptorProto* other);
-
+
// implements Message ----------------------------------------------
-
+
ServiceDescriptorProto* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -1173,7 +1298,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
void MergeFrom(const ServiceDescriptorProto& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -1186,13 +1311,12 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
// optional string name = 1;
inline bool has_name() const;
inline void clear_name();
@@ -1202,7 +1326,9 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
-
+ inline ::std::string* release_name();
+ inline void set_allocated_name(::std::string* name);
+
// repeated .google.protobuf.MethodDescriptorProto method = 2;
inline int method_size() const;
inline void clear_method();
@@ -1214,40 +1340,34 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
method() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
mutable_method();
-
+
// optional .google.protobuf.ServiceOptions options = 3;
inline bool has_options() const;
inline void clear_options();
static const int kOptionsFieldNumber = 3;
inline const ::google::protobuf::ServiceOptions& options() const;
inline ::google::protobuf::ServiceOptions* mutable_options();
-
+ inline ::google::protobuf::ServiceOptions* release_options();
+ inline void set_allocated_options(::google::protobuf::ServiceOptions* options);
+
// @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_options();
+ inline void clear_has_options();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::std::string* name_;
- static const ::std::string _default_name_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_;
::google::protobuf::ServiceOptions* 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();
-
- ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static ServiceDescriptorProto* default_instance_;
};
@@ -1257,29 +1377,29 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
public:
MethodDescriptorProto();
virtual ~MethodDescriptorProto();
-
+
MethodDescriptorProto(const MethodDescriptorProto& from);
-
+
inline MethodDescriptorProto& operator=(const MethodDescriptorProto& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const MethodDescriptorProto& default_instance();
-
+
void Swap(MethodDescriptorProto* other);
-
+
// implements Message ----------------------------------------------
-
+
MethodDescriptorProto* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -1287,7 +1407,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
void MergeFrom(const MethodDescriptorProto& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -1300,13 +1420,12 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
// optional string name = 1;
inline bool has_name() const;
inline void clear_name();
@@ -1316,7 +1435,9 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
-
+ inline ::std::string* release_name();
+ inline void set_allocated_name(::std::string* name);
+
// optional string input_type = 2;
inline bool has_input_type() const;
inline void clear_input_type();
@@ -1326,7 +1447,9 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
inline void set_input_type(const char* value);
inline void set_input_type(const char* value, size_t size);
inline ::std::string* mutable_input_type();
-
+ inline ::std::string* release_input_type();
+ inline void set_allocated_input_type(::std::string* input_type);
+
// optional string output_type = 3;
inline bool has_output_type() const;
inline void clear_output_type();
@@ -1336,43 +1459,41 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
inline void set_output_type(const char* value);
inline void set_output_type(const char* value, size_t size);
inline ::std::string* mutable_output_type();
-
+ inline ::std::string* release_output_type();
+ inline void set_allocated_output_type(::std::string* output_type);
+
// optional .google.protobuf.MethodOptions options = 4;
inline bool has_options() const;
inline void clear_options();
static const int kOptionsFieldNumber = 4;
inline const ::google::protobuf::MethodOptions& options() const;
inline ::google::protobuf::MethodOptions* mutable_options();
-
+ inline ::google::protobuf::MethodOptions* release_options();
+ inline void set_allocated_options(::google::protobuf::MethodOptions* options);
+
// @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_input_type();
+ inline void clear_has_input_type();
+ inline void set_has_output_type();
+ inline void clear_has_output_type();
+ inline void set_has_options();
+ inline void clear_has_options();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::std::string* name_;
- static const ::std::string _default_name_;
::std::string* input_type_;
- static const ::std::string _default_input_type_;
::std::string* output_type_;
- static const ::std::string _default_output_type_;
::google::protobuf::MethodOptions* 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();
-
- ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static MethodDescriptorProto* default_instance_;
};
@@ -1382,29 +1503,29 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
public:
FileOptions();
virtual ~FileOptions();
-
+
FileOptions(const FileOptions& from);
-
+
inline FileOptions& operator=(const FileOptions& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const FileOptions& default_instance();
-
+
void Swap(FileOptions* other);
-
+
// implements Message ----------------------------------------------
-
+
FileOptions* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -1412,7 +1533,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
void MergeFrom(const FileOptions& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -1425,11 +1546,10 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
typedef FileOptions_OptimizeMode OptimizeMode;
static const OptimizeMode SPEED = FileOptions_OptimizeMode_SPEED;
static const OptimizeMode CODE_SIZE = FileOptions_OptimizeMode_CODE_SIZE;
@@ -1454,9 +1574,9 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
OptimizeMode* value) {
return FileOptions_OptimizeMode_Parse(name, value);
}
-
+
// accessors -------------------------------------------------------
-
+
// optional string java_package = 1;
inline bool has_java_package() const;
inline void clear_java_package();
@@ -1466,7 +1586,9 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
inline void set_java_package(const char* value);
inline void set_java_package(const char* value, size_t size);
inline ::std::string* mutable_java_package();
-
+ inline ::std::string* release_java_package();
+ inline void set_allocated_java_package(::std::string* java_package);
+
// optional string java_outer_classname = 8;
inline bool has_java_outer_classname() const;
inline void clear_java_outer_classname();
@@ -1476,42 +1598,77 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
inline void set_java_outer_classname(const char* value);
inline void set_java_outer_classname(const char* value, size_t size);
inline ::std::string* mutable_java_outer_classname();
-
+ inline ::std::string* release_java_outer_classname();
+ inline void set_allocated_java_outer_classname(::std::string* java_outer_classname);
+
// optional bool java_multiple_files = 10 [default = false];
inline bool has_java_multiple_files() const;
inline void clear_java_multiple_files();
static const int kJavaMultipleFilesFieldNumber = 10;
inline bool java_multiple_files() const;
inline void set_java_multiple_files(bool value);
-
+
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ inline bool has_java_generate_equals_and_hash() const;
+ inline void clear_java_generate_equals_and_hash();
+ static const int kJavaGenerateEqualsAndHashFieldNumber = 20;
+ inline bool java_generate_equals_and_hash() const;
+ inline void set_java_generate_equals_and_hash(bool value);
+
+ // optional bool java_string_check_utf8 = 27 [default = false];
+ inline bool has_java_string_check_utf8() const;
+ inline void clear_java_string_check_utf8();
+ static const int kJavaStringCheckUtf8FieldNumber = 27;
+ inline bool java_string_check_utf8() const;
+ inline void set_java_string_check_utf8(bool value);
+
// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
inline bool has_optimize_for() const;
inline void clear_optimize_for();
static const int kOptimizeForFieldNumber = 9;
inline ::google::protobuf::FileOptions_OptimizeMode optimize_for() const;
inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value);
-
- // optional bool cc_generic_services = 16 [default = true];
+
+ // optional string go_package = 11;
+ inline bool has_go_package() const;
+ inline void clear_go_package();
+ static const int kGoPackageFieldNumber = 11;
+ inline const ::std::string& go_package() const;
+ inline void set_go_package(const ::std::string& value);
+ inline void set_go_package(const char* value);
+ inline void set_go_package(const char* value, size_t size);
+ inline ::std::string* mutable_go_package();
+ inline ::std::string* release_go_package();
+ inline void set_allocated_go_package(::std::string* go_package);
+
+ // optional bool cc_generic_services = 16 [default = false];
inline bool has_cc_generic_services() const;
inline void clear_cc_generic_services();
static const int kCcGenericServicesFieldNumber = 16;
inline bool cc_generic_services() const;
inline void set_cc_generic_services(bool value);
-
- // optional bool java_generic_services = 17 [default = true];
+
+ // optional bool java_generic_services = 17 [default = false];
inline bool has_java_generic_services() const;
inline void clear_java_generic_services();
static const int kJavaGenericServicesFieldNumber = 17;
inline bool java_generic_services() const;
inline void set_java_generic_services(bool value);
-
- // optional bool py_generic_services = 18 [default = true];
+
+ // optional bool py_generic_services = 18 [default = false];
inline bool has_py_generic_services() const;
inline void clear_py_generic_services();
static const int kPyGenericServicesFieldNumber = 18;
inline bool py_generic_services() const;
inline void set_py_generic_services(bool value);
-
+
+ // optional bool deprecated = 23 [default = false];
+ inline bool has_deprecated() const;
+ inline void clear_deprecated();
+ static const int kDeprecatedFieldNumber = 23;
+ inline bool deprecated() const;
+ inline void set_deprecated(bool value);
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int uninterpreted_option_size() const;
inline void clear_uninterpreted_option();
@@ -1523,41 +1680,55 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
uninterpreted_option() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
-
+
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
private:
+ inline void set_has_java_package();
+ inline void clear_has_java_package();
+ inline void set_has_java_outer_classname();
+ inline void clear_has_java_outer_classname();
+ inline void set_has_java_multiple_files();
+ inline void clear_has_java_multiple_files();
+ inline void set_has_java_generate_equals_and_hash();
+ inline void clear_has_java_generate_equals_and_hash();
+ inline void set_has_java_string_check_utf8();
+ inline void clear_has_java_string_check_utf8();
+ inline void set_has_optimize_for();
+ inline void clear_has_optimize_for();
+ inline void set_has_go_package();
+ inline void clear_has_go_package();
+ inline void set_has_cc_generic_services();
+ inline void clear_has_cc_generic_services();
+ inline void set_has_java_generic_services();
+ inline void clear_has_java_generic_services();
+ inline void set_has_py_generic_services();
+ inline void clear_has_py_generic_services();
+ inline void set_has_deprecated();
+ inline void clear_has_deprecated();
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::std::string* java_package_;
- static const ::std::string _default_java_package_;
::std::string* java_outer_classname_;
- static const ::std::string _default_java_outer_classname_;
bool java_multiple_files_;
- int optimize_for_;
+ bool java_generate_equals_and_hash_;
+ bool java_string_check_utf8_;
bool cc_generic_services_;
+ int optimize_for_;
+ ::std::string* go_package_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
bool java_generic_services_;
bool py_generic_services_;
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+ bool deprecated_;
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();
-
- ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static FileOptions* default_instance_;
};
@@ -1567,29 +1738,29 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
public:
MessageOptions();
virtual ~MessageOptions();
-
+
MessageOptions(const MessageOptions& from);
-
+
inline MessageOptions& operator=(const MessageOptions& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const MessageOptions& default_instance();
-
+
void Swap(MessageOptions* other);
-
+
// implements Message ----------------------------------------------
-
+
MessageOptions* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -1597,7 +1768,7 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
void MergeFrom(const MessageOptions& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -1610,27 +1781,33 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
// optional bool message_set_wire_format = 1 [default = false];
inline bool has_message_set_wire_format() const;
inline void clear_message_set_wire_format();
static const int kMessageSetWireFormatFieldNumber = 1;
inline bool message_set_wire_format() const;
inline void set_message_set_wire_format(bool value);
-
+
// optional bool no_standard_descriptor_accessor = 2 [default = false];
inline bool has_no_standard_descriptor_accessor() const;
inline void clear_no_standard_descriptor_accessor();
static const int kNoStandardDescriptorAccessorFieldNumber = 2;
inline bool no_standard_descriptor_accessor() const;
inline void set_no_standard_descriptor_accessor(bool value);
-
+
+ // optional bool deprecated = 3 [default = false];
+ inline bool has_deprecated() const;
+ inline void clear_deprecated();
+ static const int kDeprecatedFieldNumber = 3;
+ inline bool deprecated() const;
+ inline void set_deprecated(bool value);
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int uninterpreted_option_size() const;
inline void clear_uninterpreted_option();
@@ -1642,34 +1819,31 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
uninterpreted_option() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
-
+
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
private:
+ inline void set_has_message_set_wire_format();
+ inline void clear_has_message_set_wire_format();
+ inline void set_has_no_standard_descriptor_accessor();
+ inline void clear_has_no_standard_descriptor_accessor();
+ inline void set_has_deprecated();
+ inline void clear_has_deprecated();
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
bool message_set_wire_format_;
bool no_standard_descriptor_accessor_;
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+ bool deprecated_;
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();
-
- ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static MessageOptions* default_instance_;
};
@@ -1679,29 +1853,29 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
public:
FieldOptions();
virtual ~FieldOptions();
-
+
FieldOptions(const FieldOptions& from);
-
+
inline FieldOptions& operator=(const FieldOptions& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const FieldOptions& default_instance();
-
+
void Swap(FieldOptions* other);
-
+
// implements Message ----------------------------------------------
-
+
FieldOptions* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -1709,7 +1883,7 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
void MergeFrom(const FieldOptions& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -1722,11 +1896,10 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
typedef FieldOptions_CType CType;
static const CType STRING = FieldOptions_CType_STRING;
static const CType CORD = FieldOptions_CType_CORD;
@@ -1751,30 +1924,37 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
CType* value) {
return FieldOptions_CType_Parse(name, value);
}
-
+
// accessors -------------------------------------------------------
-
+
// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
inline bool has_ctype() const;
inline void clear_ctype();
static const int kCtypeFieldNumber = 1;
inline ::google::protobuf::FieldOptions_CType ctype() const;
inline void set_ctype(::google::protobuf::FieldOptions_CType value);
-
+
// optional bool packed = 2;
inline bool has_packed() const;
inline void clear_packed();
static const int kPackedFieldNumber = 2;
inline bool packed() const;
inline void set_packed(bool value);
-
+
+ // optional bool lazy = 5 [default = false];
+ inline bool has_lazy() const;
+ inline void clear_lazy();
+ static const int kLazyFieldNumber = 5;
+ inline bool lazy() const;
+ inline void set_lazy(bool value);
+
// optional bool deprecated = 3 [default = false];
inline bool has_deprecated() const;
inline void clear_deprecated();
static const int kDeprecatedFieldNumber = 3;
inline bool deprecated() const;
inline void set_deprecated(bool value);
-
+
// optional string experimental_map_key = 9;
inline bool has_experimental_map_key() const;
inline void clear_experimental_map_key();
@@ -1784,7 +1964,16 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
inline void set_experimental_map_key(const char* value);
inline void set_experimental_map_key(const char* value, size_t size);
inline ::std::string* mutable_experimental_map_key();
-
+ inline ::std::string* release_experimental_map_key();
+ inline void set_allocated_experimental_map_key(::std::string* experimental_map_key);
+
+ // optional bool weak = 10 [default = false];
+ inline bool has_weak() const;
+ inline void clear_weak();
+ static const int kWeakFieldNumber = 10;
+ inline bool weak() const;
+ inline void set_weak(bool value);
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int uninterpreted_option_size() const;
inline void clear_uninterpreted_option();
@@ -1796,37 +1985,40 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
uninterpreted_option() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
-
+
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
private:
+ inline void set_has_ctype();
+ inline void clear_has_ctype();
+ inline void set_has_packed();
+ inline void clear_has_packed();
+ inline void set_has_lazy();
+ inline void clear_has_lazy();
+ inline void set_has_deprecated();
+ inline void clear_has_deprecated();
+ inline void set_has_experimental_map_key();
+ inline void clear_has_experimental_map_key();
+ inline void set_has_weak();
+ inline void clear_has_weak();
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
int ctype_;
bool packed_;
+ bool lazy_;
bool deprecated_;
+ bool weak_;
::std::string* experimental_map_key_;
- static const ::std::string _default_experimental_map_key_;
::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();
-
- ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static FieldOptions* default_instance_;
};
@@ -1836,29 +2028,29 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
public:
EnumOptions();
virtual ~EnumOptions();
-
+
EnumOptions(const EnumOptions& from);
-
+
inline EnumOptions& operator=(const EnumOptions& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const EnumOptions& default_instance();
-
+
void Swap(EnumOptions* other);
-
+
// implements Message ----------------------------------------------
-
+
EnumOptions* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -1866,7 +2058,7 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
void MergeFrom(const EnumOptions& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -1879,13 +2071,26 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
+ // optional bool allow_alias = 2;
+ inline bool has_allow_alias() const;
+ inline void clear_allow_alias();
+ static const int kAllowAliasFieldNumber = 2;
+ inline bool allow_alias() const;
+ inline void set_allow_alias(bool value);
+
+ // optional bool deprecated = 3 [default = false];
+ inline bool has_deprecated() const;
+ inline void clear_deprecated();
+ static const int kDeprecatedFieldNumber = 3;
+ inline bool deprecated() const;
+ inline void set_deprecated(bool value);
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int uninterpreted_option_size() const;
inline void clear_uninterpreted_option();
@@ -1897,32 +2102,28 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
uninterpreted_option() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
-
+
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
private:
+ inline void set_has_allow_alias();
+ inline void clear_has_allow_alias();
+ inline void set_has_deprecated();
+ inline void clear_has_deprecated();
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+ bool allow_alias_;
+ bool deprecated_;
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();
-
- ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static EnumOptions* default_instance_;
};
@@ -1932,29 +2133,29 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
public:
EnumValueOptions();
virtual ~EnumValueOptions();
-
+
EnumValueOptions(const EnumValueOptions& from);
-
+
inline EnumValueOptions& operator=(const EnumValueOptions& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const EnumValueOptions& default_instance();
-
+
void Swap(EnumValueOptions* other);
-
+
// implements Message ----------------------------------------------
-
+
EnumValueOptions* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -1962,7 +2163,7 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
void MergeFrom(const EnumValueOptions& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -1975,13 +2176,19 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
+ // optional bool deprecated = 1 [default = false];
+ inline bool has_deprecated() const;
+ inline void clear_deprecated();
+ static const int kDeprecatedFieldNumber = 1;
+ inline bool deprecated() const;
+ inline void set_deprecated(bool value);
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int uninterpreted_option_size() const;
inline void clear_uninterpreted_option();
@@ -1993,32 +2200,25 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
uninterpreted_option() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
-
+
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
private:
+ inline void set_has_deprecated();
+ inline void clear_has_deprecated();
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+ bool deprecated_;
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();
-
- ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static EnumValueOptions* default_instance_;
};
@@ -2028,29 +2228,29 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
public:
ServiceOptions();
virtual ~ServiceOptions();
-
+
ServiceOptions(const ServiceOptions& from);
-
+
inline ServiceOptions& operator=(const ServiceOptions& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const ServiceOptions& default_instance();
-
+
void Swap(ServiceOptions* other);
-
+
// implements Message ----------------------------------------------
-
+
ServiceOptions* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -2058,7 +2258,7 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
void MergeFrom(const ServiceOptions& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -2071,13 +2271,19 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
+ // optional bool deprecated = 33 [default = false];
+ inline bool has_deprecated() const;
+ inline void clear_deprecated();
+ static const int kDeprecatedFieldNumber = 33;
+ inline bool deprecated() const;
+ inline void set_deprecated(bool value);
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int uninterpreted_option_size() const;
inline void clear_uninterpreted_option();
@@ -2089,32 +2295,25 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
uninterpreted_option() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
-
+
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
private:
+ inline void set_has_deprecated();
+ inline void clear_has_deprecated();
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+ bool deprecated_;
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();
-
- ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static ServiceOptions* default_instance_;
};
@@ -2124,29 +2323,29 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
public:
MethodOptions();
virtual ~MethodOptions();
-
+
MethodOptions(const MethodOptions& from);
-
+
inline MethodOptions& operator=(const MethodOptions& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const MethodOptions& default_instance();
-
+
void Swap(MethodOptions* other);
-
+
// implements Message ----------------------------------------------
-
+
MethodOptions* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -2154,7 +2353,7 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
void MergeFrom(const MethodOptions& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -2167,13 +2366,19 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
+ // optional bool deprecated = 33 [default = false];
+ inline bool has_deprecated() const;
+ inline void clear_deprecated();
+ static const int kDeprecatedFieldNumber = 33;
+ inline bool deprecated() const;
+ inline void set_deprecated(bool value);
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int uninterpreted_option_size() const;
inline void clear_uninterpreted_option();
@@ -2185,32 +2390,25 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
uninterpreted_option() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
-
+
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
private:
+ inline void set_has_deprecated();
+ inline void clear_has_deprecated();
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+ bool deprecated_;
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();
-
- ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static MethodOptions* default_instance_;
};
@@ -2220,29 +2418,29 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu
public:
UninterpretedOption_NamePart();
virtual ~UninterpretedOption_NamePart();
-
+
UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from);
-
+
inline UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const UninterpretedOption_NamePart& default_instance();
-
+
void Swap(UninterpretedOption_NamePart* other);
-
+
// implements Message ----------------------------------------------
-
+
UninterpretedOption_NamePart* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -2250,7 +2448,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu
void MergeFrom(const UninterpretedOption_NamePart& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -2263,13 +2461,12 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
// accessors -------------------------------------------------------
-
+
// required string name_part = 1;
inline bool has_name_part() const;
inline void clear_name_part();
@@ -2279,39 +2476,33 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu
inline void set_name_part(const char* value);
inline void set_name_part(const char* value, size_t size);
inline ::std::string* mutable_name_part();
-
+ inline ::std::string* release_name_part();
+ inline void set_allocated_name_part(::std::string* name_part);
+
// required bool is_extension = 2;
inline bool has_is_extension() const;
inline void clear_is_extension();
static const int kIsExtensionFieldNumber = 2;
inline bool is_extension() const;
inline void set_is_extension(bool value);
-
+
// @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart)
private:
+ inline void set_has_name_part();
+ inline void clear_has_name_part();
+ inline void set_has_is_extension();
+ inline void clear_has_is_extension();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::std::string* name_part_;
- static const ::std::string _default_name_part_;
bool is_extension_;
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();
-
- ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
+
void InitAsDefaultInstance();
static UninterpretedOption_NamePart* default_instance_;
};
@@ -2321,29 +2512,29 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag
public:
UninterpretedOption();
virtual ~UninterpretedOption();
-
+
UninterpretedOption(const UninterpretedOption& from);
-
+
inline UninterpretedOption& operator=(const UninterpretedOption& from) {
CopyFrom(from);
return *this;
}
-
+
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
-
+
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
-
+
static const ::google::protobuf::Descriptor* descriptor();
static const UninterpretedOption& default_instance();
-
+
void Swap(UninterpretedOption* other);
-
+
// implements Message ----------------------------------------------
-
+
UninterpretedOption* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
@@ -2351,7 +2542,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag
void MergeFrom(const UninterpretedOption& from);
void Clear();
bool IsInitialized() const;
-
+
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
@@ -2364,15 +2555,14 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag
void SharedDtor();
void SetCachedSize(int size) const;
public:
-
::google::protobuf::Metadata GetMetadata() const;
-
+
// nested types ----------------------------------------------------
-
+
typedef UninterpretedOption_NamePart NamePart;
-
+
// accessors -------------------------------------------------------
-
+
// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
inline int name_size() const;
inline void clear_name();
@@ -2384,7 +2574,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag
name() const;
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
mutable_name();
-
+
// optional string identifier_value = 3;
inline bool has_identifier_value() const;
inline void clear_identifier_value();
@@ -2394,28 +2584,30 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag
inline void set_identifier_value(const char* value);
inline void set_identifier_value(const char* value, size_t size);
inline ::std::string* mutable_identifier_value();
-
+ inline ::std::string* release_identifier_value();
+ inline void set_allocated_identifier_value(::std::string* identifier_value);
+
// optional uint64 positive_int_value = 4;
inline bool has_positive_int_value() const;
inline void clear_positive_int_value();
static const int kPositiveIntValueFieldNumber = 4;
inline ::google::protobuf::uint64 positive_int_value() const;
inline void set_positive_int_value(::google::protobuf::uint64 value);
-
+
// optional int64 negative_int_value = 5;
inline bool has_negative_int_value() const;
inline void clear_negative_int_value();
static const int kNegativeIntValueFieldNumber = 5;
inline ::google::protobuf::int64 negative_int_value() const;
inline void set_negative_int_value(::google::protobuf::int64 value);
-
+
// optional double double_value = 6;
inline bool has_double_value() const;
inline void clear_double_value();
static const int kDoubleValueFieldNumber = 6;
inline double double_value() const;
inline void set_double_value(double value);
-
+
// optional bytes string_value = 7;
inline bool has_string_value() const;
inline void clear_string_value();
@@ -2425,39 +2617,264 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag
inline void set_string_value(const char* value);
inline void set_string_value(const void* value, size_t size);
inline ::std::string* mutable_string_value();
-
+ inline ::std::string* release_string_value();
+ inline void set_allocated_string_value(::std::string* string_value);
+
+ // optional string aggregate_value = 8;
+ inline bool has_aggregate_value() const;
+ inline void clear_aggregate_value();
+ static const int kAggregateValueFieldNumber = 8;
+ inline const ::std::string& aggregate_value() const;
+ inline void set_aggregate_value(const ::std::string& value);
+ inline void set_aggregate_value(const char* value);
+ inline void set_aggregate_value(const char* value, size_t size);
+ inline ::std::string* mutable_aggregate_value();
+ inline ::std::string* release_aggregate_value();
+ inline void set_allocated_aggregate_value(::std::string* aggregate_value);
+
// @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption)
private:
+ inline void set_has_identifier_value();
+ inline void clear_has_identifier_value();
+ inline void set_has_positive_int_value();
+ inline void clear_has_positive_int_value();
+ inline void set_has_negative_int_value();
+ inline void clear_has_negative_int_value();
+ inline void set_has_double_value();
+ inline void clear_has_double_value();
+ inline void set_has_string_value();
+ inline void clear_has_string_value();
+ inline void set_has_aggregate_value();
+ inline void clear_has_aggregate_value();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
-
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart > name_;
::std::string* identifier_value_;
- static const ::std::string _default_identifier_value_;
::google::protobuf::uint64 positive_int_value_;
::google::protobuf::int64 negative_int_value_;
double double_value_;
::std::string* string_value_;
- static const ::std::string _default_string_value_;
+ ::std::string* aggregate_value_;
+ 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 UninterpretedOption* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Message {
+ public:
+ SourceCodeInfo_Location();
+ virtual ~SourceCodeInfo_Location();
+
+ SourceCodeInfo_Location(const SourceCodeInfo_Location& from);
+
+ inline SourceCodeInfo_Location& operator=(const SourceCodeInfo_Location& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const SourceCodeInfo_Location& default_instance();
+
+ void Swap(SourceCodeInfo_Location* other);
+
+ // implements Message ----------------------------------------------
+
+ SourceCodeInfo_Location* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const SourceCodeInfo_Location& from);
+ void MergeFrom(const SourceCodeInfo_Location& 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* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // repeated int32 path = 1 [packed = true];
+ inline int path_size() const;
+ inline void clear_path();
+ static const int kPathFieldNumber = 1;
+ inline ::google::protobuf::int32 path(int index) const;
+ inline void set_path(int index, ::google::protobuf::int32 value);
+ inline void add_path(::google::protobuf::int32 value);
+ inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+ path() const;
+ inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+ mutable_path();
+
+ // repeated int32 span = 2 [packed = true];
+ inline int span_size() const;
+ inline void clear_span();
+ static const int kSpanFieldNumber = 2;
+ inline ::google::protobuf::int32 span(int index) const;
+ inline void set_span(int index, ::google::protobuf::int32 value);
+ inline void add_span(::google::protobuf::int32 value);
+ inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+ span() const;
+ inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+ mutable_span();
+
+ // optional string leading_comments = 3;
+ inline bool has_leading_comments() const;
+ inline void clear_leading_comments();
+ static const int kLeadingCommentsFieldNumber = 3;
+ inline const ::std::string& leading_comments() const;
+ inline void set_leading_comments(const ::std::string& value);
+ inline void set_leading_comments(const char* value);
+ inline void set_leading_comments(const char* value, size_t size);
+ inline ::std::string* mutable_leading_comments();
+ inline ::std::string* release_leading_comments();
+ inline void set_allocated_leading_comments(::std::string* leading_comments);
+
+ // optional string trailing_comments = 4;
+ inline bool has_trailing_comments() const;
+ inline void clear_trailing_comments();
+ static const int kTrailingCommentsFieldNumber = 4;
+ inline const ::std::string& trailing_comments() const;
+ inline void set_trailing_comments(const ::std::string& value);
+ inline void set_trailing_comments(const char* value);
+ inline void set_trailing_comments(const char* value, size_t size);
+ inline ::std::string* mutable_trailing_comments();
+ inline ::std::string* release_trailing_comments();
+ inline void set_allocated_trailing_comments(::std::string* trailing_comments);
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location)
+ private:
+ inline void set_has_leading_comments();
+ inline void clear_has_leading_comments();
+ inline void set_has_trailing_comments();
+ inline void clear_has_trailing_comments();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::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::RepeatedField< ::google::protobuf::int32 > span_;
+ mutable int _span_cached_byte_size_;
+ ::std::string* leading_comments_;
+ ::std::string* trailing_comments_;
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();
-
- ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
+
+ void InitAsDefaultInstance();
+ static SourceCodeInfo_Location* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message {
+ public:
+ SourceCodeInfo();
+ virtual ~SourceCodeInfo();
+
+ SourceCodeInfo(const SourceCodeInfo& from);
+
+ inline SourceCodeInfo& operator=(const SourceCodeInfo& from) {
+ CopyFrom(from);
+ return *this;
}
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
}
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
}
-
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const SourceCodeInfo& default_instance();
+
+ void Swap(SourceCodeInfo* other);
+
+ // implements Message ----------------------------------------------
+
+ SourceCodeInfo* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const SourceCodeInfo& from);
+ void MergeFrom(const SourceCodeInfo& 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* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ typedef SourceCodeInfo_Location Location;
+
+ // accessors -------------------------------------------------------
+
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ inline int location_size() const;
+ inline void clear_location();
+ static const int kLocationFieldNumber = 1;
+ inline const ::google::protobuf::SourceCodeInfo_Location& location(int index) const;
+ inline ::google::protobuf::SourceCodeInfo_Location* mutable_location(int index);
+ inline ::google::protobuf::SourceCodeInfo_Location* add_location();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
+ location() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
+ mutable_location();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo)
+ private:
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::uint32 _has_bits_[1];
+ mutable int _cached_size_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_;
+ 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 UninterpretedOption* default_instance_;
+ static SourceCodeInfo* default_instance_;
};
// ===================================================================
@@ -2474,20 +2891,25 @@ inline void FileDescriptorSet::clear_file() {
file_.Clear();
}
inline const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorSet.file)
return file_.Get(index);
}
inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorSet.file)
return file_.Mutable(index);
}
inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() {
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorSet.file)
return file_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
FileDescriptorSet::file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorSet.file)
return file_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
FileDescriptorSet::mutable_file() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorSet.file)
return &file_;
}
@@ -2497,87 +2919,155 @@ FileDescriptorSet::mutable_file() {
// optional string name = 1;
inline bool FileDescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FileDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void FileDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void FileDescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& FileDescriptorProto::name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.name)
return *name_;
}
inline void FileDescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.name)
}
inline void FileDescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.name)
}
inline void FileDescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.name)
}
inline ::std::string* FileDescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.name)
return name_;
}
+inline ::std::string* FileDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void FileDescriptorProto::set_allocated_name(::std::string* name) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete name_;
+ }
+ if (name) {
+ set_has_name();
+ name_ = name;
+ } else {
+ clear_has_name();
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.name)
+}
// optional string package = 2;
inline bool FileDescriptorProto::has_package() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FileDescriptorProto::set_has_package() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void FileDescriptorProto::clear_has_package() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void FileDescriptorProto::clear_package() {
- if (package_ != &_default_package_) {
+ if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
package_->clear();
}
- _clear_bit(1);
+ clear_has_package();
}
inline const ::std::string& FileDescriptorProto::package() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.package)
return *package_;
}
inline void FileDescriptorProto::set_package(const ::std::string& value) {
- _set_bit(1);
- if (package_ == &_default_package_) {
+ set_has_package();
+ if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
package_ = new ::std::string;
}
package_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.package)
}
inline void FileDescriptorProto::set_package(const char* value) {
- _set_bit(1);
- if (package_ == &_default_package_) {
+ set_has_package();
+ if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
package_ = new ::std::string;
}
package_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.package)
}
inline void FileDescriptorProto::set_package(const char* value, size_t size) {
- _set_bit(1);
- if (package_ == &_default_package_) {
+ set_has_package();
+ if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
package_ = new ::std::string;
}
package_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.package)
}
inline ::std::string* FileDescriptorProto::mutable_package() {
- _set_bit(1);
- if (package_ == &_default_package_) {
+ set_has_package();
+ if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
package_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.package)
return package_;
}
+inline ::std::string* FileDescriptorProto::release_package() {
+ clear_has_package();
+ if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = package_;
+ package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void FileDescriptorProto::set_allocated_package(::std::string* package) {
+ if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete package_;
+ }
+ if (package) {
+ set_has_package();
+ package_ = package;
+ } else {
+ clear_has_package();
+ package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.package)
+}
// repeated string dependency = 3;
inline int FileDescriptorProto::dependency_size() const {
@@ -2587,42 +3077,112 @@ inline void FileDescriptorProto::clear_dependency() {
dependency_.Clear();
}
inline const ::std::string& FileDescriptorProto::dependency(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.dependency)
return dependency_.Get(index);
}
inline ::std::string* FileDescriptorProto::mutable_dependency(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.dependency)
return dependency_.Mutable(index);
}
inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) {
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
dependency_.Mutable(index)->assign(value);
}
inline void FileDescriptorProto::set_dependency(int index, const char* value) {
dependency_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency)
}
inline void FileDescriptorProto::set_dependency(int index, const char* value, size_t size) {
dependency_.Mutable(index)->assign(
reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.dependency)
}
inline ::std::string* FileDescriptorProto::add_dependency() {
return dependency_.Add();
}
inline void FileDescriptorProto::add_dependency(const ::std::string& value) {
dependency_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
}
inline void FileDescriptorProto::add_dependency(const char* value) {
dependency_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency)
}
inline void FileDescriptorProto::add_dependency(const char* value, size_t size) {
dependency_.Add()->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_add_pointer:google.protobuf.FileDescriptorProto.dependency)
}
inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
FileDescriptorProto::dependency() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.dependency)
return dependency_;
}
inline ::google::protobuf::RepeatedPtrField< ::std::string>*
FileDescriptorProto::mutable_dependency() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.dependency)
return &dependency_;
}
+// repeated int32 public_dependency = 10;
+inline int FileDescriptorProto::public_dependency_size() const {
+ return public_dependency_.size();
+}
+inline void FileDescriptorProto::clear_public_dependency() {
+ public_dependency_.Clear();
+}
+inline ::google::protobuf::int32 FileDescriptorProto::public_dependency(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.public_dependency)
+ return public_dependency_.Get(index);
+}
+inline void FileDescriptorProto::set_public_dependency(int index, ::google::protobuf::int32 value) {
+ public_dependency_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.public_dependency)
+}
+inline void FileDescriptorProto::add_public_dependency(::google::protobuf::int32 value) {
+ public_dependency_.Add(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.public_dependency)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+FileDescriptorProto::public_dependency() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.public_dependency)
+ return public_dependency_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+FileDescriptorProto::mutable_public_dependency() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.public_dependency)
+ return &public_dependency_;
+}
+
+// repeated int32 weak_dependency = 11;
+inline int FileDescriptorProto::weak_dependency_size() const {
+ return weak_dependency_.size();
+}
+inline void FileDescriptorProto::clear_weak_dependency() {
+ weak_dependency_.Clear();
+}
+inline ::google::protobuf::int32 FileDescriptorProto::weak_dependency(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.weak_dependency)
+ return weak_dependency_.Get(index);
+}
+inline void FileDescriptorProto::set_weak_dependency(int index, ::google::protobuf::int32 value) {
+ weak_dependency_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.weak_dependency)
+}
+inline void FileDescriptorProto::add_weak_dependency(::google::protobuf::int32 value) {
+ weak_dependency_.Add(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.weak_dependency)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+FileDescriptorProto::weak_dependency() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.weak_dependency)
+ return weak_dependency_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+FileDescriptorProto::mutable_weak_dependency() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.weak_dependency)
+ return &weak_dependency_;
+}
+
// repeated .google.protobuf.DescriptorProto message_type = 4;
inline int FileDescriptorProto::message_type_size() const {
return message_type_.size();
@@ -2631,20 +3191,25 @@ inline void FileDescriptorProto::clear_message_type() {
message_type_.Clear();
}
inline const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.message_type)
return message_type_.Get(index);
}
inline ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.message_type)
return message_type_.Mutable(index);
}
inline ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() {
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.message_type)
return message_type_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
FileDescriptorProto::message_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.message_type)
return message_type_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
FileDescriptorProto::mutable_message_type() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.message_type)
return &message_type_;
}
@@ -2656,20 +3221,25 @@ inline void FileDescriptorProto::clear_enum_type() {
enum_type_.Clear();
}
inline const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.enum_type)
return enum_type_.Get(index);
}
inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.enum_type)
return enum_type_.Mutable(index);
}
inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() {
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.enum_type)
return enum_type_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
FileDescriptorProto::enum_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.enum_type)
return enum_type_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
FileDescriptorProto::mutable_enum_type() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.enum_type)
return &enum_type_;
}
@@ -2681,20 +3251,25 @@ inline void FileDescriptorProto::clear_service() {
service_.Clear();
}
inline const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.service)
return service_.Get(index);
}
inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.service)
return service_.Mutable(index);
}
inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() {
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.service)
return service_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
FileDescriptorProto::service() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.service)
return service_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
FileDescriptorProto::mutable_service() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.service)
return &service_;
}
@@ -2706,39 +3281,109 @@ inline void FileDescriptorProto::clear_extension() {
extension_.Clear();
}
inline const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.extension)
return extension_.Get(index);
}
inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.extension)
return extension_.Mutable(index);
}
inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() {
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.extension)
return extension_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
FileDescriptorProto::extension() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.extension)
return extension_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
FileDescriptorProto::mutable_extension() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.extension)
return &extension_;
}
// optional .google.protobuf.FileOptions options = 8;
inline bool FileDescriptorProto::has_options() const {
- return _has_bit(7);
+ return (_has_bits_[0] & 0x00000200u) != 0;
+}
+inline void FileDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000200u;
+}
+inline void FileDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000200u;
}
inline void FileDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
- _clear_bit(7);
+ clear_has_options();
}
inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
- _set_bit(7);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::FileOptions;
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.options)
return options_;
}
+inline ::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::FileOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+inline void FileDescriptorProto::set_allocated_options(::google::protobuf::FileOptions* options) {
+ delete options_;
+ options_ = options;
+ if (options) {
+ set_has_options();
+ } else {
+ clear_has_options();
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.options)
+}
+
+// optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+inline bool FileDescriptorProto::has_source_code_info() const {
+ return (_has_bits_[0] & 0x00000400u) != 0;
+}
+inline void FileDescriptorProto::set_has_source_code_info() {
+ _has_bits_[0] |= 0x00000400u;
+}
+inline void FileDescriptorProto::clear_has_source_code_info() {
+ _has_bits_[0] &= ~0x00000400u;
+}
+inline void FileDescriptorProto::clear_source_code_info() {
+ if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
+ clear_has_source_code_info();
+}
+inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info)
+ return source_code_info_ != NULL ? *source_code_info_ : *default_instance_->source_code_info_;
+}
+inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() {
+ set_has_source_code_info();
+ if (source_code_info_ == NULL) source_code_info_ = new ::google::protobuf::SourceCodeInfo;
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.source_code_info)
+ return source_code_info_;
+}
+inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
+ clear_has_source_code_info();
+ ::google::protobuf::SourceCodeInfo* temp = source_code_info_;
+ source_code_info_ = NULL;
+ return temp;
+}
+inline void FileDescriptorProto::set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info) {
+ delete source_code_info_;
+ source_code_info_ = source_code_info;
+ if (source_code_info) {
+ set_has_source_code_info();
+ } else {
+ clear_has_source_code_info();
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.source_code_info)
+}
// -------------------------------------------------------------------
@@ -2746,34 +3391,50 @@ inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
// optional int32 start = 1;
inline bool DescriptorProto_ExtensionRange::has_start() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void DescriptorProto_ExtensionRange::set_has_start() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void DescriptorProto_ExtensionRange::clear_has_start() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void DescriptorProto_ExtensionRange::clear_start() {
start_ = 0;
- _clear_bit(0);
+ clear_has_start();
}
inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.start)
return start_;
}
inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) {
- _set_bit(0);
+ set_has_start();
start_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.start)
}
// optional int32 end = 2;
inline bool DescriptorProto_ExtensionRange::has_end() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void DescriptorProto_ExtensionRange::set_has_end() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void DescriptorProto_ExtensionRange::clear_has_end() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void DescriptorProto_ExtensionRange::clear_end() {
end_ = 0;
- _clear_bit(1);
+ clear_has_end();
}
inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.end)
return end_;
}
inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) {
- _set_bit(1);
+ set_has_end();
end_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.end)
}
// -------------------------------------------------------------------
@@ -2782,45 +3443,79 @@ inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 va
// optional string name = 1;
inline bool DescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void DescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void DescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void DescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& DescriptorProto::name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.name)
return *name_;
}
inline void DescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.name)
}
inline void DescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.name)
}
inline void DescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.name)
}
inline ::std::string* DescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.name)
return name_;
}
+inline ::std::string* DescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void DescriptorProto::set_allocated_name(::std::string* name) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete name_;
+ }
+ if (name) {
+ set_has_name();
+ name_ = name;
+ } else {
+ clear_has_name();
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.name)
+}
// repeated .google.protobuf.FieldDescriptorProto field = 2;
inline int DescriptorProto::field_size() const {
@@ -2830,20 +3525,25 @@ inline void DescriptorProto::clear_field() {
field_.Clear();
}
inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.field)
return field_.Get(index);
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.field)
return field_.Mutable(index);
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() {
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.field)
return field_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
DescriptorProto::field() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.field)
return field_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
DescriptorProto::mutable_field() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.field)
return &field_;
}
@@ -2855,20 +3555,25 @@ inline void DescriptorProto::clear_extension() {
extension_.Clear();
}
inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension)
return extension_.Get(index);
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension)
return extension_.Mutable(index);
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() {
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension)
return extension_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
DescriptorProto::extension() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension)
return extension_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
DescriptorProto::mutable_extension() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension)
return &extension_;
}
@@ -2880,20 +3585,25 @@ inline void DescriptorProto::clear_nested_type() {
nested_type_.Clear();
}
inline const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.nested_type)
return nested_type_.Get(index);
}
inline ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.nested_type)
return nested_type_.Mutable(index);
}
inline ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() {
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.nested_type)
return nested_type_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
DescriptorProto::nested_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.nested_type)
return nested_type_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
DescriptorProto::mutable_nested_type() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.nested_type)
return &nested_type_;
}
@@ -2905,20 +3615,25 @@ inline void DescriptorProto::clear_enum_type() {
enum_type_.Clear();
}
inline const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.enum_type)
return enum_type_.Get(index);
}
inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.enum_type)
return enum_type_.Mutable(index);
}
inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() {
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.enum_type)
return enum_type_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
DescriptorProto::enum_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.enum_type)
return enum_type_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
DescriptorProto::mutable_enum_type() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.enum_type)
return &enum_type_;
}
@@ -2930,39 +3645,98 @@ inline void DescriptorProto::clear_extension_range() {
extension_range_.Clear();
}
inline const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension_range)
return extension_range_.Get(index);
}
inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension_range)
return extension_range_.Mutable(index);
}
inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() {
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension_range)
return extension_range_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
DescriptorProto::extension_range() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension_range)
return extension_range_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
DescriptorProto::mutable_extension_range() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension_range)
return &extension_range_;
}
+// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+inline int DescriptorProto::oneof_decl_size() const {
+ return oneof_decl_.size();
+}
+inline void DescriptorProto::clear_oneof_decl() {
+ oneof_decl_.Clear();
+}
+inline const ::google::protobuf::OneofDescriptorProto& DescriptorProto::oneof_decl(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.oneof_decl)
+ return oneof_decl_.Get(index);
+}
+inline ::google::protobuf::OneofDescriptorProto* DescriptorProto::mutable_oneof_decl(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.oneof_decl)
+ return oneof_decl_.Mutable(index);
+}
+inline ::google::protobuf::OneofDescriptorProto* DescriptorProto::add_oneof_decl() {
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.oneof_decl)
+ return oneof_decl_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
+DescriptorProto::oneof_decl() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.oneof_decl)
+ return oneof_decl_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
+DescriptorProto::mutable_oneof_decl() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.oneof_decl)
+ return &oneof_decl_;
+}
+
// optional .google.protobuf.MessageOptions options = 7;
inline bool DescriptorProto::has_options() const {
- return _has_bit(6);
+ return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void DescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000080u;
+}
+inline void DescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000080u;
}
inline void DescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
- _clear_bit(6);
+ clear_has_options();
}
inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
- _set_bit(6);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::MessageOptions;
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.options)
return options_;
}
+inline ::google::protobuf::MessageOptions* DescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::MessageOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+inline void DescriptorProto::set_allocated_options(::google::protobuf::MessageOptions* options) {
+ delete options_;
+ options_ = options;
+ if (options) {
+ set_has_options();
+ } else {
+ clear_has_options();
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.options)
+}
// -------------------------------------------------------------------
@@ -2970,238 +3744,526 @@ inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
// optional string name = 1;
inline bool FieldDescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FieldDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void FieldDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void FieldDescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& FieldDescriptorProto::name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.name)
return *name_;
}
inline void FieldDescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.name)
}
inline void FieldDescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.name)
}
inline void FieldDescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.name)
}
inline ::std::string* FieldDescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.name)
return name_;
}
+inline ::std::string* FieldDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void FieldDescriptorProto::set_allocated_name(::std::string* name) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete name_;
+ }
+ if (name) {
+ set_has_name();
+ name_ = name;
+ } else {
+ clear_has_name();
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.name)
+}
// optional int32 number = 3;
inline bool FieldDescriptorProto::has_number() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FieldDescriptorProto::set_has_number() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void FieldDescriptorProto::clear_has_number() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void FieldDescriptorProto::clear_number() {
number_ = 0;
- _clear_bit(1);
+ clear_has_number();
}
inline ::google::protobuf::int32 FieldDescriptorProto::number() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.number)
return number_;
}
inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) {
- _set_bit(1);
+ set_has_number();
number_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.number)
}
// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
inline bool FieldDescriptorProto::has_label() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void FieldDescriptorProto::set_has_label() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void FieldDescriptorProto::clear_has_label() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void FieldDescriptorProto::clear_label() {
label_ = 1;
- _clear_bit(2);
+ clear_has_label();
}
inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.label)
return static_cast< ::google::protobuf::FieldDescriptorProto_Label >(label_);
}
inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) {
- GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Label_IsValid(value));
- _set_bit(2);
+ assert(::google::protobuf::FieldDescriptorProto_Label_IsValid(value));
+ set_has_label();
label_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.label)
}
// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
inline bool FieldDescriptorProto::has_type() const {
- return _has_bit(3);
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void FieldDescriptorProto::set_has_type() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void FieldDescriptorProto::clear_has_type() {
+ _has_bits_[0] &= ~0x00000008u;
}
inline void FieldDescriptorProto::clear_type() {
type_ = 1;
- _clear_bit(3);
+ clear_has_type();
}
inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type)
return static_cast< ::google::protobuf::FieldDescriptorProto_Type >(type_);
}
inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) {
- GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Type_IsValid(value));
- _set_bit(3);
+ assert(::google::protobuf::FieldDescriptorProto_Type_IsValid(value));
+ set_has_type();
type_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type)
}
// optional string type_name = 6;
inline bool FieldDescriptorProto::has_type_name() const {
- return _has_bit(4);
+ return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void FieldDescriptorProto::set_has_type_name() {
+ _has_bits_[0] |= 0x00000010u;
+}
+inline void FieldDescriptorProto::clear_has_type_name() {
+ _has_bits_[0] &= ~0x00000010u;
}
inline void FieldDescriptorProto::clear_type_name() {
- if (type_name_ != &_default_type_name_) {
+ if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
type_name_->clear();
}
- _clear_bit(4);
+ clear_has_type_name();
}
inline const ::std::string& FieldDescriptorProto::type_name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type_name)
return *type_name_;
}
inline void FieldDescriptorProto::set_type_name(const ::std::string& value) {
- _set_bit(4);
- if (type_name_ == &_default_type_name_) {
+ set_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
type_name_ = new ::std::string;
}
type_name_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type_name)
}
inline void FieldDescriptorProto::set_type_name(const char* value) {
- _set_bit(4);
- if (type_name_ == &_default_type_name_) {
+ set_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
type_name_ = new ::std::string;
}
type_name_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.type_name)
}
inline void FieldDescriptorProto::set_type_name(const char* value, size_t size) {
- _set_bit(4);
- if (type_name_ == &_default_type_name_) {
+ set_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
type_name_ = new ::std::string;
}
type_name_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.type_name)
}
inline ::std::string* FieldDescriptorProto::mutable_type_name() {
- _set_bit(4);
- if (type_name_ == &_default_type_name_) {
+ set_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
type_name_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.type_name)
return type_name_;
}
+inline ::std::string* FieldDescriptorProto::release_type_name() {
+ clear_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = type_name_;
+ type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void FieldDescriptorProto::set_allocated_type_name(::std::string* type_name) {
+ if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete type_name_;
+ }
+ if (type_name) {
+ set_has_type_name();
+ type_name_ = type_name;
+ } else {
+ clear_has_type_name();
+ type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.type_name)
+}
// optional string extendee = 2;
inline bool FieldDescriptorProto::has_extendee() const {
- return _has_bit(5);
+ return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void FieldDescriptorProto::set_has_extendee() {
+ _has_bits_[0] |= 0x00000020u;
+}
+inline void FieldDescriptorProto::clear_has_extendee() {
+ _has_bits_[0] &= ~0x00000020u;
}
inline void FieldDescriptorProto::clear_extendee() {
- if (extendee_ != &_default_extendee_) {
+ if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
extendee_->clear();
}
- _clear_bit(5);
+ clear_has_extendee();
}
inline const ::std::string& FieldDescriptorProto::extendee() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.extendee)
return *extendee_;
}
inline void FieldDescriptorProto::set_extendee(const ::std::string& value) {
- _set_bit(5);
- if (extendee_ == &_default_extendee_) {
+ set_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
extendee_ = new ::std::string;
}
extendee_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.extendee)
}
inline void FieldDescriptorProto::set_extendee(const char* value) {
- _set_bit(5);
- if (extendee_ == &_default_extendee_) {
+ set_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
extendee_ = new ::std::string;
}
extendee_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.extendee)
}
inline void FieldDescriptorProto::set_extendee(const char* value, size_t size) {
- _set_bit(5);
- if (extendee_ == &_default_extendee_) {
+ set_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
extendee_ = new ::std::string;
}
extendee_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.extendee)
}
inline ::std::string* FieldDescriptorProto::mutable_extendee() {
- _set_bit(5);
- if (extendee_ == &_default_extendee_) {
+ set_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
extendee_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.extendee)
return extendee_;
}
+inline ::std::string* FieldDescriptorProto::release_extendee() {
+ clear_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = extendee_;
+ extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void FieldDescriptorProto::set_allocated_extendee(::std::string* extendee) {
+ if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete extendee_;
+ }
+ if (extendee) {
+ set_has_extendee();
+ extendee_ = extendee;
+ } else {
+ clear_has_extendee();
+ extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.extendee)
+}
// optional string default_value = 7;
inline bool FieldDescriptorProto::has_default_value() const {
- return _has_bit(6);
+ return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void FieldDescriptorProto::set_has_default_value() {
+ _has_bits_[0] |= 0x00000040u;
+}
+inline void FieldDescriptorProto::clear_has_default_value() {
+ _has_bits_[0] &= ~0x00000040u;
}
inline void FieldDescriptorProto::clear_default_value() {
- if (default_value_ != &_default_default_value_) {
+ if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
default_value_->clear();
}
- _clear_bit(6);
+ clear_has_default_value();
}
inline const ::std::string& FieldDescriptorProto::default_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.default_value)
return *default_value_;
}
inline void FieldDescriptorProto::set_default_value(const ::std::string& value) {
- _set_bit(6);
- if (default_value_ == &_default_default_value_) {
+ set_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
default_value_ = new ::std::string;
}
default_value_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.default_value)
}
inline void FieldDescriptorProto::set_default_value(const char* value) {
- _set_bit(6);
- if (default_value_ == &_default_default_value_) {
+ set_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
default_value_ = new ::std::string;
}
default_value_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.default_value)
}
inline void FieldDescriptorProto::set_default_value(const char* value, size_t size) {
- _set_bit(6);
- if (default_value_ == &_default_default_value_) {
+ set_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
default_value_ = new ::std::string;
}
default_value_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.default_value)
}
inline ::std::string* FieldDescriptorProto::mutable_default_value() {
- _set_bit(6);
- if (default_value_ == &_default_default_value_) {
+ set_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
default_value_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.default_value)
return default_value_;
}
+inline ::std::string* FieldDescriptorProto::release_default_value() {
+ clear_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = default_value_;
+ default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void FieldDescriptorProto::set_allocated_default_value(::std::string* default_value) {
+ if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete default_value_;
+ }
+ if (default_value) {
+ set_has_default_value();
+ default_value_ = default_value;
+ } else {
+ clear_has_default_value();
+ default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.default_value)
+}
+
+// optional int32 oneof_index = 9;
+inline bool FieldDescriptorProto::has_oneof_index() const {
+ return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void FieldDescriptorProto::set_has_oneof_index() {
+ _has_bits_[0] |= 0x00000080u;
+}
+inline void FieldDescriptorProto::clear_has_oneof_index() {
+ _has_bits_[0] &= ~0x00000080u;
+}
+inline void FieldDescriptorProto::clear_oneof_index() {
+ oneof_index_ = 0;
+ clear_has_oneof_index();
+}
+inline ::google::protobuf::int32 FieldDescriptorProto::oneof_index() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.oneof_index)
+ return oneof_index_;
+}
+inline void FieldDescriptorProto::set_oneof_index(::google::protobuf::int32 value) {
+ set_has_oneof_index();
+ oneof_index_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.oneof_index)
+}
// optional .google.protobuf.FieldOptions options = 8;
inline bool FieldDescriptorProto::has_options() const {
- return _has_bit(7);
+ return (_has_bits_[0] & 0x00000100u) != 0;
+}
+inline void FieldDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000100u;
+}
+inline void FieldDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000100u;
}
inline void FieldDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
- _clear_bit(7);
+ clear_has_options();
}
inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() {
- _set_bit(7);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::FieldOptions;
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.options)
return options_;
}
+inline ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::FieldOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+inline void FieldDescriptorProto::set_allocated_options(::google::protobuf::FieldOptions* options) {
+ delete options_;
+ options_ = options;
+ if (options) {
+ set_has_options();
+ } else {
+ clear_has_options();
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.options)
+}
+
+// -------------------------------------------------------------------
+
+// OneofDescriptorProto
+
+// optional string name = 1;
+inline bool OneofDescriptorProto::has_name() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void OneofDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void OneofDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void OneofDescriptorProto::clear_name() {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ name_->clear();
+ }
+ clear_has_name();
+}
+inline const ::std::string& OneofDescriptorProto::name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.name)
+ return *name_;
+}
+inline void OneofDescriptorProto::set_name(const ::std::string& value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.OneofDescriptorProto.name)
+}
+inline void OneofDescriptorProto::set_name(const char* value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.OneofDescriptorProto.name)
+}
+inline void OneofDescriptorProto::set_name(const char* value, size_t size) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ name_ = new ::std::string;
+ }
+ name_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.OneofDescriptorProto.name)
+}
+inline ::std::string* OneofDescriptorProto::mutable_name() {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ name_ = new ::std::string;
+ }
+ // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.name)
+ return name_;
+}
+inline ::std::string* OneofDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void OneofDescriptorProto::set_allocated_name(::std::string* name) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete name_;
+ }
+ if (name) {
+ set_has_name();
+ name_ = name;
+ } else {
+ clear_has_name();
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name)
+}
// -------------------------------------------------------------------
@@ -3209,45 +4271,79 @@ inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options()
// optional string name = 1;
inline bool EnumDescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void EnumDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void EnumDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void EnumDescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& EnumDescriptorProto::name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.name)
return *name_;
}
inline void EnumDescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.name)
}
inline void EnumDescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.name)
}
inline void EnumDescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumDescriptorProto.name)
}
inline ::std::string* EnumDescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.name)
return name_;
}
+inline ::std::string* EnumDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void EnumDescriptorProto::set_allocated_name(::std::string* name) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete name_;
+ }
+ if (name) {
+ set_has_name();
+ name_ = name;
+ } else {
+ clear_has_name();
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.name)
+}
// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
inline int EnumDescriptorProto::value_size() const {
@@ -3257,39 +4353,68 @@ inline void EnumDescriptorProto::clear_value() {
value_.Clear();
}
inline const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.value)
return value_.Get(index);
}
inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.value)
return value_.Mutable(index);
}
inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() {
+ // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.value)
return value_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
EnumDescriptorProto::value() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.value)
return value_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
EnumDescriptorProto::mutable_value() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.value)
return &value_;
}
// optional .google.protobuf.EnumOptions options = 3;
inline bool EnumDescriptorProto::has_options() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void EnumDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void EnumDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void EnumDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
- _clear_bit(2);
+ clear_has_options();
}
inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
- _set_bit(2);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::EnumOptions;
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.options)
return options_;
}
+inline ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::EnumOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+inline void EnumDescriptorProto::set_allocated_options(::google::protobuf::EnumOptions* options) {
+ delete options_;
+ options_ = options;
+ if (options) {
+ set_has_options();
+ } else {
+ clear_has_options();
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.options)
+}
// -------------------------------------------------------------------
@@ -3297,78 +4422,144 @@ inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
// optional string name = 1;
inline bool EnumValueDescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void EnumValueDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void EnumValueDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void EnumValueDescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& EnumValueDescriptorProto::name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.name)
return *name_;
}
inline void EnumValueDescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.name)
}
inline void EnumValueDescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValueDescriptorProto.name)
}
inline void EnumValueDescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValueDescriptorProto.name)
}
inline ::std::string* EnumValueDescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.name)
return name_;
}
+inline ::std::string* EnumValueDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void EnumValueDescriptorProto::set_allocated_name(::std::string* name) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete name_;
+ }
+ if (name) {
+ set_has_name();
+ name_ = name;
+ } else {
+ clear_has_name();
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.name)
+}
// optional int32 number = 2;
inline bool EnumValueDescriptorProto::has_number() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void EnumValueDescriptorProto::set_has_number() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void EnumValueDescriptorProto::clear_has_number() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void EnumValueDescriptorProto::clear_number() {
number_ = 0;
- _clear_bit(1);
+ clear_has_number();
}
inline ::google::protobuf::int32 EnumValueDescriptorProto::number() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.number)
return number_;
}
inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) {
- _set_bit(1);
+ set_has_number();
number_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.number)
}
// optional .google.protobuf.EnumValueOptions options = 3;
inline bool EnumValueDescriptorProto::has_options() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void EnumValueDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void EnumValueDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void EnumValueDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
- _clear_bit(2);
+ clear_has_options();
}
inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() {
- _set_bit(2);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::EnumValueOptions;
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.options)
return options_;
}
+inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::EnumValueOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+inline void EnumValueDescriptorProto::set_allocated_options(::google::protobuf::EnumValueOptions* options) {
+ delete options_;
+ options_ = options;
+ if (options) {
+ set_has_options();
+ } else {
+ clear_has_options();
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
+}
// -------------------------------------------------------------------
@@ -3376,45 +4567,79 @@ inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_o
// optional string name = 1;
inline bool ServiceDescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void ServiceDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void ServiceDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void ServiceDescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& ServiceDescriptorProto::name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.name)
return *name_;
}
inline void ServiceDescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.ServiceDescriptorProto.name)
}
inline void ServiceDescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.ServiceDescriptorProto.name)
}
inline void ServiceDescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.ServiceDescriptorProto.name)
}
inline ::std::string* ServiceDescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.name)
return name_;
}
+inline ::std::string* ServiceDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void ServiceDescriptorProto::set_allocated_name(::std::string* name) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete name_;
+ }
+ if (name) {
+ set_has_name();
+ name_ = name;
+ } else {
+ clear_has_name();
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.name)
+}
// repeated .google.protobuf.MethodDescriptorProto method = 2;
inline int ServiceDescriptorProto::method_size() const {
@@ -3424,39 +4649,68 @@ inline void ServiceDescriptorProto::clear_method() {
method_.Clear();
}
inline const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.method)
return method_.Get(index);
}
inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.method)
return method_.Mutable(index);
}
inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() {
+ // @@protoc_insertion_point(field_add:google.protobuf.ServiceDescriptorProto.method)
return method_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
ServiceDescriptorProto::method() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.ServiceDescriptorProto.method)
return method_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
ServiceDescriptorProto::mutable_method() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceDescriptorProto.method)
return &method_;
}
// optional .google.protobuf.ServiceOptions options = 3;
inline bool ServiceDescriptorProto::has_options() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void ServiceDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void ServiceDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void ServiceDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
- _clear_bit(2);
+ clear_has_options();
}
inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() {
- _set_bit(2);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::ServiceOptions;
+ // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.options)
return options_;
}
+inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::ServiceOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+inline void ServiceDescriptorProto::set_allocated_options(::google::protobuf::ServiceOptions* options) {
+ delete options_;
+ options_ = options;
+ if (options) {
+ set_has_options();
+ } else {
+ clear_has_options();
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.options)
+}
// -------------------------------------------------------------------
@@ -3464,146 +4718,272 @@ inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_optio
// optional string name = 1;
inline bool MethodDescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void MethodDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void MethodDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void MethodDescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& MethodDescriptorProto::name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.name)
return *name_;
}
inline void MethodDescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.name)
}
inline void MethodDescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.name)
}
inline void MethodDescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.name)
}
inline ::std::string* MethodDescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.name)
return name_;
}
+inline ::std::string* MethodDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void MethodDescriptorProto::set_allocated_name(::std::string* name) {
+ if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete name_;
+ }
+ if (name) {
+ set_has_name();
+ name_ = name;
+ } else {
+ clear_has_name();
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.name)
+}
// optional string input_type = 2;
inline bool MethodDescriptorProto::has_input_type() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void MethodDescriptorProto::set_has_input_type() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void MethodDescriptorProto::clear_has_input_type() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void MethodDescriptorProto::clear_input_type() {
- if (input_type_ != &_default_input_type_) {
+ if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
input_type_->clear();
}
- _clear_bit(1);
+ clear_has_input_type();
}
inline const ::std::string& MethodDescriptorProto::input_type() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.input_type)
return *input_type_;
}
inline void MethodDescriptorProto::set_input_type(const ::std::string& value) {
- _set_bit(1);
- if (input_type_ == &_default_input_type_) {
+ set_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
input_type_ = new ::std::string;
}
input_type_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.input_type)
}
inline void MethodDescriptorProto::set_input_type(const char* value) {
- _set_bit(1);
- if (input_type_ == &_default_input_type_) {
+ set_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
input_type_ = new ::std::string;
}
input_type_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.input_type)
}
inline void MethodDescriptorProto::set_input_type(const char* value, size_t size) {
- _set_bit(1);
- if (input_type_ == &_default_input_type_) {
+ set_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
input_type_ = new ::std::string;
}
input_type_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.input_type)
}
inline ::std::string* MethodDescriptorProto::mutable_input_type() {
- _set_bit(1);
- if (input_type_ == &_default_input_type_) {
+ set_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
input_type_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.input_type)
return input_type_;
}
+inline ::std::string* MethodDescriptorProto::release_input_type() {
+ clear_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = input_type_;
+ input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void MethodDescriptorProto::set_allocated_input_type(::std::string* input_type) {
+ if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete input_type_;
+ }
+ if (input_type) {
+ set_has_input_type();
+ input_type_ = input_type;
+ } else {
+ clear_has_input_type();
+ input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.input_type)
+}
// optional string output_type = 3;
inline bool MethodDescriptorProto::has_output_type() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void MethodDescriptorProto::set_has_output_type() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void MethodDescriptorProto::clear_has_output_type() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void MethodDescriptorProto::clear_output_type() {
- if (output_type_ != &_default_output_type_) {
+ if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
output_type_->clear();
}
- _clear_bit(2);
+ clear_has_output_type();
}
inline const ::std::string& MethodDescriptorProto::output_type() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.output_type)
return *output_type_;
}
inline void MethodDescriptorProto::set_output_type(const ::std::string& value) {
- _set_bit(2);
- if (output_type_ == &_default_output_type_) {
+ set_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
output_type_ = new ::std::string;
}
output_type_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.output_type)
}
inline void MethodDescriptorProto::set_output_type(const char* value) {
- _set_bit(2);
- if (output_type_ == &_default_output_type_) {
+ set_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
output_type_ = new ::std::string;
}
output_type_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.output_type)
}
inline void MethodDescriptorProto::set_output_type(const char* value, size_t size) {
- _set_bit(2);
- if (output_type_ == &_default_output_type_) {
+ set_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
output_type_ = new ::std::string;
}
output_type_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.output_type)
}
inline ::std::string* MethodDescriptorProto::mutable_output_type() {
- _set_bit(2);
- if (output_type_ == &_default_output_type_) {
+ set_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
output_type_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.output_type)
return output_type_;
}
+inline ::std::string* MethodDescriptorProto::release_output_type() {
+ clear_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = output_type_;
+ output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void MethodDescriptorProto::set_allocated_output_type(::std::string* output_type) {
+ if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete output_type_;
+ }
+ if (output_type) {
+ set_has_output_type();
+ output_type_ = output_type;
+ } else {
+ clear_has_output_type();
+ output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.output_type)
+}
// optional .google.protobuf.MethodOptions options = 4;
inline bool MethodDescriptorProto::has_options() const {
- return _has_bit(3);
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void MethodDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void MethodDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000008u;
}
inline void MethodDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
- _clear_bit(3);
+ clear_has_options();
}
inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() {
- _set_bit(3);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::MethodOptions;
+ // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.options)
return options_;
}
+inline ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::MethodOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+inline void MethodDescriptorProto::set_allocated_options(::google::protobuf::MethodOptions* options) {
+ delete options_;
+ options_ = options;
+ if (options) {
+ set_has_options();
+ } else {
+ clear_has_options();
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.options)
+}
// -------------------------------------------------------------------
@@ -3611,167 +4991,423 @@ inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options
// optional string java_package = 1;
inline bool FileOptions::has_java_package() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FileOptions::set_has_java_package() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void FileOptions::clear_has_java_package() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void FileOptions::clear_java_package() {
- if (java_package_ != &_default_java_package_) {
+ if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
java_package_->clear();
}
- _clear_bit(0);
+ clear_has_java_package();
}
inline const ::std::string& FileOptions::java_package() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_package)
return *java_package_;
}
inline void FileOptions::set_java_package(const ::std::string& value) {
- _set_bit(0);
- if (java_package_ == &_default_java_package_) {
+ set_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
java_package_ = new ::std::string;
}
java_package_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_package)
}
inline void FileOptions::set_java_package(const char* value) {
- _set_bit(0);
- if (java_package_ == &_default_java_package_) {
+ set_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
java_package_ = new ::std::string;
}
java_package_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_package)
}
inline void FileOptions::set_java_package(const char* value, size_t size) {
- _set_bit(0);
- if (java_package_ == &_default_java_package_) {
+ set_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
java_package_ = new ::std::string;
}
java_package_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_package)
}
inline ::std::string* FileOptions::mutable_java_package() {
- _set_bit(0);
- if (java_package_ == &_default_java_package_) {
+ set_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
java_package_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_package)
return java_package_;
}
+inline ::std::string* FileOptions::release_java_package() {
+ clear_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = java_package_;
+ java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void FileOptions::set_allocated_java_package(::std::string* java_package) {
+ if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete java_package_;
+ }
+ if (java_package) {
+ set_has_java_package();
+ java_package_ = java_package;
+ } else {
+ clear_has_java_package();
+ java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_package)
+}
// optional string java_outer_classname = 8;
inline bool FileOptions::has_java_outer_classname() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FileOptions::set_has_java_outer_classname() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void FileOptions::clear_has_java_outer_classname() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void FileOptions::clear_java_outer_classname() {
- if (java_outer_classname_ != &_default_java_outer_classname_) {
+ if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
java_outer_classname_->clear();
}
- _clear_bit(1);
+ clear_has_java_outer_classname();
}
inline const ::std::string& FileOptions::java_outer_classname() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_outer_classname)
return *java_outer_classname_;
}
inline void FileOptions::set_java_outer_classname(const ::std::string& value) {
- _set_bit(1);
- if (java_outer_classname_ == &_default_java_outer_classname_) {
+ set_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
java_outer_classname_ = new ::std::string;
}
java_outer_classname_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_outer_classname)
}
inline void FileOptions::set_java_outer_classname(const char* value) {
- _set_bit(1);
- if (java_outer_classname_ == &_default_java_outer_classname_) {
+ set_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
java_outer_classname_ = new ::std::string;
}
java_outer_classname_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_outer_classname)
}
inline void FileOptions::set_java_outer_classname(const char* value, size_t size) {
- _set_bit(1);
- if (java_outer_classname_ == &_default_java_outer_classname_) {
+ set_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
java_outer_classname_ = new ::std::string;
}
java_outer_classname_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_outer_classname)
}
inline ::std::string* FileOptions::mutable_java_outer_classname() {
- _set_bit(1);
- if (java_outer_classname_ == &_default_java_outer_classname_) {
+ set_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
java_outer_classname_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_outer_classname)
return java_outer_classname_;
}
+inline ::std::string* FileOptions::release_java_outer_classname() {
+ clear_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = java_outer_classname_;
+ java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void FileOptions::set_allocated_java_outer_classname(::std::string* java_outer_classname) {
+ if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete java_outer_classname_;
+ }
+ if (java_outer_classname) {
+ set_has_java_outer_classname();
+ java_outer_classname_ = java_outer_classname;
+ } else {
+ clear_has_java_outer_classname();
+ java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_outer_classname)
+}
// optional bool java_multiple_files = 10 [default = false];
inline bool FileOptions::has_java_multiple_files() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void FileOptions::set_has_java_multiple_files() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void FileOptions::clear_has_java_multiple_files() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void FileOptions::clear_java_multiple_files() {
java_multiple_files_ = false;
- _clear_bit(2);
+ clear_has_java_multiple_files();
}
inline bool FileOptions::java_multiple_files() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_multiple_files)
return java_multiple_files_;
}
inline void FileOptions::set_java_multiple_files(bool value) {
- _set_bit(2);
+ set_has_java_multiple_files();
java_multiple_files_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_multiple_files)
+}
+
+// optional bool java_generate_equals_and_hash = 20 [default = false];
+inline bool FileOptions::has_java_generate_equals_and_hash() const {
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void FileOptions::set_has_java_generate_equals_and_hash() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void FileOptions::clear_has_java_generate_equals_and_hash() {
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline void FileOptions::clear_java_generate_equals_and_hash() {
+ java_generate_equals_and_hash_ = false;
+ clear_has_java_generate_equals_and_hash();
+}
+inline bool FileOptions::java_generate_equals_and_hash() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generate_equals_and_hash)
+ return java_generate_equals_and_hash_;
+}
+inline void FileOptions::set_java_generate_equals_and_hash(bool value) {
+ set_has_java_generate_equals_and_hash();
+ java_generate_equals_and_hash_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generate_equals_and_hash)
+}
+
+// optional bool java_string_check_utf8 = 27 [default = false];
+inline bool FileOptions::has_java_string_check_utf8() const {
+ return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void FileOptions::set_has_java_string_check_utf8() {
+ _has_bits_[0] |= 0x00000010u;
+}
+inline void FileOptions::clear_has_java_string_check_utf8() {
+ _has_bits_[0] &= ~0x00000010u;
+}
+inline void FileOptions::clear_java_string_check_utf8() {
+ java_string_check_utf8_ = false;
+ clear_has_java_string_check_utf8();
+}
+inline bool FileOptions::java_string_check_utf8() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_string_check_utf8)
+ return java_string_check_utf8_;
+}
+inline void FileOptions::set_java_string_check_utf8(bool value) {
+ set_has_java_string_check_utf8();
+ java_string_check_utf8_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_string_check_utf8)
}
// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
inline bool FileOptions::has_optimize_for() const {
- return _has_bit(3);
+ return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void FileOptions::set_has_optimize_for() {
+ _has_bits_[0] |= 0x00000020u;
+}
+inline void FileOptions::clear_has_optimize_for() {
+ _has_bits_[0] &= ~0x00000020u;
}
inline void FileOptions::clear_optimize_for() {
optimize_for_ = 1;
- _clear_bit(3);
+ clear_has_optimize_for();
}
inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.optimize_for)
return static_cast< ::google::protobuf::FileOptions_OptimizeMode >(optimize_for_);
}
inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) {
- GOOGLE_DCHECK(::google::protobuf::FileOptions_OptimizeMode_IsValid(value));
- _set_bit(3);
+ assert(::google::protobuf::FileOptions_OptimizeMode_IsValid(value));
+ set_has_optimize_for();
optimize_for_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.optimize_for)
}
-// optional bool cc_generic_services = 16 [default = true];
+// optional string go_package = 11;
+inline bool FileOptions::has_go_package() const {
+ return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void FileOptions::set_has_go_package() {
+ _has_bits_[0] |= 0x00000040u;
+}
+inline void FileOptions::clear_has_go_package() {
+ _has_bits_[0] &= ~0x00000040u;
+}
+inline void FileOptions::clear_go_package() {
+ if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ go_package_->clear();
+ }
+ clear_has_go_package();
+}
+inline const ::std::string& FileOptions::go_package() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.go_package)
+ return *go_package_;
+}
+inline void FileOptions::set_go_package(const ::std::string& value) {
+ set_has_go_package();
+ if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ go_package_ = new ::std::string;
+ }
+ go_package_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.go_package)
+}
+inline void FileOptions::set_go_package(const char* value) {
+ set_has_go_package();
+ if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ go_package_ = new ::std::string;
+ }
+ go_package_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.go_package)
+}
+inline void FileOptions::set_go_package(const char* value, size_t size) {
+ set_has_go_package();
+ if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ go_package_ = new ::std::string;
+ }
+ go_package_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.go_package)
+}
+inline ::std::string* FileOptions::mutable_go_package() {
+ set_has_go_package();
+ if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ go_package_ = new ::std::string;
+ }
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.go_package)
+ return go_package_;
+}
+inline ::std::string* FileOptions::release_go_package() {
+ clear_has_go_package();
+ if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = go_package_;
+ go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void FileOptions::set_allocated_go_package(::std::string* go_package) {
+ if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete go_package_;
+ }
+ if (go_package) {
+ set_has_go_package();
+ go_package_ = go_package;
+ } else {
+ clear_has_go_package();
+ go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.go_package)
+}
+
+// optional bool cc_generic_services = 16 [default = false];
inline bool FileOptions::has_cc_generic_services() const {
- return _has_bit(4);
+ return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void FileOptions::set_has_cc_generic_services() {
+ _has_bits_[0] |= 0x00000080u;
+}
+inline void FileOptions::clear_has_cc_generic_services() {
+ _has_bits_[0] &= ~0x00000080u;
}
inline void FileOptions::clear_cc_generic_services() {
- cc_generic_services_ = true;
- _clear_bit(4);
+ cc_generic_services_ = false;
+ clear_has_cc_generic_services();
}
inline bool FileOptions::cc_generic_services() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_generic_services)
return cc_generic_services_;
}
inline void FileOptions::set_cc_generic_services(bool value) {
- _set_bit(4);
+ set_has_cc_generic_services();
cc_generic_services_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_generic_services)
}
-// optional bool java_generic_services = 17 [default = true];
+// optional bool java_generic_services = 17 [default = false];
inline bool FileOptions::has_java_generic_services() const {
- return _has_bit(5);
+ return (_has_bits_[0] & 0x00000100u) != 0;
+}
+inline void FileOptions::set_has_java_generic_services() {
+ _has_bits_[0] |= 0x00000100u;
+}
+inline void FileOptions::clear_has_java_generic_services() {
+ _has_bits_[0] &= ~0x00000100u;
}
inline void FileOptions::clear_java_generic_services() {
- java_generic_services_ = true;
- _clear_bit(5);
+ java_generic_services_ = false;
+ clear_has_java_generic_services();
}
inline bool FileOptions::java_generic_services() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generic_services)
return java_generic_services_;
}
inline void FileOptions::set_java_generic_services(bool value) {
- _set_bit(5);
+ set_has_java_generic_services();
java_generic_services_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generic_services)
}
-// optional bool py_generic_services = 18 [default = true];
+// optional bool py_generic_services = 18 [default = false];
inline bool FileOptions::has_py_generic_services() const {
- return _has_bit(6);
+ return (_has_bits_[0] & 0x00000200u) != 0;
+}
+inline void FileOptions::set_has_py_generic_services() {
+ _has_bits_[0] |= 0x00000200u;
+}
+inline void FileOptions::clear_has_py_generic_services() {
+ _has_bits_[0] &= ~0x00000200u;
}
inline void FileOptions::clear_py_generic_services() {
- py_generic_services_ = true;
- _clear_bit(6);
+ py_generic_services_ = false;
+ clear_has_py_generic_services();
}
inline bool FileOptions::py_generic_services() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.py_generic_services)
return py_generic_services_;
}
inline void FileOptions::set_py_generic_services(bool value) {
- _set_bit(6);
+ set_has_py_generic_services();
py_generic_services_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services)
+}
+
+// optional bool deprecated = 23 [default = false];
+inline bool FileOptions::has_deprecated() const {
+ return (_has_bits_[0] & 0x00000400u) != 0;
+}
+inline void FileOptions::set_has_deprecated() {
+ _has_bits_[0] |= 0x00000400u;
+}
+inline void FileOptions::clear_has_deprecated() {
+ _has_bits_[0] &= ~0x00000400u;
+}
+inline void FileOptions::clear_deprecated() {
+ deprecated_ = false;
+ clear_has_deprecated();
+}
+inline bool FileOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.deprecated)
+ return deprecated_;
+}
+inline void FileOptions::set_deprecated(bool value) {
+ set_has_deprecated();
+ deprecated_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.deprecated)
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
@@ -3782,20 +5418,25 @@ inline void FileOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() {
+ // @@protoc_insertion_point(field_add:google.protobuf.FileOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
FileOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileOptions.uninterpreted_option)
return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
FileOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileOptions.uninterpreted_option)
return &uninterpreted_option_;
}
@@ -3805,34 +5446,74 @@ FileOptions::mutable_uninterpreted_option() {
// optional bool message_set_wire_format = 1 [default = false];
inline bool MessageOptions::has_message_set_wire_format() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void MessageOptions::set_has_message_set_wire_format() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void MessageOptions::clear_has_message_set_wire_format() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void MessageOptions::clear_message_set_wire_format() {
message_set_wire_format_ = false;
- _clear_bit(0);
+ clear_has_message_set_wire_format();
}
inline bool MessageOptions::message_set_wire_format() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.message_set_wire_format)
return message_set_wire_format_;
}
inline void MessageOptions::set_message_set_wire_format(bool value) {
- _set_bit(0);
+ set_has_message_set_wire_format();
message_set_wire_format_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.message_set_wire_format)
}
// optional bool no_standard_descriptor_accessor = 2 [default = false];
inline bool MessageOptions::has_no_standard_descriptor_accessor() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void MessageOptions::set_has_no_standard_descriptor_accessor() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void MessageOptions::clear_has_no_standard_descriptor_accessor() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void MessageOptions::clear_no_standard_descriptor_accessor() {
no_standard_descriptor_accessor_ = false;
- _clear_bit(1);
+ clear_has_no_standard_descriptor_accessor();
}
inline bool MessageOptions::no_standard_descriptor_accessor() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
return no_standard_descriptor_accessor_;
}
inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) {
- _set_bit(1);
+ set_has_no_standard_descriptor_accessor();
no_standard_descriptor_accessor_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
+}
+
+// optional bool deprecated = 3 [default = false];
+inline bool MessageOptions::has_deprecated() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void MessageOptions::set_has_deprecated() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void MessageOptions::clear_has_deprecated() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void MessageOptions::clear_deprecated() {
+ deprecated_ = false;
+ clear_has_deprecated();
+}
+inline bool MessageOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.deprecated)
+ return deprecated_;
+}
+inline void MessageOptions::set_deprecated(bool value) {
+ set_has_deprecated();
+ deprecated_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated)
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
@@ -3843,20 +5524,25 @@ inline void MessageOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.MessageOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* MessageOptions::add_uninterpreted_option() {
+ // @@protoc_insertion_point(field_add:google.protobuf.MessageOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
MessageOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.MessageOptions.uninterpreted_option)
return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
MessageOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.MessageOptions.uninterpreted_option)
return &uninterpreted_option_;
}
@@ -3866,94 +5552,200 @@ MessageOptions::mutable_uninterpreted_option() {
// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
inline bool FieldOptions::has_ctype() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FieldOptions::set_has_ctype() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void FieldOptions::clear_has_ctype() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void FieldOptions::clear_ctype() {
ctype_ = 0;
- _clear_bit(0);
+ clear_has_ctype();
}
inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.ctype)
return static_cast< ::google::protobuf::FieldOptions_CType >(ctype_);
}
inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) {
- GOOGLE_DCHECK(::google::protobuf::FieldOptions_CType_IsValid(value));
- _set_bit(0);
+ assert(::google::protobuf::FieldOptions_CType_IsValid(value));
+ set_has_ctype();
ctype_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.ctype)
}
// optional bool packed = 2;
inline bool FieldOptions::has_packed() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FieldOptions::set_has_packed() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void FieldOptions::clear_has_packed() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void FieldOptions::clear_packed() {
packed_ = false;
- _clear_bit(1);
+ clear_has_packed();
}
inline bool FieldOptions::packed() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.packed)
return packed_;
}
inline void FieldOptions::set_packed(bool value) {
- _set_bit(1);
+ set_has_packed();
packed_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.packed)
+}
+
+// optional bool lazy = 5 [default = false];
+inline bool FieldOptions::has_lazy() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void FieldOptions::set_has_lazy() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void FieldOptions::clear_has_lazy() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void FieldOptions::clear_lazy() {
+ lazy_ = false;
+ clear_has_lazy();
+}
+inline bool FieldOptions::lazy() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.lazy)
+ return lazy_;
+}
+inline void FieldOptions::set_lazy(bool value) {
+ set_has_lazy();
+ lazy_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.lazy)
}
// optional bool deprecated = 3 [default = false];
inline bool FieldOptions::has_deprecated() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void FieldOptions::set_has_deprecated() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void FieldOptions::clear_has_deprecated() {
+ _has_bits_[0] &= ~0x00000008u;
}
inline void FieldOptions::clear_deprecated() {
deprecated_ = false;
- _clear_bit(2);
+ clear_has_deprecated();
}
inline bool FieldOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.deprecated)
return deprecated_;
}
inline void FieldOptions::set_deprecated(bool value) {
- _set_bit(2);
+ set_has_deprecated();
deprecated_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.deprecated)
}
// optional string experimental_map_key = 9;
inline bool FieldOptions::has_experimental_map_key() const {
- return _has_bit(3);
+ return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void FieldOptions::set_has_experimental_map_key() {
+ _has_bits_[0] |= 0x00000010u;
+}
+inline void FieldOptions::clear_has_experimental_map_key() {
+ _has_bits_[0] &= ~0x00000010u;
}
inline void FieldOptions::clear_experimental_map_key() {
- if (experimental_map_key_ != &_default_experimental_map_key_) {
+ if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
experimental_map_key_->clear();
}
- _clear_bit(3);
+ clear_has_experimental_map_key();
}
inline const ::std::string& FieldOptions::experimental_map_key() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.experimental_map_key)
return *experimental_map_key_;
}
inline void FieldOptions::set_experimental_map_key(const ::std::string& value) {
- _set_bit(3);
- if (experimental_map_key_ == &_default_experimental_map_key_) {
+ set_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
experimental_map_key_ = new ::std::string;
}
experimental_map_key_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.experimental_map_key)
}
inline void FieldOptions::set_experimental_map_key(const char* value) {
- _set_bit(3);
- if (experimental_map_key_ == &_default_experimental_map_key_) {
+ set_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
experimental_map_key_ = new ::std::string;
}
experimental_map_key_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.FieldOptions.experimental_map_key)
}
inline void FieldOptions::set_experimental_map_key(const char* value, size_t size) {
- _set_bit(3);
- if (experimental_map_key_ == &_default_experimental_map_key_) {
+ set_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
experimental_map_key_ = new ::std::string;
}
experimental_map_key_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldOptions.experimental_map_key)
}
inline ::std::string* FieldOptions::mutable_experimental_map_key() {
- _set_bit(3);
- if (experimental_map_key_ == &_default_experimental_map_key_) {
+ set_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
experimental_map_key_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.experimental_map_key)
return experimental_map_key_;
}
+inline ::std::string* FieldOptions::release_experimental_map_key() {
+ clear_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = experimental_map_key_;
+ experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void FieldOptions::set_allocated_experimental_map_key(::std::string* experimental_map_key) {
+ if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete experimental_map_key_;
+ }
+ if (experimental_map_key) {
+ set_has_experimental_map_key();
+ experimental_map_key_ = experimental_map_key;
+ } else {
+ clear_has_experimental_map_key();
+ experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldOptions.experimental_map_key)
+}
+
+// optional bool weak = 10 [default = false];
+inline bool FieldOptions::has_weak() const {
+ return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void FieldOptions::set_has_weak() {
+ _has_bits_[0] |= 0x00000020u;
+}
+inline void FieldOptions::clear_has_weak() {
+ _has_bits_[0] &= ~0x00000020u;
+}
+inline void FieldOptions::clear_weak() {
+ weak_ = false;
+ clear_has_weak();
+}
+inline bool FieldOptions::weak() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.weak)
+ return weak_;
+}
+inline void FieldOptions::set_weak(bool value) {
+ set_has_weak();
+ weak_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.weak)
+}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int FieldOptions::uninterpreted_option_size() const {
@@ -3963,20 +5755,25 @@ inline void FieldOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_option() {
+ // @@protoc_insertion_point(field_add:google.protobuf.FieldOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
FieldOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.uninterpreted_option)
return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
FieldOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldOptions.uninterpreted_option)
return &uninterpreted_option_;
}
@@ -3984,6 +5781,54 @@ FieldOptions::mutable_uninterpreted_option() {
// EnumOptions
+// optional bool allow_alias = 2;
+inline bool EnumOptions::has_allow_alias() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void EnumOptions::set_has_allow_alias() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void EnumOptions::clear_has_allow_alias() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void EnumOptions::clear_allow_alias() {
+ allow_alias_ = false;
+ clear_has_allow_alias();
+}
+inline bool EnumOptions::allow_alias() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.allow_alias)
+ return allow_alias_;
+}
+inline void EnumOptions::set_allow_alias(bool value) {
+ set_has_allow_alias();
+ allow_alias_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.allow_alias)
+}
+
+// optional bool deprecated = 3 [default = false];
+inline bool EnumOptions::has_deprecated() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void EnumOptions::set_has_deprecated() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void EnumOptions::clear_has_deprecated() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void EnumOptions::clear_deprecated() {
+ deprecated_ = false;
+ clear_has_deprecated();
+}
+inline bool EnumOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.deprecated)
+ return deprecated_;
+}
+inline void EnumOptions::set_deprecated(bool value) {
+ set_has_deprecated();
+ deprecated_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated)
+}
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int EnumOptions::uninterpreted_option_size() const {
return uninterpreted_option_.size();
@@ -3992,20 +5837,25 @@ inline void EnumOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_option() {
+ // @@protoc_insertion_point(field_add:google.protobuf.EnumOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
EnumOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumOptions.uninterpreted_option)
return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
EnumOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumOptions.uninterpreted_option)
return &uninterpreted_option_;
}
@@ -4013,6 +5863,30 @@ EnumOptions::mutable_uninterpreted_option() {
// EnumValueOptions
+// optional bool deprecated = 1 [default = false];
+inline bool EnumValueOptions::has_deprecated() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void EnumValueOptions::set_has_deprecated() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void EnumValueOptions::clear_has_deprecated() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void EnumValueOptions::clear_deprecated() {
+ deprecated_ = false;
+ clear_has_deprecated();
+}
+inline bool EnumValueOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.deprecated)
+ return deprecated_;
+}
+inline void EnumValueOptions::set_deprecated(bool value) {
+ set_has_deprecated();
+ deprecated_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumValueOptions.deprecated)
+}
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int EnumValueOptions::uninterpreted_option_size() const {
return uninterpreted_option_.size();
@@ -4021,20 +5895,25 @@ inline void EnumValueOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() {
+ // @@protoc_insertion_point(field_add:google.protobuf.EnumValueOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
EnumValueOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumValueOptions.uninterpreted_option)
return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
EnumValueOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValueOptions.uninterpreted_option)
return &uninterpreted_option_;
}
@@ -4042,6 +5921,30 @@ EnumValueOptions::mutable_uninterpreted_option() {
// ServiceOptions
+// optional bool deprecated = 33 [default = false];
+inline bool ServiceOptions::has_deprecated() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void ServiceOptions::set_has_deprecated() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void ServiceOptions::clear_has_deprecated() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void ServiceOptions::clear_deprecated() {
+ deprecated_ = false;
+ clear_has_deprecated();
+}
+inline bool ServiceOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.deprecated)
+ return deprecated_;
+}
+inline void ServiceOptions::set_deprecated(bool value) {
+ set_has_deprecated();
+ deprecated_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.ServiceOptions.deprecated)
+}
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int ServiceOptions::uninterpreted_option_size() const {
return uninterpreted_option_.size();
@@ -4050,20 +5953,25 @@ inline void ServiceOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterpreted_option() {
+ // @@protoc_insertion_point(field_add:google.protobuf.ServiceOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
ServiceOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.ServiceOptions.uninterpreted_option)
return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
ServiceOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceOptions.uninterpreted_option)
return &uninterpreted_option_;
}
@@ -4071,6 +5979,30 @@ ServiceOptions::mutable_uninterpreted_option() {
// MethodOptions
+// optional bool deprecated = 33 [default = false];
+inline bool MethodOptions::has_deprecated() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void MethodOptions::set_has_deprecated() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void MethodOptions::clear_has_deprecated() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void MethodOptions::clear_deprecated() {
+ deprecated_ = false;
+ clear_has_deprecated();
+}
+inline bool MethodOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.deprecated)
+ return deprecated_;
+}
+inline void MethodOptions::set_deprecated(bool value) {
+ set_has_deprecated();
+ deprecated_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.deprecated)
+}
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int MethodOptions::uninterpreted_option_size() const {
return uninterpreted_option_.size();
@@ -4079,20 +6011,25 @@ inline void MethodOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.MethodOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() {
+ // @@protoc_insertion_point(field_add:google.protobuf.MethodOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
MethodOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.MethodOptions.uninterpreted_option)
return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
MethodOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.MethodOptions.uninterpreted_option)
return &uninterpreted_option_;
}
@@ -4102,60 +6039,102 @@ MethodOptions::mutable_uninterpreted_option() {
// required string name_part = 1;
inline bool UninterpretedOption_NamePart::has_name_part() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void UninterpretedOption_NamePart::set_has_name_part() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void UninterpretedOption_NamePart::clear_has_name_part() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void UninterpretedOption_NamePart::clear_name_part() {
- if (name_part_ != &_default_name_part_) {
+ if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_part_->clear();
}
- _clear_bit(0);
+ clear_has_name_part();
}
inline const ::std::string& UninterpretedOption_NamePart::name_part() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.name_part)
return *name_part_;
}
inline void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) {
- _set_bit(0);
- if (name_part_ == &_default_name_part_) {
+ set_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_part_ = new ::std::string;
}
name_part_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.name_part)
}
inline void UninterpretedOption_NamePart::set_name_part(const char* value) {
- _set_bit(0);
- if (name_part_ == &_default_name_part_) {
+ set_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_part_ = new ::std::string;
}
name_part_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.NamePart.name_part)
}
inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) {
- _set_bit(0);
- if (name_part_ == &_default_name_part_) {
+ set_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_part_ = new ::std::string;
}
name_part_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.NamePart.name_part)
}
inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() {
- _set_bit(0);
- if (name_part_ == &_default_name_part_) {
+ set_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
name_part_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.NamePart.name_part)
return name_part_;
}
+inline ::std::string* UninterpretedOption_NamePart::release_name_part() {
+ clear_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_part_;
+ name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void UninterpretedOption_NamePart::set_allocated_name_part(::std::string* name_part) {
+ if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete name_part_;
+ }
+ if (name_part) {
+ set_has_name_part();
+ name_part_ = name_part;
+ } else {
+ clear_has_name_part();
+ name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.NamePart.name_part)
+}
// required bool is_extension = 2;
inline bool UninterpretedOption_NamePart::has_is_extension() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void UninterpretedOption_NamePart::set_has_is_extension() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void UninterpretedOption_NamePart::clear_has_is_extension() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void UninterpretedOption_NamePart::clear_is_extension() {
is_extension_ = false;
- _clear_bit(1);
+ clear_has_is_extension();
}
inline bool UninterpretedOption_NamePart::is_extension() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.is_extension)
return is_extension_;
}
inline void UninterpretedOption_NamePart::set_is_extension(bool value) {
- _set_bit(1);
+ set_has_is_extension();
is_extension_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.is_extension)
}
// -------------------------------------------------------------------
@@ -4170,154 +6149,577 @@ inline void UninterpretedOption::clear_name() {
name_.Clear();
}
inline const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.name)
return name_.Get(index);
}
inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.name)
return name_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() {
+ // @@protoc_insertion_point(field_add:google.protobuf.UninterpretedOption.name)
return name_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
UninterpretedOption::name() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name)
return name_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
UninterpretedOption::mutable_name() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.UninterpretedOption.name)
return &name_;
}
// optional string identifier_value = 3;
inline bool UninterpretedOption::has_identifier_value() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void UninterpretedOption::set_has_identifier_value() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void UninterpretedOption::clear_has_identifier_value() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void UninterpretedOption::clear_identifier_value() {
- if (identifier_value_ != &_default_identifier_value_) {
+ if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
identifier_value_->clear();
}
- _clear_bit(1);
+ clear_has_identifier_value();
}
inline const ::std::string& UninterpretedOption::identifier_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.identifier_value)
return *identifier_value_;
}
inline void UninterpretedOption::set_identifier_value(const ::std::string& value) {
- _set_bit(1);
- if (identifier_value_ == &_default_identifier_value_) {
+ set_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
identifier_value_ = new ::std::string;
}
identifier_value_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.identifier_value)
}
inline void UninterpretedOption::set_identifier_value(const char* value) {
- _set_bit(1);
- if (identifier_value_ == &_default_identifier_value_) {
+ set_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
identifier_value_ = new ::std::string;
}
identifier_value_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.identifier_value)
}
inline void UninterpretedOption::set_identifier_value(const char* value, size_t size) {
- _set_bit(1);
- if (identifier_value_ == &_default_identifier_value_) {
+ set_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
identifier_value_ = new ::std::string;
}
identifier_value_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.identifier_value)
}
inline ::std::string* UninterpretedOption::mutable_identifier_value() {
- _set_bit(1);
- if (identifier_value_ == &_default_identifier_value_) {
+ set_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
identifier_value_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.identifier_value)
return identifier_value_;
}
+inline ::std::string* UninterpretedOption::release_identifier_value() {
+ clear_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = identifier_value_;
+ identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void UninterpretedOption::set_allocated_identifier_value(::std::string* identifier_value) {
+ if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete identifier_value_;
+ }
+ if (identifier_value) {
+ set_has_identifier_value();
+ identifier_value_ = identifier_value;
+ } else {
+ clear_has_identifier_value();
+ identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.identifier_value)
+}
// optional uint64 positive_int_value = 4;
inline bool UninterpretedOption::has_positive_int_value() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void UninterpretedOption::set_has_positive_int_value() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void UninterpretedOption::clear_has_positive_int_value() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void UninterpretedOption::clear_positive_int_value() {
positive_int_value_ = GOOGLE_ULONGLONG(0);
- _clear_bit(2);
+ clear_has_positive_int_value();
}
inline ::google::protobuf::uint64 UninterpretedOption::positive_int_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.positive_int_value)
return positive_int_value_;
}
inline void UninterpretedOption::set_positive_int_value(::google::protobuf::uint64 value) {
- _set_bit(2);
+ set_has_positive_int_value();
positive_int_value_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.positive_int_value)
}
// optional int64 negative_int_value = 5;
inline bool UninterpretedOption::has_negative_int_value() const {
- return _has_bit(3);
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void UninterpretedOption::set_has_negative_int_value() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void UninterpretedOption::clear_has_negative_int_value() {
+ _has_bits_[0] &= ~0x00000008u;
}
inline void UninterpretedOption::clear_negative_int_value() {
negative_int_value_ = GOOGLE_LONGLONG(0);
- _clear_bit(3);
+ clear_has_negative_int_value();
}
inline ::google::protobuf::int64 UninterpretedOption::negative_int_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.negative_int_value)
return negative_int_value_;
}
inline void UninterpretedOption::set_negative_int_value(::google::protobuf::int64 value) {
- _set_bit(3);
+ set_has_negative_int_value();
negative_int_value_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.negative_int_value)
}
// optional double double_value = 6;
inline bool UninterpretedOption::has_double_value() const {
- return _has_bit(4);
+ return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void UninterpretedOption::set_has_double_value() {
+ _has_bits_[0] |= 0x00000010u;
+}
+inline void UninterpretedOption::clear_has_double_value() {
+ _has_bits_[0] &= ~0x00000010u;
}
inline void UninterpretedOption::clear_double_value() {
double_value_ = 0;
- _clear_bit(4);
+ clear_has_double_value();
}
inline double UninterpretedOption::double_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.double_value)
return double_value_;
}
inline void UninterpretedOption::set_double_value(double value) {
- _set_bit(4);
+ set_has_double_value();
double_value_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.double_value)
}
// optional bytes string_value = 7;
inline bool UninterpretedOption::has_string_value() const {
- return _has_bit(5);
+ return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void UninterpretedOption::set_has_string_value() {
+ _has_bits_[0] |= 0x00000020u;
+}
+inline void UninterpretedOption::clear_has_string_value() {
+ _has_bits_[0] &= ~0x00000020u;
}
inline void UninterpretedOption::clear_string_value() {
- if (string_value_ != &_default_string_value_) {
+ if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
string_value_->clear();
}
- _clear_bit(5);
+ clear_has_string_value();
}
inline const ::std::string& UninterpretedOption::string_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.string_value)
return *string_value_;
}
inline void UninterpretedOption::set_string_value(const ::std::string& value) {
- _set_bit(5);
- if (string_value_ == &_default_string_value_) {
+ set_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
string_value_ = new ::std::string;
}
string_value_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.string_value)
}
inline void UninterpretedOption::set_string_value(const char* value) {
- _set_bit(5);
- if (string_value_ == &_default_string_value_) {
+ set_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
string_value_ = new ::std::string;
}
string_value_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.string_value)
}
inline void UninterpretedOption::set_string_value(const void* value, size_t size) {
- _set_bit(5);
- if (string_value_ == &_default_string_value_) {
+ set_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
string_value_ = new ::std::string;
}
string_value_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.string_value)
}
inline ::std::string* UninterpretedOption::mutable_string_value() {
- _set_bit(5);
- if (string_value_ == &_default_string_value_) {
+ set_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
string_value_ = new ::std::string;
}
+ // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.string_value)
return string_value_;
}
+inline ::std::string* UninterpretedOption::release_string_value() {
+ clear_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = string_value_;
+ string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void UninterpretedOption::set_allocated_string_value(::std::string* string_value) {
+ if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete string_value_;
+ }
+ if (string_value) {
+ set_has_string_value();
+ string_value_ = string_value;
+ } else {
+ clear_has_string_value();
+ string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.string_value)
+}
+
+// optional string aggregate_value = 8;
+inline bool UninterpretedOption::has_aggregate_value() const {
+ return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void UninterpretedOption::set_has_aggregate_value() {
+ _has_bits_[0] |= 0x00000040u;
+}
+inline void UninterpretedOption::clear_has_aggregate_value() {
+ _has_bits_[0] &= ~0x00000040u;
+}
+inline void UninterpretedOption::clear_aggregate_value() {
+ if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ aggregate_value_->clear();
+ }
+ clear_has_aggregate_value();
+}
+inline const ::std::string& UninterpretedOption::aggregate_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.aggregate_value)
+ return *aggregate_value_;
+}
+inline void UninterpretedOption::set_aggregate_value(const ::std::string& value) {
+ set_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ aggregate_value_ = new ::std::string;
+ }
+ aggregate_value_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.aggregate_value)
+}
+inline void UninterpretedOption::set_aggregate_value(const char* value) {
+ set_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ aggregate_value_ = new ::std::string;
+ }
+ aggregate_value_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.aggregate_value)
+}
+inline void UninterpretedOption::set_aggregate_value(const char* value, size_t size) {
+ set_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ aggregate_value_ = new ::std::string;
+ }
+ aggregate_value_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.aggregate_value)
+}
+inline ::std::string* UninterpretedOption::mutable_aggregate_value() {
+ set_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ aggregate_value_ = new ::std::string;
+ }
+ // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.aggregate_value)
+ return aggregate_value_;
+}
+inline ::std::string* UninterpretedOption::release_aggregate_value() {
+ clear_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = aggregate_value_;
+ aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void UninterpretedOption::set_allocated_aggregate_value(::std::string* aggregate_value) {
+ if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete aggregate_value_;
+ }
+ if (aggregate_value) {
+ set_has_aggregate_value();
+ aggregate_value_ = aggregate_value;
+ } else {
+ clear_has_aggregate_value();
+ aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.aggregate_value)
+}
+
+// -------------------------------------------------------------------
+
+// SourceCodeInfo_Location
+
+// repeated int32 path = 1 [packed = true];
+inline int SourceCodeInfo_Location::path_size() const {
+ return path_.size();
+}
+inline void SourceCodeInfo_Location::clear_path() {
+ path_.Clear();
+}
+inline ::google::protobuf::int32 SourceCodeInfo_Location::path(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.path)
+ return path_.Get(index);
+}
+inline void SourceCodeInfo_Location::set_path(int index, ::google::protobuf::int32 value) {
+ path_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.path)
+}
+inline void SourceCodeInfo_Location::add_path(::google::protobuf::int32 value) {
+ path_.Add(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.path)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+SourceCodeInfo_Location::path() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.path)
+ return path_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+SourceCodeInfo_Location::mutable_path() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.path)
+ return &path_;
+}
+
+// repeated int32 span = 2 [packed = true];
+inline int SourceCodeInfo_Location::span_size() const {
+ return span_.size();
+}
+inline void SourceCodeInfo_Location::clear_span() {
+ span_.Clear();
+}
+inline ::google::protobuf::int32 SourceCodeInfo_Location::span(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.span)
+ return span_.Get(index);
+}
+inline void SourceCodeInfo_Location::set_span(int index, ::google::protobuf::int32 value) {
+ span_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.span)
+}
+inline void SourceCodeInfo_Location::add_span(::google::protobuf::int32 value) {
+ span_.Add(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.span)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+SourceCodeInfo_Location::span() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.span)
+ return span_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+SourceCodeInfo_Location::mutable_span() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.span)
+ return &span_;
+}
+
+// optional string leading_comments = 3;
+inline bool SourceCodeInfo_Location::has_leading_comments() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void SourceCodeInfo_Location::set_has_leading_comments() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void SourceCodeInfo_Location::clear_has_leading_comments() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void SourceCodeInfo_Location::clear_leading_comments() {
+ if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ leading_comments_->clear();
+ }
+ clear_has_leading_comments();
+}
+inline const ::std::string& SourceCodeInfo_Location::leading_comments() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_comments)
+ return *leading_comments_;
+}
+inline void SourceCodeInfo_Location::set_leading_comments(const ::std::string& value) {
+ set_has_leading_comments();
+ if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ leading_comments_ = new ::std::string;
+ }
+ leading_comments_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+inline void SourceCodeInfo_Location::set_leading_comments(const char* value) {
+ set_has_leading_comments();
+ if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ leading_comments_ = new ::std::string;
+ }
+ leading_comments_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+inline void SourceCodeInfo_Location::set_leading_comments(const char* value, size_t size) {
+ set_has_leading_comments();
+ if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ leading_comments_ = new ::std::string;
+ }
+ leading_comments_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+inline ::std::string* SourceCodeInfo_Location::mutable_leading_comments() {
+ set_has_leading_comments();
+ if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ leading_comments_ = new ::std::string;
+ }
+ // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_comments)
+ return leading_comments_;
+}
+inline ::std::string* SourceCodeInfo_Location::release_leading_comments() {
+ clear_has_leading_comments();
+ if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = leading_comments_;
+ leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void SourceCodeInfo_Location::set_allocated_leading_comments(::std::string* leading_comments) {
+ if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete leading_comments_;
+ }
+ if (leading_comments) {
+ set_has_leading_comments();
+ leading_comments_ = leading_comments;
+ } else {
+ clear_has_leading_comments();
+ leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+
+// optional string trailing_comments = 4;
+inline bool SourceCodeInfo_Location::has_trailing_comments() const {
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void SourceCodeInfo_Location::set_has_trailing_comments() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void SourceCodeInfo_Location::clear_has_trailing_comments() {
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline void SourceCodeInfo_Location::clear_trailing_comments() {
+ if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ trailing_comments_->clear();
+ }
+ clear_has_trailing_comments();
+}
+inline const ::std::string& SourceCodeInfo_Location::trailing_comments() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+ return *trailing_comments_;
+}
+inline void SourceCodeInfo_Location::set_trailing_comments(const ::std::string& value) {
+ set_has_trailing_comments();
+ if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ trailing_comments_ = new ::std::string;
+ }
+ trailing_comments_->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+inline void SourceCodeInfo_Location::set_trailing_comments(const char* value) {
+ set_has_trailing_comments();
+ if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ trailing_comments_ = new ::std::string;
+ }
+ trailing_comments_->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+inline void SourceCodeInfo_Location::set_trailing_comments(const char* value, size_t size) {
+ set_has_trailing_comments();
+ if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ trailing_comments_ = new ::std::string;
+ }
+ trailing_comments_->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+inline ::std::string* SourceCodeInfo_Location::mutable_trailing_comments() {
+ set_has_trailing_comments();
+ if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ trailing_comments_ = new ::std::string;
+ }
+ // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+ return trailing_comments_;
+}
+inline ::std::string* SourceCodeInfo_Location::release_trailing_comments() {
+ clear_has_trailing_comments();
+ if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ return NULL;
+ } else {
+ ::std::string* temp = trailing_comments_;
+ trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return temp;
+ }
+}
+inline void SourceCodeInfo_Location::set_allocated_trailing_comments(::std::string* trailing_comments) {
+ if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+ delete trailing_comments_;
+ }
+ if (trailing_comments) {
+ set_has_trailing_comments();
+ trailing_comments_ = trailing_comments;
+ } else {
+ clear_has_trailing_comments();
+ trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+
+// -------------------------------------------------------------------
+
+// SourceCodeInfo
+
+// repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+inline int SourceCodeInfo::location_size() const {
+ return location_.size();
+}
+inline void SourceCodeInfo::clear_location() {
+ location_.Clear();
+}
+inline const ::google::protobuf::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.location)
+ return location_.Get(index);
+}
+inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.location)
+ return location_.Mutable(index);
+}
+inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location() {
+ // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.location)
+ return location_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
+SourceCodeInfo::location() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.location)
+ return location_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
+SourceCodeInfo::mutable_location() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.location)
+ return &location_;
+}
// @@protoc_insertion_point(namespace_scope)
@@ -4329,18 +6731,22 @@ inline ::std::string* UninterpretedOption::mutable_string_value() {
namespace google {
namespace protobuf {
+template <> struct is_proto_enum< ::google::protobuf::FieldDescriptorProto_Type> : ::google::protobuf::internal::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Type>() {
return ::google::protobuf::FieldDescriptorProto_Type_descriptor();
}
+template <> struct is_proto_enum< ::google::protobuf::FieldDescriptorProto_Label> : ::google::protobuf::internal::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Label>() {
return ::google::protobuf::FieldDescriptorProto_Label_descriptor();
}
+template <> struct is_proto_enum< ::google::protobuf::FileOptions_OptimizeMode> : ::google::protobuf::internal::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FileOptions_OptimizeMode>() {
return ::google::protobuf::FileOptions_OptimizeMode_descriptor();
}
+template <> struct is_proto_enum< ::google::protobuf::FieldOptions_CType> : ::google::protobuf::internal::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldOptions_CType>() {
return ::google::protobuf::FieldOptions_CType_descriptor();
diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto
index cc04aa8..a753601 100644
--- a/src/google/protobuf/descriptor.proto
+++ b/src/google/protobuf/descriptor.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -59,6 +59,11 @@ message FileDescriptorProto {
// 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;
@@ -67,6 +72,12 @@ message FileDescriptorProto {
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.
@@ -85,6 +96,8 @@ message DescriptorProto {
}
repeated ExtensionRange extension_range = 5;
+ repeated OneofDescriptorProto oneof_decl = 8;
+
optional MessageOptions options = 7;
}
@@ -95,13 +108,13 @@ message FieldDescriptorProto {
// Order is weird for historical reasons.
TYPE_DOUBLE = 1;
TYPE_FLOAT = 2;
- TYPE_INT64 = 3; // Not ZigZag encoded. Negative numbers
- // take 10 bytes. Use TYPE_SINT64 if negative
- // values are likely.
+ // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
+ // negative values are likely.
+ TYPE_INT64 = 3;
TYPE_UINT64 = 4;
- TYPE_INT32 = 5; // Not ZigZag encoded. Negative numbers
- // take 10 bytes. Use TYPE_SINT32 if negative
- // values are likely.
+ // 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;
@@ -132,7 +145,7 @@ message FieldDescriptorProto {
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.
+ // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
optional Type type = 5;
// For message and enum types, this is the name of the type. If the name
@@ -153,9 +166,20 @@ message FieldDescriptorProto {
// TODO(kenton): Base-64 encode?
optional string default_value = 7;
+ // If set, gives the index of a oneof in the containing type's oneof_decl
+ // list. This field is a member of that oneof. Extensions of a oneof should
+ // not set this since the oneof to which they belong will be inferred based
+ // on the extension range containing the extension's field number.
+ optional int32 oneof_index = 9;
+
optional FieldOptions options = 8;
}
+// Describes a oneof.
+message OneofDescriptorProto {
+ optional string name = 1;
+}
+
// Describes an enum type.
message EnumDescriptorProto {
optional string name = 1;
@@ -193,6 +217,7 @@ message MethodDescriptorProto {
optional MethodOptions options = 4;
}
+
// ===================================================================
// Options
@@ -214,10 +239,15 @@ message MethodDescriptorProto {
// 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 kenton@google.com to reserve extension
-// numbers. Simply tell me how many you need and I'll send you back a
-// set of numbers to use -- there's no need to explain how you intend to
-// use them. If this turns out to be popular, a web service will be set up
+// 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:
+// https://developers.google.com/protocol-buffers/docs/proto#options
+// If this turns out to be popular, a web service will be set up
// to automatically assign option numbers.
@@ -245,6 +275,27 @@ message FileOptions {
// 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.
+ // - In the full runtime, this is purely 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.)
+ optional bool java_generate_equals_and_hash = 20 [default=false];
+
+ // 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.
+ optional bool java_string_check_utf8 = 27 [default=false];
+
+
// Generated classes can be optimized for speed or code size.
enum OptimizeMode {
SPEED = 1; // Generate complete code for parsing, serialization,
@@ -254,6 +305,9 @@ message FileOptions {
}
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;
@@ -264,13 +318,19 @@ message FileOptions {
// early versions of proto2.
//
// Generic services are now considered deprecated in favor of using plugins
- // that generate code specific to your particular RPC system. If you are
- // using such a plugin, set these to false. In the future, we may change
- // the default to false, so if you explicitly want generic services, you
- // should explicitly set these to true.
- optional bool cc_generic_services = 16 [default=true];
- optional bool java_generic_services = 17 [default=true];
- optional bool py_generic_services = 18 [default=true];
+ // 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];
+
+ // 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.
+ optional bool deprecated = 23 [default=false];
+
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@@ -305,6 +365,12 @@ message MessageOptions {
// from proto1 easier; new code should avoid fields named "descriptor".
optional bool no_standard_descriptor_accessor = 2 [default=false];
+ // 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.
+ optional bool deprecated = 3 [default=false];
+
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@@ -333,6 +399,37 @@ message FieldOptions {
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
@@ -353,6 +450,11 @@ message FieldOptions {
// 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;
@@ -362,6 +464,16 @@ message FieldOptions {
message EnumOptions {
+ // Set this option to true to allow mapping different tag names to the same
+ // value.
+ optional bool allow_alias = 2;
+
+ // 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.
+ optional bool deprecated = 3 [default=false];
+
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@@ -370,6 +482,12 @@ message EnumOptions {
}
message EnumValueOptions {
+ // 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.
+ optional bool deprecated = 1 [default=false];
+
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@@ -384,6 +502,12 @@ message ServiceOptions {
// we were already using them long before we decided to release Protocol
// Buffers.
+ // 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.
+ optional bool deprecated = 33 [default=false];
+
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@@ -398,6 +522,12 @@ message MethodOptions {
// we were already using them long before we decided to release Protocol
// Buffers.
+ // 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.
+ optional bool deprecated = 33 [default=false];
+
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@@ -405,6 +535,7 @@ message MethodOptions {
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,
@@ -430,4 +561,127 @@ message UninterpretedOption {
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/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc
index 95708d9..d024eab 100644
--- a/src/google/protobuf/descriptor_database.cc
+++ b/src/google/protobuf/descriptor_database.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -39,8 +39,8 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
-#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/stl_util.h>
+#include <google/protobuf/stubs/map_util.h>
namespace google {
namespace protobuf {
@@ -101,7 +101,7 @@ bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddSymbol(
if (iter == by_symbol_.end()) {
// Apparently the map is currently empty. Just insert and be done with it.
- by_symbol_.insert(make_pair(name, value));
+ by_symbol_.insert(typename map<string, Value>::value_type(name, value));
return true;
}
@@ -128,7 +128,7 @@ bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddSymbol(
// Insert the new symbol using the iterator as a hint, the new entry will
// appear immediately before the one the iterator is pointing at.
- by_symbol_.insert(iter, make_pair(name, value));
+ by_symbol_.insert(iter, typename map<string, Value>::value_type(name, value));
return true;
}
@@ -289,6 +289,7 @@ bool SimpleDescriptorDatabase::FindAllExtensionNumbers(
return index_.FindAllExtensionNumbers(extendee_type, output);
}
+
bool SimpleDescriptorDatabase::MaybeCopy(const FileDescriptorProto* file,
FileDescriptorProto* output) {
if (file == NULL) return false;
@@ -537,5 +538,6 @@ bool MergedDescriptorDatabase::FindAllExtensionNumbers(
return success;
}
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/descriptor_database.h b/src/google/protobuf/descriptor_database.h
index f32b1db..934e402 100644
--- a/src/google/protobuf/descriptor_database.h
+++ b/src/google/protobuf/descriptor_database.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -41,6 +41,7 @@
#include <string>
#include <utility>
#include <vector>
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
namespace google {
@@ -95,11 +96,12 @@ class LIBPROTOBUF_EXPORT DescriptorDatabase {
//
// This method has a default implementation that always returns
// false.
- virtual bool FindAllExtensionNumbers(const string& extendee_type,
- vector<int>* output) {
+ virtual bool FindAllExtensionNumbers(const string& /* extendee_type */,
+ vector<int>* /* output */) {
return false;
}
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase);
};
@@ -355,6 +357,7 @@ class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase {
bool FindAllExtensionNumbers(const string& extendee_type,
vector<int>* output);
+
private:
vector<DescriptorDatabase*> sources_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase);
diff --git a/src/google/protobuf/descriptor_database_unittest.cc b/src/google/protobuf/descriptor_database_unittest.cc
index ac72ddc..6642d71 100644
--- a/src/google/protobuf/descriptor_database_unittest.cc
+++ b/src/google/protobuf/descriptor_database_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/descriptor_pb2_test.py b/src/google/protobuf/descriptor_pb2_test.py
new file mode 100644
index 0000000..48a0d48
--- /dev/null
+++ b/src/google/protobuf/descriptor_pb2_test.py
@@ -0,0 +1,54 @@
+#! /usr/bin/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.
+
+# Verify that prebuild and checkedin version of descriptor_pb2.py is up to date.
+
+from google3.pyglib import resources
+import unittest
+
+_DESC = 'google3/net/proto2/proto/descriptor_pb2.'
+_OLD = _DESC + 'py-prebuilt'
+_NEW = _DESC + 'compiled'
+
+
+class PregeneratedFileChanged(unittest.TestCase):
+
+ def testSameText(self):
+ generated = resources.GetResource(_NEW)
+ checkedin = resources.GetResource(_OLD)
+ self.assertMultiLineEqual(
+ generated, checkedin, 'It seems that protoc _pb2 generator changed. '
+ 'Please run google/protobuf/generate_descriptor_proto.sh to '
+ 'regnerate a new version of %s and add it to your CL' % _OLD)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index ec2c815..ac96160 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -36,13 +36,15 @@
#include <vector>
+#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_custom_options.pb.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor_database.h>
#include <google/protobuf/dynamic_message.h>
-#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/text_format.h>
-#include <google/protobuf/unittest.pb.h>
-#include <google/protobuf/unittest_custom_options.pb.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
@@ -644,6 +646,104 @@ TEST_F(DescriptorTest, FieldEnumType) {
// ===================================================================
+// Test simple flat messages and fields.
+class OneofDescriptorTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ // Build descriptors for the following definitions:
+ //
+ // package garply;
+ // message TestOneof {
+ // optional int32 a = 1;
+ // oneof foo {
+ // string b = 2;
+ // TestOneof c = 3;
+ // }
+ // oneof bar {
+ // float d = 4;
+ // }
+ // }
+
+ FileDescriptorProto baz_file;
+ baz_file.set_name("baz.proto");
+ baz_file.set_package("garply");
+
+ DescriptorProto* oneof_message = AddMessage(&baz_file, "TestOneof");
+ oneof_message->add_oneof_decl()->set_name("foo");
+ oneof_message->add_oneof_decl()->set_name("bar");
+
+ AddField(oneof_message, "a", 1,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(oneof_message, "b", 2,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_STRING);
+ oneof_message->mutable_field(1)->set_oneof_index(0);
+ AddField(oneof_message, "c", 3,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_MESSAGE);
+ oneof_message->mutable_field(2)->set_oneof_index(0);
+ oneof_message->mutable_field(2)->set_type_name("TestOneof");
+
+ AddField(oneof_message, "d", 4,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_FLOAT);
+ oneof_message->mutable_field(3)->set_oneof_index(1);
+
+ // Build the descriptors and get the pointers.
+ baz_file_ = pool_.BuildFile(baz_file);
+ ASSERT_TRUE(baz_file_ != NULL);
+
+ ASSERT_EQ(1, baz_file_->message_type_count());
+ oneof_message_ = baz_file_->message_type(0);
+
+ ASSERT_EQ(2, oneof_message_->oneof_decl_count());
+ oneof_ = oneof_message_->oneof_decl(0);
+ oneof2_ = oneof_message_->oneof_decl(1);
+
+ ASSERT_EQ(4, oneof_message_->field_count());
+ a_ = oneof_message_->field(0);
+ b_ = oneof_message_->field(1);
+ c_ = oneof_message_->field(2);
+ d_ = oneof_message_->field(3);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* baz_file_;
+
+ const Descriptor* oneof_message_;
+
+ const OneofDescriptor* oneof_;
+ const OneofDescriptor* oneof2_;
+ const FieldDescriptor* a_;
+ const FieldDescriptor* b_;
+ const FieldDescriptor* c_;
+ const FieldDescriptor* d_;
+ const FieldDescriptor* e_;
+ const FieldDescriptor* f_;
+};
+
+TEST_F(OneofDescriptorTest, Normal) {
+ EXPECT_EQ("foo", oneof_->name());
+ EXPECT_EQ("garply.TestOneof.foo", oneof_->full_name());
+ EXPECT_EQ(0, oneof_->index());
+ ASSERT_EQ(2, oneof_->field_count());
+ EXPECT_EQ(b_, oneof_->field(0));
+ EXPECT_EQ(c_, oneof_->field(1));
+ EXPECT_TRUE(a_->containing_oneof() == NULL);
+ EXPECT_EQ(oneof_, b_->containing_oneof());
+ EXPECT_EQ(oneof_, c_->containing_oneof());
+}
+
+TEST_F(OneofDescriptorTest, FindByName) {
+ EXPECT_EQ(oneof_, oneof_message_->FindOneofByName("foo"));
+ EXPECT_EQ(oneof2_, oneof_message_->FindOneofByName("bar"));
+ EXPECT_TRUE(oneof_message_->FindOneofByName("no_such_oneof") == NULL);
+}
+
+// ===================================================================
+
class StylizedFieldNamesTest : public testing::Test {
protected:
void SetUp() {
@@ -1514,13 +1614,46 @@ TEST_F(ExtensionDescriptorTest, FindAllExtensions) {
EXPECT_EQ(39, extensions[3]->number());
}
+TEST_F(ExtensionDescriptorTest, DuplicateFieldNumber) {
+ DescriptorPool pool;
+ FileDescriptorProto file_proto;
+ // Add "google/protobuf/descriptor.proto".
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+ // Add "foo.proto":
+ // import "google/protobuf/descriptor.proto";
+ // extend google.protobuf.FieldOptions {
+ // optional int32 option1 = 1000;
+ // }
+ file_proto.Clear();
+ file_proto.set_name("foo.proto");
+ file_proto.add_dependency("google/protobuf/descriptor.proto");
+ AddExtension(&file_proto, "google.protobuf.FieldOptions", "option1", 1000,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+ // Add "bar.proto":
+ // import "google/protobuf/descriptor.proto";
+ // extend google.protobuf.FieldOptions {
+ // optional int32 option2 = 1000;
+ // }
+ file_proto.Clear();
+ file_proto.set_name("bar.proto");
+ file_proto.add_dependency("google/protobuf/descriptor.proto");
+ AddExtension(&file_proto, "google.protobuf.FieldOptions", "option2", 1000,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ // Currently we only generate a warning for conflicting extension numbers.
+ // TODO(xiaofeng): Change it to an error.
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+}
+
// ===================================================================
class MiscTest : public testing::Test {
protected:
- // Function which makes a field of the given type just to find out what its
- // cpp_type is.
- FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) {
+ // Function which makes a field descriptor of the given type.
+ const FieldDescriptor* GetFieldDescriptorOfType(FieldDescriptor::Type type) {
FileDescriptorProto file_proto;
file_proto.set_name("foo.proto");
AddEmptyEnum(&file_proto, "DummyEnum");
@@ -1538,19 +1671,99 @@ class MiscTest : public testing::Test {
}
// Build the descriptors and get the pointers.
- DescriptorPool pool;
- const FileDescriptor* file = pool.BuildFile(file_proto);
+ pool_.reset(new DescriptorPool());
+ const FileDescriptor* file = pool_->BuildFile(file_proto);
if (file != NULL &&
file->message_type_count() == 1 &&
file->message_type(0)->field_count() == 1) {
- return file->message_type(0)->field(0)->cpp_type();
+ return file->message_type(0)->field(0);
} else {
- return static_cast<FieldDescriptor::CppType>(0);
+ return NULL;
}
}
+
+ const char* GetTypeNameForFieldType(FieldDescriptor::Type type) {
+ const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+ return field != NULL ? field->type_name() : "";
+ }
+
+ FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) {
+ const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+ return field != NULL ? field->cpp_type() :
+ static_cast<FieldDescriptor::CppType>(0);
+ }
+
+ const char* GetCppTypeNameForFieldType(FieldDescriptor::Type type) {
+ const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+ return field != NULL ? field->cpp_type_name() : "";
+ }
+
+ const Descriptor* GetMessageDescriptorForFieldType(
+ FieldDescriptor::Type type) {
+ const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+ return field != NULL ? field->message_type() : NULL;
+ }
+
+ const EnumDescriptor* GetEnumDescriptorForFieldType(
+ FieldDescriptor::Type type) {
+ const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+ return field != NULL ? field->enum_type() : NULL;
+ }
+
+ scoped_ptr<DescriptorPool> pool_;
};
+TEST_F(MiscTest, TypeNames) {
+ // Test that correct type names are returned.
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_STREQ("double" , GetTypeNameForFieldType(FD::TYPE_DOUBLE ));
+ EXPECT_STREQ("float" , GetTypeNameForFieldType(FD::TYPE_FLOAT ));
+ EXPECT_STREQ("int64" , GetTypeNameForFieldType(FD::TYPE_INT64 ));
+ EXPECT_STREQ("uint64" , GetTypeNameForFieldType(FD::TYPE_UINT64 ));
+ EXPECT_STREQ("int32" , GetTypeNameForFieldType(FD::TYPE_INT32 ));
+ EXPECT_STREQ("fixed64" , GetTypeNameForFieldType(FD::TYPE_FIXED64 ));
+ EXPECT_STREQ("fixed32" , GetTypeNameForFieldType(FD::TYPE_FIXED32 ));
+ EXPECT_STREQ("bool" , GetTypeNameForFieldType(FD::TYPE_BOOL ));
+ EXPECT_STREQ("string" , GetTypeNameForFieldType(FD::TYPE_STRING ));
+ EXPECT_STREQ("group" , GetTypeNameForFieldType(FD::TYPE_GROUP ));
+ EXPECT_STREQ("message" , GetTypeNameForFieldType(FD::TYPE_MESSAGE ));
+ EXPECT_STREQ("bytes" , GetTypeNameForFieldType(FD::TYPE_BYTES ));
+ EXPECT_STREQ("uint32" , GetTypeNameForFieldType(FD::TYPE_UINT32 ));
+ EXPECT_STREQ("enum" , GetTypeNameForFieldType(FD::TYPE_ENUM ));
+ EXPECT_STREQ("sfixed32", GetTypeNameForFieldType(FD::TYPE_SFIXED32));
+ EXPECT_STREQ("sfixed64", GetTypeNameForFieldType(FD::TYPE_SFIXED64));
+ EXPECT_STREQ("sint32" , GetTypeNameForFieldType(FD::TYPE_SINT32 ));
+ EXPECT_STREQ("sint64" , GetTypeNameForFieldType(FD::TYPE_SINT64 ));
+}
+
+TEST_F(MiscTest, StaticTypeNames) {
+ // Test that correct type names are returned.
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_STREQ("double" , FD::TypeName(FD::TYPE_DOUBLE ));
+ EXPECT_STREQ("float" , FD::TypeName(FD::TYPE_FLOAT ));
+ EXPECT_STREQ("int64" , FD::TypeName(FD::TYPE_INT64 ));
+ EXPECT_STREQ("uint64" , FD::TypeName(FD::TYPE_UINT64 ));
+ EXPECT_STREQ("int32" , FD::TypeName(FD::TYPE_INT32 ));
+ EXPECT_STREQ("fixed64" , FD::TypeName(FD::TYPE_FIXED64 ));
+ EXPECT_STREQ("fixed32" , FD::TypeName(FD::TYPE_FIXED32 ));
+ EXPECT_STREQ("bool" , FD::TypeName(FD::TYPE_BOOL ));
+ EXPECT_STREQ("string" , FD::TypeName(FD::TYPE_STRING ));
+ EXPECT_STREQ("group" , FD::TypeName(FD::TYPE_GROUP ));
+ EXPECT_STREQ("message" , FD::TypeName(FD::TYPE_MESSAGE ));
+ EXPECT_STREQ("bytes" , FD::TypeName(FD::TYPE_BYTES ));
+ EXPECT_STREQ("uint32" , FD::TypeName(FD::TYPE_UINT32 ));
+ EXPECT_STREQ("enum" , FD::TypeName(FD::TYPE_ENUM ));
+ EXPECT_STREQ("sfixed32", FD::TypeName(FD::TYPE_SFIXED32));
+ EXPECT_STREQ("sfixed64", FD::TypeName(FD::TYPE_SFIXED64));
+ EXPECT_STREQ("sint32" , FD::TypeName(FD::TYPE_SINT32 ));
+ EXPECT_STREQ("sint64" , FD::TypeName(FD::TYPE_SINT64 ));
+}
+
TEST_F(MiscTest, CppTypes) {
// Test that CPP types are assigned correctly.
@@ -1576,6 +1789,99 @@ TEST_F(MiscTest, CppTypes) {
EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_SINT64 ));
}
+TEST_F(MiscTest, CppTypeNames) {
+ // Test that correct CPP type names are returned.
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_STREQ("double" , GetCppTypeNameForFieldType(FD::TYPE_DOUBLE ));
+ EXPECT_STREQ("float" , GetCppTypeNameForFieldType(FD::TYPE_FLOAT ));
+ EXPECT_STREQ("int64" , GetCppTypeNameForFieldType(FD::TYPE_INT64 ));
+ EXPECT_STREQ("uint64" , GetCppTypeNameForFieldType(FD::TYPE_UINT64 ));
+ EXPECT_STREQ("int32" , GetCppTypeNameForFieldType(FD::TYPE_INT32 ));
+ EXPECT_STREQ("uint64" , GetCppTypeNameForFieldType(FD::TYPE_FIXED64 ));
+ EXPECT_STREQ("uint32" , GetCppTypeNameForFieldType(FD::TYPE_FIXED32 ));
+ EXPECT_STREQ("bool" , GetCppTypeNameForFieldType(FD::TYPE_BOOL ));
+ EXPECT_STREQ("string" , GetCppTypeNameForFieldType(FD::TYPE_STRING ));
+ EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_GROUP ));
+ EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_MESSAGE ));
+ EXPECT_STREQ("string" , GetCppTypeNameForFieldType(FD::TYPE_BYTES ));
+ EXPECT_STREQ("uint32" , GetCppTypeNameForFieldType(FD::TYPE_UINT32 ));
+ EXPECT_STREQ("enum" , GetCppTypeNameForFieldType(FD::TYPE_ENUM ));
+ EXPECT_STREQ("int32" , GetCppTypeNameForFieldType(FD::TYPE_SFIXED32));
+ EXPECT_STREQ("int64" , GetCppTypeNameForFieldType(FD::TYPE_SFIXED64));
+ EXPECT_STREQ("int32" , GetCppTypeNameForFieldType(FD::TYPE_SINT32 ));
+ EXPECT_STREQ("int64" , GetCppTypeNameForFieldType(FD::TYPE_SINT64 ));
+}
+
+TEST_F(MiscTest, StaticCppTypeNames) {
+ // Test that correct CPP type names are returned.
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_STREQ("int32" , FD::CppTypeName(FD::CPPTYPE_INT32 ));
+ EXPECT_STREQ("int64" , FD::CppTypeName(FD::CPPTYPE_INT64 ));
+ EXPECT_STREQ("uint32" , FD::CppTypeName(FD::CPPTYPE_UINT32 ));
+ EXPECT_STREQ("uint64" , FD::CppTypeName(FD::CPPTYPE_UINT64 ));
+ EXPECT_STREQ("double" , FD::CppTypeName(FD::CPPTYPE_DOUBLE ));
+ EXPECT_STREQ("float" , FD::CppTypeName(FD::CPPTYPE_FLOAT ));
+ EXPECT_STREQ("bool" , FD::CppTypeName(FD::CPPTYPE_BOOL ));
+ EXPECT_STREQ("enum" , FD::CppTypeName(FD::CPPTYPE_ENUM ));
+ EXPECT_STREQ("string" , FD::CppTypeName(FD::CPPTYPE_STRING ));
+ EXPECT_STREQ("message", FD::CppTypeName(FD::CPPTYPE_MESSAGE));
+}
+
+TEST_F(MiscTest, MessageType) {
+ // Test that message_type() is NULL for non-aggregate fields
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_DOUBLE ));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_FLOAT ));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_INT64 ));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_UINT64 ));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_INT32 ));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_FIXED64 ));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_FIXED32 ));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_BOOL ));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_STRING ));
+ EXPECT_TRUE(NULL != GetMessageDescriptorForFieldType(FD::TYPE_GROUP ));
+ EXPECT_TRUE(NULL != GetMessageDescriptorForFieldType(FD::TYPE_MESSAGE ));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_BYTES ));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_UINT32 ));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_ENUM ));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED32));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED64));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_SINT32 ));
+ EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_SINT64 ));
+}
+
+TEST_F(MiscTest, EnumType) {
+ // Test that enum_type() is NULL for non-enum fields
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_DOUBLE ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_FLOAT ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_INT64 ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_UINT64 ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_INT32 ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_FIXED64 ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_FIXED32 ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_BOOL ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_STRING ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_GROUP ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_MESSAGE ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_BYTES ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_UINT32 ));
+ EXPECT_TRUE(NULL != GetEnumDescriptorForFieldType(FD::TYPE_ENUM ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED32));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED64));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_SINT32 ));
+ EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_SINT64 ));
+}
+
+
TEST_F(MiscTest, DefaultValues) {
// Test that setting default values works.
FileDescriptorProto file_proto;
@@ -1670,7 +1976,7 @@ TEST_F(MiscTest, DefaultValues) {
message->field(3)->default_value_uint64());
EXPECT_EQ(4.5 , message->field(4)->default_value_float ());
EXPECT_EQ(10e100 , message->field(5)->default_value_double());
- EXPECT_EQ(true , message->field(6)->default_value_bool ());
+ EXPECT_TRUE( message->field(6)->default_value_bool ());
EXPECT_EQ("hello" , message->field(7)->default_value_string());
EXPECT_EQ("\001\002\003" , message->field(8)->default_value_string());
EXPECT_EQ(enum_value_b , message->field(9)->default_value_enum ());
@@ -1693,7 +1999,7 @@ TEST_F(MiscTest, DefaultValues) {
EXPECT_EQ(0 , message->field(14)->default_value_uint64());
EXPECT_EQ(0.0f , message->field(15)->default_value_float ());
EXPECT_EQ(0.0 , message->field(16)->default_value_double());
- EXPECT_EQ(false, message->field(17)->default_value_bool ());
+ EXPECT_FALSE( message->field(17)->default_value_bool ());
EXPECT_EQ("" , message->field(18)->default_value_string());
EXPECT_EQ("" , message->field(19)->default_value_string());
EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum());
@@ -1739,13 +2045,31 @@ TEST_F(MiscTest, FieldOptions) {
}
// ===================================================================
+enum DescriptorPoolMode {
+ NO_DATABASE,
+ FALLBACK_DATABASE
+};
-class AllowUnknownDependenciesTest : public testing::Test {
+class AllowUnknownDependenciesTest
+ : public testing::TestWithParam<DescriptorPoolMode> {
protected:
+ DescriptorPoolMode mode() {
+ return GetParam();
+ }
+
virtual void SetUp() {
FileDescriptorProto foo_proto, bar_proto;
- pool_.AllowUnknownDependencies();
+ switch (mode()) {
+ case NO_DATABASE:
+ pool_.reset(new DescriptorPool);
+ break;
+ case FALLBACK_DATABASE:
+ pool_.reset(new DescriptorPool(&db_));
+ break;
+ }
+
+ pool_->AllowUnknownDependencies();
ASSERT_TRUE(TextFormat::ParseFromString(
"name: 'foo.proto'"
@@ -1776,13 +2100,13 @@ class AllowUnknownDependenciesTest : public testing::Test {
&bar_proto));
// Collect pointers to stuff.
- bar_file_ = pool_.BuildFile(bar_proto);
+ bar_file_ = BuildFile(bar_proto);
ASSERT_TRUE(bar_file_ != NULL);
ASSERT_EQ(1, bar_file_->message_type_count());
bar_type_ = bar_file_->message_type(0);
- foo_file_ = pool_.BuildFile(foo_proto);
+ foo_file_ = BuildFile(foo_proto);
ASSERT_TRUE(foo_file_ != NULL);
ASSERT_EQ(1, foo_file_->message_type_count());
@@ -1794,6 +2118,20 @@ class AllowUnknownDependenciesTest : public testing::Test {
qux_field_ = foo_type_->field(2);
}
+ const FileDescriptor* BuildFile(const FileDescriptorProto& proto) {
+ switch (mode()) {
+ case NO_DATABASE:
+ return pool_->BuildFile(proto);
+ break;
+ case FALLBACK_DATABASE: {
+ EXPECT_TRUE(db_.Add(proto));
+ return pool_->FindFileByName(proto.name());
+ }
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+ }
+
const FileDescriptor* bar_file_;
const Descriptor* bar_type_;
const FileDescriptor* foo_file_;
@@ -1802,46 +2140,50 @@ class AllowUnknownDependenciesTest : public testing::Test {
const FieldDescriptor* baz_field_;
const FieldDescriptor* qux_field_;
- DescriptorPool pool_;
+ SimpleDescriptorDatabase db_; // used if in FALLBACK_DATABASE mode.
+ scoped_ptr<DescriptorPool> pool_;
};
-TEST_F(AllowUnknownDependenciesTest, PlaceholderFile) {
+TEST_P(AllowUnknownDependenciesTest, PlaceholderFile) {
ASSERT_EQ(2, foo_file_->dependency_count());
EXPECT_EQ(bar_file_, foo_file_->dependency(0));
+ EXPECT_FALSE(bar_file_->is_placeholder());
const FileDescriptor* baz_file = foo_file_->dependency(1);
EXPECT_EQ("baz.proto", baz_file->name());
EXPECT_EQ(0, baz_file->message_type_count());
+ EXPECT_TRUE(baz_file->is_placeholder());
// Placeholder files should not be findable.
- EXPECT_EQ(bar_file_, pool_.FindFileByName(bar_file_->name()));
- EXPECT_TRUE(pool_.FindFileByName(baz_file->name()) == NULL);
+ EXPECT_EQ(bar_file_, pool_->FindFileByName(bar_file_->name()));
+ EXPECT_TRUE(pool_->FindFileByName(baz_file->name()) == NULL);
}
-TEST_F(AllowUnknownDependenciesTest, PlaceholderTypes) {
+TEST_P(AllowUnknownDependenciesTest, PlaceholderTypes) {
ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_field_->type());
EXPECT_EQ(bar_type_, bar_field_->message_type());
+ EXPECT_FALSE(bar_type_->is_placeholder());
ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_field_->type());
const Descriptor* baz_type = baz_field_->message_type();
EXPECT_EQ("Baz", baz_type->name());
EXPECT_EQ("Baz", baz_type->full_name());
- EXPECT_EQ("Baz.placeholder.proto", baz_type->file()->name());
EXPECT_EQ(0, baz_type->extension_range_count());
+ EXPECT_TRUE(baz_type->is_placeholder());
ASSERT_EQ(FieldDescriptor::TYPE_ENUM, qux_field_->type());
const EnumDescriptor* qux_type = qux_field_->enum_type();
EXPECT_EQ("Qux", qux_type->name());
EXPECT_EQ("corge.Qux", qux_type->full_name());
- EXPECT_EQ("corge.Qux.placeholder.proto", qux_type->file()->name());
+ EXPECT_TRUE(qux_type->is_placeholder());
// Placeholder types should not be findable.
- EXPECT_EQ(bar_type_, pool_.FindMessageTypeByName(bar_type_->full_name()));
- EXPECT_TRUE(pool_.FindMessageTypeByName(baz_type->full_name()) == NULL);
- EXPECT_TRUE(pool_.FindEnumTypeByName(qux_type->full_name()) == NULL);
+ EXPECT_EQ(bar_type_, pool_->FindMessageTypeByName(bar_type_->full_name()));
+ EXPECT_TRUE(pool_->FindMessageTypeByName(baz_type->full_name()) == NULL);
+ EXPECT_TRUE(pool_->FindEnumTypeByName(qux_type->full_name()) == NULL);
}
-TEST_F(AllowUnknownDependenciesTest, CopyTo) {
+TEST_P(AllowUnknownDependenciesTest, CopyTo) {
// FieldDescriptor::CopyTo() should write non-fully-qualified type names
// for placeholder types which were not originally fully-qualified.
FieldDescriptorProto proto;
@@ -1864,7 +2206,7 @@ TEST_F(AllowUnknownDependenciesTest, CopyTo) {
EXPECT_EQ(FieldDescriptorProto::TYPE_ENUM, proto.type());
}
-TEST_F(AllowUnknownDependenciesTest, CustomOptions) {
+TEST_P(AllowUnknownDependenciesTest, CustomOptions) {
// Qux should still have the uninterpreted option attached.
ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size());
const UninterpretedOption& option =
@@ -1873,7 +2215,7 @@ TEST_F(AllowUnknownDependenciesTest, CustomOptions) {
EXPECT_EQ("grault", option.name(0).name_part());
}
-TEST_F(AllowUnknownDependenciesTest, UnknownExtendee) {
+TEST_P(AllowUnknownDependenciesTest, UnknownExtendee) {
// Test that we can extend an unknown type. This is slightly tricky because
// it means that the placeholder type must have an extension range.
@@ -1884,19 +2226,20 @@ TEST_F(AllowUnknownDependenciesTest, UnknownExtendee) {
"extension { extendee: 'UnknownType' name:'some_extension' number:123"
" label:LABEL_OPTIONAL type:TYPE_INT32 }",
&extension_proto));
- const FileDescriptor* file = pool_.BuildFile(extension_proto);
+ const FileDescriptor* file = BuildFile(extension_proto);
ASSERT_TRUE(file != NULL);
ASSERT_EQ(1, file->extension_count());
const Descriptor* extendee = file->extension(0)->containing_type();
EXPECT_EQ("UnknownType", extendee->name());
+ EXPECT_TRUE(extendee->is_placeholder());
ASSERT_EQ(1, extendee->extension_range_count());
EXPECT_EQ(1, extendee->extension_range(0)->start);
EXPECT_EQ(FieldDescriptor::kMaxNumber + 1, extendee->extension_range(0)->end);
}
-TEST_F(AllowUnknownDependenciesTest, CustomOption) {
+TEST_P(AllowUnknownDependenciesTest, CustomOption) {
// Test that we can use a custom option without having parsed
// descriptor.proto.
@@ -1937,7 +2280,7 @@ TEST_F(AllowUnknownDependenciesTest, CustomOption) {
"}",
&option_proto));
- const FileDescriptor* file = pool_.BuildFile(option_proto);
+ const FileDescriptor* file = BuildFile(option_proto);
ASSERT_TRUE(file != NULL);
// Verify that no extension options were set, but they were left as
@@ -1949,6 +2292,81 @@ TEST_F(AllowUnknownDependenciesTest, CustomOption) {
EXPECT_EQ(2, file->options().uninterpreted_option_size());
}
+TEST_P(AllowUnknownDependenciesTest,
+ UndeclaredDependencyTriggersBuildOfDependency) {
+ // Crazy case: suppose foo.proto refers to a symbol without declaring the
+ // dependency that finds it. In the event that the pool is backed by a
+ // DescriptorDatabase, the pool will attempt to find the symbol in the
+ // database. If successful, it will build the undeclared dependency to verify
+ // that the file does indeed contain the symbol. If that file fails to build,
+ // then its descriptors must be rolled back. However, we still want foo.proto
+ // to build successfully, since we are allowing unknown dependencies.
+
+ FileDescriptorProto undeclared_dep_proto;
+ // We make this file fail to build by giving it two fields with tag 1.
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"invalid_file_as_undeclared_dep.proto\" "
+ "package: \"undeclared\" "
+ "message_type: { "
+ " name: \"Quux\" "
+ " field { "
+ " name:'qux' number:1 label:LABEL_OPTIONAL type: TYPE_INT32 "
+ " }"
+ " field { "
+ " name:'quux' number:1 label:LABEL_OPTIONAL type: TYPE_INT64 "
+ " }"
+ "}",
+ &undeclared_dep_proto));
+ // We can't use the BuildFile() helper because we don't actually want to build
+ // it into the descriptor pool in the fallback database case: it just needs to
+ // be sitting in the database so that it gets built during the building of
+ // test.proto below.
+ switch (mode()) {
+ case NO_DATABASE: {
+ ASSERT_TRUE(pool_->BuildFile(undeclared_dep_proto) == NULL);
+ break;
+ }
+ case FALLBACK_DATABASE: {
+ ASSERT_TRUE(db_.Add(undeclared_dep_proto));
+ }
+ }
+
+ FileDescriptorProto test_proto;
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"test.proto\" "
+ "message_type: { "
+ " name: \"Corge\" "
+ " field { "
+ " name:'quux' number:1 label: LABEL_OPTIONAL "
+ " type_name:'undeclared.Quux' type: TYPE_MESSAGE "
+ " }"
+ "}",
+ &test_proto));
+
+ const FileDescriptor* file = BuildFile(test_proto);
+ ASSERT_TRUE(file != NULL);
+ GOOGLE_LOG(INFO) << file->DebugString();
+
+ EXPECT_EQ(0, file->dependency_count());
+ ASSERT_EQ(1, file->message_type_count());
+ const Descriptor* corge_desc = file->message_type(0);
+ ASSERT_EQ("Corge", corge_desc->name());
+ ASSERT_EQ(1, corge_desc->field_count());
+ EXPECT_FALSE(corge_desc->is_placeholder());
+
+ const FieldDescriptor* quux_field = corge_desc->field(0);
+ ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, quux_field->type());
+ ASSERT_EQ("Quux", quux_field->message_type()->name());
+ ASSERT_EQ("undeclared.Quux", quux_field->message_type()->full_name());
+ EXPECT_TRUE(quux_field->message_type()->is_placeholder());
+ // The place holder type should not be findable.
+ ASSERT_TRUE(pool_->FindMessageTypeByName("undeclared.Quux") == NULL);
+}
+
+INSTANTIATE_TEST_CASE_P(DatabaseSource,
+ AllowUnknownDependenciesTest,
+ testing::Values(NO_DATABASE, FALLBACK_DATABASE));
+
// ===================================================================
TEST(CustomOptions, OptionLocations) {
@@ -2212,6 +2630,230 @@ TEST(CustomOptions, MessageOptionThreeFieldsSet) {
EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo());
}
+TEST(CustomOptions, MessageOptionRepeatedLeafFieldSet) {
+ // This test verifies that repeated fields in custom options can be
+ // given multiple values by repeating the option with a different value.
+ // This test checks repeated leaf values. Each repeated custom value
+ // appears in a different uninterpreted_option, which will be concatenated
+ // when they are merged into the final option value.
+ DescriptorPool pool;
+
+ FileDescriptorProto file_proto;
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+ protobuf_unittest::TestMessageWithCustomOptions::descriptor()
+ ->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+ // The following represents the definition:
+ //
+ // import "google/protobuf/unittest_custom_options.proto"
+ // package protobuf_unittest;
+ // message Foo {
+ // option (complex_opt1).foo4 = 12;
+ // option (complex_opt1).foo4 = 34;
+ // option (complex_opt1).foo4 = 56;
+ // }
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"custom_options_import.proto\" "
+ "package: \"protobuf_unittest\" "
+ "dependency: \"google/protobuf/unittest_custom_options.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ " options { "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt1\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"foo4\" "
+ " is_extension: false "
+ " } "
+ " positive_int_value: 12 "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt1\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"foo4\" "
+ " is_extension: false "
+ " } "
+ " positive_int_value: 34 "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt1\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"foo4\" "
+ " is_extension: false "
+ " } "
+ " positive_int_value: 56 "
+ " } "
+ " } "
+ "}",
+ &file_proto));
+
+ const FileDescriptor* file = pool.BuildFile(file_proto);
+ ASSERT_TRUE(file != NULL);
+ ASSERT_EQ(1, file->message_type_count());
+
+ const MessageOptions& options = file->message_type(0)->options();
+ EXPECT_EQ(3, options.GetExtension(protobuf_unittest::complex_opt1).foo4_size());
+ EXPECT_EQ(12, options.GetExtension(protobuf_unittest::complex_opt1).foo4(0));
+ EXPECT_EQ(34, options.GetExtension(protobuf_unittest::complex_opt1).foo4(1));
+ EXPECT_EQ(56, options.GetExtension(protobuf_unittest::complex_opt1).foo4(2));
+}
+
+TEST(CustomOptions, MessageOptionRepeatedMsgFieldSet) {
+ // This test verifies that repeated fields in custom options can be
+ // given multiple values by repeating the option with a different value.
+ // This test checks repeated message values. Each repeated custom value
+ // appears in a different uninterpreted_option, which will be concatenated
+ // when they are merged into the final option value.
+ DescriptorPool pool;
+
+ FileDescriptorProto file_proto;
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+ protobuf_unittest::TestMessageWithCustomOptions::descriptor()
+ ->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+ // The following represents the definition:
+ //
+ // import "google/protobuf/unittest_custom_options.proto"
+ // package protobuf_unittest;
+ // message Foo {
+ // option (complex_opt2).barney = {waldo: 1};
+ // option (complex_opt2).barney = {waldo: 10};
+ // option (complex_opt2).barney = {waldo: 100};
+ // }
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"custom_options_import.proto\" "
+ "package: \"protobuf_unittest\" "
+ "dependency: \"google/protobuf/unittest_custom_options.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ " options { "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt2\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"barney\" "
+ " is_extension: false "
+ " } "
+ " aggregate_value: \"waldo: 1\" "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt2\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"barney\" "
+ " is_extension: false "
+ " } "
+ " aggregate_value: \"waldo: 10\" "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt2\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"barney\" "
+ " is_extension: false "
+ " } "
+ " aggregate_value: \"waldo: 100\" "
+ " } "
+ " } "
+ "}",
+ &file_proto));
+
+ const FileDescriptor* file = pool.BuildFile(file_proto);
+ ASSERT_TRUE(file != NULL);
+ ASSERT_EQ(1, file->message_type_count());
+
+ const MessageOptions& options = file->message_type(0)->options();
+ EXPECT_EQ(3, options.GetExtension(
+ protobuf_unittest::complex_opt2).barney_size());
+ EXPECT_EQ(1,options.GetExtension(
+ protobuf_unittest::complex_opt2).barney(0).waldo());
+ EXPECT_EQ(10, options.GetExtension(
+ protobuf_unittest::complex_opt2).barney(1).waldo());
+ EXPECT_EQ(100, options.GetExtension(
+ protobuf_unittest::complex_opt2).barney(2).waldo());
+}
+
+// Check that aggregate options were parsed and saved correctly in
+// the appropriate descriptors.
+TEST(CustomOptions, AggregateOptions) {
+ const Descriptor* msg = protobuf_unittest::AggregateMessage::descriptor();
+ const FileDescriptor* file = msg->file();
+ const FieldDescriptor* field = msg->FindFieldByName("fieldname");
+ const EnumDescriptor* enumd = file->FindEnumTypeByName("AggregateEnum");
+ const EnumValueDescriptor* enumv = enumd->FindValueByName("VALUE");
+ const ServiceDescriptor* service = file->FindServiceByName(
+ "AggregateService");
+ const MethodDescriptor* method = service->FindMethodByName("Method");
+
+ // Tests for the different types of data embedded in fileopt
+ const protobuf_unittest::Aggregate& file_options =
+ file->options().GetExtension(protobuf_unittest::fileopt);
+ EXPECT_EQ(100, file_options.i());
+ EXPECT_EQ("FileAnnotation", file_options.s());
+ EXPECT_EQ("NestedFileAnnotation", file_options.sub().s());
+ EXPECT_EQ("FileExtensionAnnotation",
+ file_options.file().GetExtension(protobuf_unittest::fileopt).s());
+ EXPECT_EQ("EmbeddedMessageSetElement",
+ file_options.mset().GetExtension(
+ protobuf_unittest::AggregateMessageSetElement
+ ::message_set_extension).s());
+
+ // Simple tests for all the other types of annotations
+ EXPECT_EQ("MessageAnnotation",
+ msg->options().GetExtension(protobuf_unittest::msgopt).s());
+ EXPECT_EQ("FieldAnnotation",
+ field->options().GetExtension(protobuf_unittest::fieldopt).s());
+ EXPECT_EQ("EnumAnnotation",
+ enumd->options().GetExtension(protobuf_unittest::enumopt).s());
+ EXPECT_EQ("EnumValueAnnotation",
+ enumv->options().GetExtension(protobuf_unittest::enumvalopt).s());
+ EXPECT_EQ("ServiceAnnotation",
+ service->options().GetExtension(protobuf_unittest::serviceopt).s());
+ EXPECT_EQ("MethodAnnotation",
+ method->options().GetExtension(protobuf_unittest::methodopt).s());
+}
+
+TEST(CustomOptions, UnusedImportWarning) {
+ DescriptorPool pool;
+
+ FileDescriptorProto file_proto;
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+ protobuf_unittest::TestMessageWithCustomOptions::descriptor()
+ ->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);
+}
// ===================================================================
@@ -2226,6 +2868,7 @@ class MockErrorCollector : public DescriptorPool::ErrorCollector {
~MockErrorCollector() {}
string text_;
+ string warning_text_;
// implements ErrorCollector ---------------------------------------
void AddError(const string& filename,
@@ -2249,6 +2892,29 @@ class MockErrorCollector : public DescriptorPool::ErrorCollector {
&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);
+ }
};
class ValidationErrorTest : public testing::Test {
@@ -2275,6 +2941,19 @@ class ValidationErrorTest : public testing::Test {
EXPECT_EQ(expected_errors, error_collector.text_);
}
+ // Parse file_text as a FileDescriptorProto in text format and add it
+ // to the DescriptorPool. Expect errors to be produced which match the
+ // given warning text.
+ void BuildFileWithWarnings(const string& file_text,
+ const string& expected_warnings) {
+ FileDescriptorProto file_proto;
+ ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+
+ MockErrorCollector error_collector;
+ EXPECT_TRUE(pool_.BuildFileCollectingErrors(file_proto, &error_collector));
+ EXPECT_EQ(expected_warnings, error_collector.warning_text_);
+ }
+
// Builds some already-parsed file in our test pool.
void BuildFileInTestPool(const FileDescriptor* file) {
FileDescriptorProto file_proto;
@@ -2412,6 +3091,15 @@ TEST_F(ValidationErrorTest, UnknownDependency) {
"bar.proto: bar.proto: OTHER: Import \"foo.proto\" has not been loaded.\n");
}
+TEST_F(ValidationErrorTest, InvalidPublicDependencyIndex) {
+ BuildFile("name: \"foo.proto\"");
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "dependency: \"foo.proto\" "
+ "public_dependency: 1",
+ "bar.proto: bar.proto: OTHER: Invalid public dependency index.\n");
+}
+
TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) {
// Used to crash: If we depend on a non-existent file and then refer to a
// package defined in a file that we didn't import, and that package is
@@ -2519,8 +3207,8 @@ TEST_F(ValidationErrorTest, InvalidDefaults) {
" default_value: \"1\" }"
"}",
- "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value.\n"
- "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value.\n"
+ "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value \"abc\".\n"
+ "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value \"\".\n"
"foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or "
"false.\n"
"foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n"
@@ -2603,6 +3291,38 @@ TEST_F(ValidationErrorTest, NonExtensionWithExtendee) {
"non-extension field.\n");
}
+TEST_F(ValidationErrorTest, FieldOneofIndexTooLarge) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 1 }"
+ " field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 0 }"
+ " oneof_decl { name:\"bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: OTHER: FieldDescriptorProto.oneof_index 1 is out of "
+ "range for type \"Foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, FieldOneofIndexNegative) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: -1 }"
+ " field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 0 }"
+ " oneof_decl { name:\"bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: OTHER: FieldDescriptorProto.oneof_index -1 is out of "
+ "range for type \"Foo\".\n");
+}
+
TEST_F(ValidationErrorTest, FieldNumberConflict) {
BuildFileWithErrors(
"name: \"foo.proto\" "
@@ -2763,6 +3483,28 @@ TEST_F(ValidationErrorTest, NotAnExtensionNumber) {
"number.\n");
}
+TEST_F(ValidationErrorTest, RequiredExtension) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Bar\""
+ " extension_range { start: 1000 end: 10000 }"
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " extension {"
+ " name:\"foo\""
+ " number:1000"
+ " label:LABEL_REQUIRED"
+ " type:TYPE_INT32"
+ " extendee: \"Bar\""
+ " }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: Message extensions cannot have required "
+ "fields.\n");
+}
+
TEST_F(ValidationErrorTest, UndefinedFieldType) {
BuildFileWithErrors(
"name: \"foo.proto\" "
@@ -2774,6 +3516,36 @@ TEST_F(ValidationErrorTest, UndefinedFieldType) {
"foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n");
}
+TEST_F(ValidationErrorTest, UndefinedFieldTypeWithDefault) {
+ // See b/12533582. Previously this failed because the default value was not
+ // accepted by the parser, which assumed an enum type, leading to an unclear
+ // error message. We want this input to yield a validation error instead,
+ // since the unknown type is the primary problem.
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"int\" "
+ " default_value:\"1\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: \"int\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, UndefinedNestedFieldType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " nested_type { name:\"Baz\" }"
+ " field { name:\"foo\" number:1"
+ " label:LABEL_OPTIONAL"
+ " type_name:\"Foo.Baz.Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: \"Foo.Baz.Bar\" is not defined.\n");
+}
+
TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) {
BuildFile(
"name: \"bar.proto\" "
@@ -2790,8 +3562,167 @@ TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) {
"necessary import.\n");
}
+TEST_F(ValidationErrorTest, FieldTypeDefinedInIndirectDependency) {
+ // Test for hidden dependencies.
+ //
+ // // bar.proto
+ // message Bar{}
+ //
+ // // forward.proto
+ // import "bar.proto"
+ //
+ // // foo.proto
+ // import "forward.proto"
+ // message Foo {
+ // optional Bar foo = 1; // Error, needs to import bar.proto explicitly.
+ // }
+ //
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Bar\" }");
+
+ BuildFile(
+ "name: \"forward.proto\""
+ "dependency: \"bar.proto\"");
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"forward.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}",
+ "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
+ "which is not imported by \"foo.proto\". To use it here, please add the "
+ "necessary import.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeDefinedInPublicDependency) {
+ // Test for public dependencies.
+ //
+ // // bar.proto
+ // message Bar{}
+ //
+ // // forward.proto
+ // import public "bar.proto"
+ //
+ // // foo.proto
+ // import "forward.proto"
+ // message Foo {
+ // optional Bar foo = 1; // Correct. "bar.proto" is public imported into
+ // // forward.proto, so when "foo.proto" imports
+ // // "forward.proto", it imports "bar.proto" too.
+ // }
+ //
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Bar\" }");
+
+ BuildFile(
+ "name: \"forward.proto\""
+ "dependency: \"bar.proto\" "
+ "public_dependency: 0");
+
+ BuildFile(
+ "name: \"foo.proto\" "
+ "dependency: \"forward.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeDefinedInTransitivePublicDependency) {
+ // Test for public dependencies.
+ //
+ // // bar.proto
+ // message Bar{}
+ //
+ // // forward.proto
+ // import public "bar.proto"
+ //
+ // // forward2.proto
+ // import public "forward.proto"
+ //
+ // // foo.proto
+ // import "forward2.proto"
+ // message Foo {
+ // optional Bar foo = 1; // Correct, public imports are transitive.
+ // }
+ //
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Bar\" }");
+
+ BuildFile(
+ "name: \"forward.proto\""
+ "dependency: \"bar.proto\" "
+ "public_dependency: 0");
+
+ BuildFile(
+ "name: \"forward2.proto\""
+ "dependency: \"forward.proto\" "
+ "public_dependency: 0");
+
+ BuildFile(
+ "name: \"foo.proto\" "
+ "dependency: \"forward2.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest,
+ FieldTypeDefinedInPrivateDependencyOfPublicDependency) {
+ // Test for public dependencies.
+ //
+ // // bar.proto
+ // message Bar{}
+ //
+ // // forward.proto
+ // import "bar.proto"
+ //
+ // // forward2.proto
+ // import public "forward.proto"
+ //
+ // // foo.proto
+ // import "forward2.proto"
+ // message Foo {
+ // optional Bar foo = 1; // Error, the "bar.proto" is not public imported
+ // // into "forward.proto", so will not be imported
+ // // into either "forward2.proto" or "foo.proto".
+ // }
+ //
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Bar\" }");
+
+ BuildFile(
+ "name: \"forward.proto\""
+ "dependency: \"bar.proto\"");
+
+ BuildFile(
+ "name: \"forward2.proto\""
+ "dependency: \"forward.proto\" "
+ "public_dependency: 0");
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"forward2.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}",
+ "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
+ "which is not imported by \"foo.proto\". To use it here, please add the "
+ "necessary import.\n");
+}
+
+
TEST_F(ValidationErrorTest, SearchMostLocalFirst) {
- // The following should produce an error that Bar.Baz is not defined:
+ // The following should produce an error that Bar.Baz is resolved but
+ // not defined:
// message Bar { message Baz {} }
// message Foo {
// message Bar {
@@ -2817,7 +3748,10 @@ TEST_F(ValidationErrorTest, SearchMostLocalFirst) {
" type_name:\"Bar.Baz\" }"
"}",
- "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is not defined.\n");
+ "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is resolved to \"Foo.Bar.Baz\","
+ " which is not defined. The innermost scope is searched first in name "
+ "resolution. Consider using a leading '.'(i.e., \".Bar.Baz\") to start "
+ "from the outermost scope.\n");
}
TEST_F(ValidationErrorTest, SearchMostLocalFirst2) {
@@ -2959,6 +3893,20 @@ TEST_F(ValidationErrorTest, BadEnumDefaultValue) {
"\"NO_SUCH_VALUE\".\n");
}
+TEST_F(ValidationErrorTest, EnumDefaultValueIsInteger) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
+ " default_value:\"0\" }"
+ "}",
+
+ "foo.proto: Foo.foo: DEFAULT_VALUE: Default value for an enum field must "
+ "be an identifier.\n");
+}
+
TEST_F(ValidationErrorTest, PrimitiveWithTypeName) {
BuildFileWithErrors(
"name: \"foo.proto\" "
@@ -2983,6 +3931,31 @@ TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) {
"type_name.\n");
}
+TEST_F(ValidationErrorTest, OneofWithNoFields) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " oneof_decl { name:\"bar\" }"
+ "}",
+
+ "foo.proto: Foo.bar: NAME: Oneof must have at least one field.\n");
+}
+
+TEST_F(ValidationErrorTest, OneofLabelMismatch) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_REPEATED type:TYPE_INT32 "
+ " oneof_index:0 }"
+ " oneof_decl { name:\"bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: NAME: Fields of oneofs must themselves have label "
+ "LABEL_OPTIONAL.\n");
+}
+
TEST_F(ValidationErrorTest, InputTypeNotDefined) {
BuildFileWithErrors(
"name: \"foo.proto\" "
@@ -2992,7 +3965,8 @@ TEST_F(ValidationErrorTest, InputTypeNotDefined) {
" method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
"}",
- "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n");
+ "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n"
+ );
}
TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
@@ -3005,7 +3979,8 @@ TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
" method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
"}",
- "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n");
+ "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n"
+ );
}
TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
@@ -3017,7 +3992,8 @@ TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
" method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
"}",
- "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n");
+ "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n"
+ );
}
TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
@@ -3030,9 +4006,11 @@ TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
" method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
"}",
- "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n");
+ "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n"
+ );
}
+
TEST_F(ValidationErrorTest, IllegalPackedField) {
BuildFileWithErrors(
"name: \"foo.proto\" "
@@ -3139,20 +4117,85 @@ TEST_F(ValidationErrorTest, InvalidOptionName) {
"reserved name \"uninterpreted_option\".\n");
}
-TEST_F(ValidationErrorTest, RepeatedOption) {
+TEST_F(ValidationErrorTest, RepeatedMessageOption) {
BuildDescriptorMessagesInTestPool();
BuildFileWithErrors(
"name: \"foo.proto\" "
"dependency: \"google/protobuf/descriptor.proto\" "
- "extension { name: \"foo\" number: 7672757 label: LABEL_REPEATED "
- " type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
- "options { uninterpreted_option { name { name_part: \"foo\" "
+ "message_type: { name: \"Bar\" field: { "
+ " name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
+ "} "
+ "extension { name: \"bar\" number: 7672757 label: LABEL_REPEATED "
+ " type: TYPE_MESSAGE type_name: \"Bar\" "
+ " extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"bar\" "
" is_extension: true } "
- " double_value: 1.2 } }",
+ " name { name_part: \"foo\" "
+ " is_extension: false } "
+ " positive_int_value: 1 } }",
- "foo.proto: foo.proto: OPTION_NAME: Option field \"(foo)\" is repeated. "
- "Repeated options are not supported.\n");
+ "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" is a "
+ "repeated message. Repeated message options must be initialized "
+ "using an aggregate value.\n");
+}
+
+TEST_F(ValidationErrorTest, ResolveUndefinedOption) {
+ // The following should produce an eror that baz.bar is resolved but not
+ // defined.
+ // foo.proto:
+ // package baz
+ // import google/protobuf/descriptor.proto
+ // message Bar { optional int32 foo = 1; }
+ // extend FileOptions { optional Bar bar = 7672757; }
+ //
+ // qux.proto:
+ // package qux.baz
+ // option (baz.bar).foo = 1;
+ //
+ // Although "baz.bar" is already defined, the lookup code will try
+ // "qux.baz.bar", since it's the match from the innermost scope, which will
+ // cause a symbol not defined error.
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFile(
+ "name: \"foo.proto\" "
+ "package: \"baz\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "message_type: { name: \"Bar\" field: { "
+ " name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
+ "} "
+ "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_MESSAGE type_name: \"Bar\" "
+ " extendee: \"google.protobuf.FileOptions\" }");
+
+ BuildFileWithErrors(
+ "name: \"qux.proto\" "
+ "package: \"qux.baz\" "
+ "options { uninterpreted_option { name { name_part: \"baz.bar\" "
+ " is_extension: true } "
+ " name { name_part: \"foo\" "
+ " is_extension: false } "
+ " positive_int_value: 1 } }",
+
+ "qux.proto: qux.proto: OPTION_NAME: Option \"(baz.bar)\" is resolved to "
+ "\"(qux.baz.bar)\","
+ " which is not defined. The innermost scope is searched first in name "
+ "resolution. Consider using a leading '.'(i.e., \"(.baz.bar)\") to start "
+ "from the outermost scope.\n");
+}
+
+TEST_F(ValidationErrorTest, UnknownOption) {
+ BuildFileWithErrors(
+ "name: \"qux.proto\" "
+ "package: \"qux.baz\" "
+ "options { uninterpreted_option { name { name_part: \"baaz.bar\" "
+ " is_extension: true } "
+ " name { name_part: \"foo\" "
+ " is_extension: false } "
+ " positive_int_value: 1 } }",
+
+ "qux.proto: qux.proto: OPTION_NAME: Option \"(baaz.bar)\" unknown.\n");
}
TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) {
@@ -3425,25 +4468,69 @@ TEST_F(ValidationErrorTest, StringOptionValueIsNotString) {
"string option \"foo\".\n");
}
-TEST_F(ValidationErrorTest, TryingToSetMessageValuedOption) {
+TEST_F(ValidationErrorTest, DuplicateExtensionFieldNumber) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFile(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"option1\" number: 1000 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }");
+
+ BuildFileWithWarnings(
+ "name: \"bar.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"option2\" number: 1000 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }",
+ "bar.proto: option2: NUMBER: Extension number 1000 has already been used "
+ "in \"google.protobuf.FileOptions\" by extension \"option1\" defined in "
+ "foo.proto.\n");
+}
+
+// Helper function for tests that check for aggregate value parsing
+// errors. The "value" argument is embedded inside the
+// "uninterpreted_option" portion of the result.
+static string EmbedAggregateValue(const char* value) {
+ return strings::Substitute(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "message_type { name: \"Foo\" } "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_MESSAGE type_name: \"Foo\" "
+ " extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " $0 } }",
+ value);
+}
+
+TEST_F(ValidationErrorTest, AggregateValueNotFound) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ EmbedAggregateValue("string_value: \"\""),
+ "foo.proto: foo.proto: OPTION_VALUE: Option \"foo\" is a message. "
+ "To set the entire message, use syntax like "
+ "\"foo = { <proto text format> }\". To set fields within it, use "
+ "syntax like \"foo.foo = value\".\n");
+}
+
+TEST_F(ValidationErrorTest, AggregateValueParseError) {
BuildDescriptorMessagesInTestPool();
BuildFileWithErrors(
- "name: \"foo.proto\" "
- "dependency: \"google/protobuf/descriptor.proto\" "
- "message_type { "
- " name: \"TestMessage\" "
- " field { name:\"baz\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING }"
- "}"
- "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL "
- " type: TYPE_MESSAGE type_name: \"TestMessage\" "
- " extendee: \"google.protobuf.FileOptions\" }"
- "options { uninterpreted_option { name { name_part: \"bar\" "
- " is_extension: true } "
- " identifier_value: \"QUUX\" } }",
+ EmbedAggregateValue("aggregate_value: \"1+2\""),
+ "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
+ "value for \"foo\": Expected identifier.\n");
+}
+
+TEST_F(ValidationErrorTest, AggregateValueUnknownFields) {
+ BuildDescriptorMessagesInTestPool();
- "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" cannot be of "
- "message type.\n");
+ BuildFileWithErrors(
+ EmbedAggregateValue("aggregate_value: \"x:100\""),
+ "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
+ "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n");
}
TEST_F(ValidationErrorTest, NotLiteImportsLite) {
@@ -3483,11 +4570,25 @@ TEST_F(ValidationErrorTest, LiteExtendsNotLite) {
TEST_F(ValidationErrorTest, NoLiteServices) {
BuildFileWithErrors(
"name: \"foo.proto\" "
- "options { optimize_for: LITE_RUNTIME } "
+ "options {"
+ " optimize_for: LITE_RUNTIME"
+ " cc_generic_services: true"
+ " java_generic_services: true"
+ "} "
"service { name: \"Foo\" }",
"foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot "
- "define services.\n");
+ "define services unless you set both options cc_generic_services and "
+ "java_generic_sevices to false.\n");
+
+ BuildFile(
+ "name: \"bar.proto\" "
+ "options {"
+ " optimize_for: LITE_RUNTIME"
+ " cc_generic_services: false"
+ " java_generic_services: false"
+ "} "
+ "service { name: \"Bar\" }");
}
TEST_F(ValidationErrorTest, RollbackAfterError) {
@@ -3514,7 +4615,8 @@ TEST_F(ValidationErrorTest, RollbackAfterError) {
" }"
"}",
- "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n");
+ "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n"
+ );
// Make sure that if we build the same file again with the error fixed,
// it works. If the above rollback was incomplete, then some symbols will
@@ -3563,6 +4665,78 @@ TEST_F(ValidationErrorTest, ErrorsReportedToLogError) {
EXPECT_EQ(" Foo: \"Foo\" is already defined.", errors[1]);
}
+TEST_F(ValidationErrorTest, DisallowEnumAlias) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Bar\""
+ " value { name:\"ENUM_A\" number:0 }"
+ " value { name:\"ENUM_B\" number:0 }"
+ "}",
+ "foo.proto: Bar: NUMBER: "
+ "\"ENUM_B\" uses the same enum value as \"ENUM_A\". "
+ "If this is intended, set 'option allow_alias = true;' to the enum "
+ "definition.\n");
+}
+
+TEST_F(ValidationErrorTest, AllowEnumAlias) {
+ BuildFile(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Bar\""
+ " value { name:\"ENUM_A\" number:0 }"
+ " value { name:\"ENUM_B\" number:0 }"
+ " options { allow_alias: true }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, UnusedImportWarning) {
+
+ pool_.AddUnusedImportTrackFile("bar.proto");
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Bar\" }");
+
+ pool_.AddUnusedImportTrackFile("base.proto");
+ BuildFile(
+ "name: \"base.proto\" "
+ "message_type { name: \"Base\" }");
+
+ pool_.AddUnusedImportTrackFile("baz.proto");
+ BuildFile(
+ "name: \"baz.proto\" "
+ "message_type { name: \"Baz\" }");
+
+ pool_.AddUnusedImportTrackFile("public.proto");
+ BuildFile(
+ "name: \"public.proto\" "
+ "dependency: \"bar.proto\""
+ "public_dependency: 0");
+
+ // // forward.proto
+ // import "base.proto" // No warning: Base message is used.
+ // import "bar.proto" // Will log a warning.
+ // import public "baz.proto" // No warning: Do not track import public.
+ // import "public.proto" // No warning: public.proto has import public.
+ // message Forward {
+ // optional Base base = 1;
+ // }
+ //
+ pool_.AddUnusedImportTrackFile("forward.proto");
+ BuildFile(
+ "name: \"forward.proto\""
+ "dependency: \"base.proto\""
+ "dependency: \"bar.proto\""
+ "dependency: \"baz.proto\""
+ "dependency: \"public.proto\""
+ "public_dependency: 2 "
+ "message_type {"
+ " name: \"Forward\""
+ " field { name:\"base\" number:1 label:LABEL_OPTIONAL type_name:\"Base\" }"
+ "}");
+}
+
+
// ===================================================================
// DescriptorDatabase
@@ -3581,16 +4755,23 @@ class DatabaseBackedPoolTest : public testing::Test {
virtual void SetUp() {
AddToDatabase(&database_,
- "name: \"foo.proto\" "
- "message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } "
- "enum_type { name:\"TestEnum\" value { name:\"DUMMY\" number:0 } } "
- "service { name:\"TestService\" } ");
+ "name: 'foo.proto' "
+ "message_type { name:'Foo' extension_range { start: 1 end: 100 } } "
+ "enum_type { name:'TestEnum' value { name:'DUMMY' number:0 } } "
+ "service { name:'TestService' } ");
AddToDatabase(&database_,
- "name: \"bar.proto\" "
- "dependency: \"foo.proto\" "
- "message_type { name:\"Bar\" } "
- "extension { name:\"foo_ext\" extendee: \".Foo\" number:5 "
+ "name: 'bar.proto' "
+ "dependency: 'foo.proto' "
+ "message_type { name:'Bar' } "
+ "extension { name:'foo_ext' extendee: '.Foo' number:5 "
" label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+ // Baz has an undeclared dependency on Foo.
+ AddToDatabase(&database_,
+ "name: 'baz.proto' "
+ "message_type { "
+ " name:'Baz' "
+ " field { name:'foo' number:1 label:LABEL_OPTIONAL type_name:'Foo' } "
+ "}");
}
// We can't inject a file containing errors into a DescriptorPool, so we
@@ -3829,6 +5010,33 @@ TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) {
error_collector.text_);
}
+TEST_F(DatabaseBackedPoolTest, UndeclaredDependencyOnUnbuiltType) {
+ // Check that we find and report undeclared dependencies on types that exist
+ // in the descriptor database but that have not not been built yet.
+ MockErrorCollector error_collector;
+ DescriptorPool pool(&database_, &error_collector);
+ EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
+ EXPECT_EQ(
+ "baz.proto: Baz.foo: TYPE: \"Foo\" seems to be defined in \"foo.proto\", "
+ "which is not imported by \"baz.proto\". To use it here, please add "
+ "the necessary import.\n",
+ error_collector.text_);
+}
+
+TEST_F(DatabaseBackedPoolTest, RollbackAfterError) {
+ // Make sure that all traces of bad types are removed from the pool. This used
+ // to be b/4529436, due to the fact that a symbol resolution failure could
+ // potentially cause another file to be recursively built, which would trigger
+ // a checkpoint _past_ possibly invalid symbols.
+ // Baz is defined in the database, but the file is invalid because it is
+ // missing a necessary import.
+ DescriptorPool pool(&database_);
+ EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
+ // Make sure that searching again for the file or the type fails.
+ EXPECT_TRUE(pool.FindFileByName("baz.proto") == NULL);
+ EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
+}
+
TEST_F(DatabaseBackedPoolTest, UnittestProto) {
// Try to load all of unittest.proto from a DescriptorDatabase. This should
// thoroughly test all paths through DescriptorBuilder to insure that there
@@ -3851,6 +5059,10 @@ TEST_F(DatabaseBackedPoolTest, UnittestProto) {
EXPECT_EQ(original_file_proto.DebugString(),
file_from_database_proto.DebugString());
+
+ // Also verify that CopyTo() did not omit any information.
+ EXPECT_EQ(original_file->DebugString(),
+ file_from_database->DebugString());
}
TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) {
@@ -3885,6 +5097,16 @@ TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) {
EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == NULL);
EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == NULL);
+
+ EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no.such.field") == NULL);
+ EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no_such_field") == NULL);
+ EXPECT_TRUE(pool.FindMessageTypeByName("Foo.NoSuchMessageType") == NULL);
+ EXPECT_TRUE(pool.FindFieldByName("Foo.no_such_field") == NULL);
+ EXPECT_TRUE(pool.FindExtensionByName("Foo.no_such_extension") == NULL);
+ EXPECT_TRUE(pool.FindEnumTypeByName("Foo.NoSuchEnumType") == NULL);
+ EXPECT_TRUE(pool.FindEnumValueByName("Foo.NO_SUCH_VALUE") == NULL);
+ EXPECT_TRUE(pool.FindMethodByName("TestService.NoSuchMethod") == NULL);
+
EXPECT_EQ(0, call_counter.call_count_);
}
@@ -3909,15 +5131,93 @@ TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) {
EXPECT_EQ("", error_collector.text_);
}
+// DescriptorDatabase that attempts to induce exponentially-bad performance
+// in DescriptorPool. For every positive N, the database contains a file
+// fileN.proto, which defines a message MessageN, which contains fields of
+// type MessageK for all K in [0,N). Message0 is not defined anywhere
+// (file0.proto exists, but is empty), so every other file and message type
+// will fail to build.
+//
+// If the DescriptorPool is not careful to memoize errors, an attempt to
+// build a descriptor for MessageN can require O(2^N) time.
+class ExponentialErrorDatabase : public DescriptorDatabase {
+ public:
+ ExponentialErrorDatabase() {}
+ ~ExponentialErrorDatabase() {}
+
+ // implements DescriptorDatabase ---------------------------------
+ bool FindFileByName(const string& filename,
+ FileDescriptorProto* output) {
+ int file_num = -1;
+ FullMatch(filename, "file", ".proto", &file_num);
+ if (file_num > -1) {
+ return PopulateFile(file_num, output);
+ } else {
+ return false;
+ }
+ }
+ bool FindFileContainingSymbol(const string& symbol_name,
+ FileDescriptorProto* output) {
+ int file_num = -1;
+ FullMatch(symbol_name, "Message", "", &file_num);
+ if (file_num > 0) {
+ return PopulateFile(file_num, output);
+ } else {
+ return false;
+ }
+ }
+ bool FindFileContainingExtension(const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) {
+ return false;
+ }
+
+ private:
+ void FullMatch(const string& name,
+ const string& begin_with,
+ const string& end_with,
+ int* file_num) {
+ int begin_size = begin_with.size();
+ int end_size = end_with.size();
+ if (name.substr(0, begin_size) != begin_with ||
+ name.substr(name.size()- end_size, end_size) != end_with) {
+ return;
+ }
+ safe_strto32(name.substr(begin_size, name.size() - end_size - begin_size),
+ file_num);
+ }
+
+ bool PopulateFile(int file_num, FileDescriptorProto* output) {
+ using strings::Substitute;
+ GOOGLE_CHECK_GE(file_num, 0);
+ output->Clear();
+ output->set_name(Substitute("file$0.proto", file_num));
+ // file0.proto doesn't define Message0
+ if (file_num > 0) {
+ DescriptorProto* message = output->add_message_type();
+ message->set_name(Substitute("Message$0", file_num));
+ for (int i = 0; i < file_num; ++i) {
+ output->add_dependency(Substitute("file$0.proto", i));
+ FieldDescriptorProto* field = message->add_field();
+ field->set_name(Substitute("field$0", i));
+ field->set_number(i);
+ field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
+ field->set_type(FieldDescriptorProto::TYPE_MESSAGE);
+ field->set_type_name(Substitute("Message$0", i));
+ }
+ }
+ return true;
+ }
+};
+
TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) {
- ErrorDescriptorDatabase error_database;
- MockErrorCollector error_collector;
- DescriptorPool pool(&error_database, &error_collector);
+ ExponentialErrorDatabase error_database;
+ DescriptorPool pool(&error_database);
- EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
- error_collector.text_.clear();
- EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
- EXPECT_EQ("", error_collector.text_);
+ GOOGLE_LOG(INFO) << "A timeout in this test probably indicates a real bug.";
+
+ EXPECT_TRUE(pool.FindFileByName("file40.proto") == NULL);
+ EXPECT_TRUE(pool.FindMessageTypeByName("Message40") == NULL);
}
TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
@@ -3950,6 +5250,251 @@ TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
// ===================================================================
+class AbortingErrorCollector : public DescriptorPool::ErrorCollector {
+ public:
+ AbortingErrorCollector() {}
+
+ virtual void AddError(
+ const string &filename,
+ const string &element_name,
+ const Message *message,
+ ErrorLocation location,
+ const string &error_message) {
+ GOOGLE_LOG(FATAL) << "AddError() called unexpectedly: " << filename << ": "
+ << error_message;
+ }
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AbortingErrorCollector);
+};
+
+// A source tree containing only one file.
+class SingletonSourceTree : public compiler::SourceTree {
+ public:
+ SingletonSourceTree(const string& filename, const string& contents)
+ : filename_(filename), contents_(contents) {}
+
+ virtual io::ZeroCopyInputStream* Open(const string& filename) {
+ return filename == filename_ ?
+ new io::ArrayInputStream(contents_.data(), contents_.size()) : NULL;
+ }
+
+ private:
+ const string filename_;
+ const string contents_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SingletonSourceTree);
+};
+
+const char *const kSourceLocationTestInput =
+ "syntax = \"proto2\";\n"
+ "message A {\n"
+ " optional int32 a = 1;\n"
+ " message B {\n"
+ " required double b = 1;\n"
+ " }\n"
+ "}\n"
+ "enum Indecision {\n"
+ " YES = 1;\n"
+ " NO = 2;\n"
+ " MAYBE = 3;\n"
+ "}\n"
+ "service S {\n"
+ " rpc Method(A) returns (A.B);\n"
+ // Put an empty line here to make the source location range match.
+ "\n"
+ "}\n"
+ "message MessageWithExtensions {\n"
+ " extensions 1000 to max;\n"
+ "}\n"
+ "extend MessageWithExtensions {\n"
+ " optional int32 int32_extension = 1001;\n"
+ "}\n"
+ "message C {\n"
+ " extend MessageWithExtensions {\n"
+ " optional C message_extension = 1002;\n"
+ " }\n"
+ "}\n";
+
+class SourceLocationTest : public testing::Test {
+ public:
+ SourceLocationTest()
+ : source_tree_("/test/test.proto", kSourceLocationTestInput),
+ db_(&source_tree_),
+ pool_(&db_, &collector_) {}
+
+ static string PrintSourceLocation(const SourceLocation &loc) {
+ return strings::Substitute("$0:$1-$2:$3",
+ 1 + loc.start_line,
+ 1 + loc.start_column,
+ 1 + loc.end_line,
+ 1 + loc.end_column);
+ }
+
+ private:
+ AbortingErrorCollector collector_;
+ SingletonSourceTree source_tree_;
+ compiler::SourceTreeDescriptorDatabase db_;
+
+ protected:
+ DescriptorPool pool_;
+};
+
+// TODO(adonovan): implement support for option fields and for
+// subparts of declarations.
+
+TEST_F(SourceLocationTest, GetSourceLocation) {
+ SourceLocation loc;
+
+ const FileDescriptor *file_desc =
+ GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+
+ const Descriptor *a_desc = file_desc->FindMessageTypeByName("A");
+ EXPECT_TRUE(a_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("2:1-7:2", PrintSourceLocation(loc));
+
+ const Descriptor *a_b_desc = a_desc->FindNestedTypeByName("B");
+ EXPECT_TRUE(a_b_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("4:3-6:4", PrintSourceLocation(loc));
+
+ const EnumDescriptor *e_desc = file_desc->FindEnumTypeByName("Indecision");
+ EXPECT_TRUE(e_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("8:1-12:2", PrintSourceLocation(loc));
+
+ const EnumValueDescriptor *yes_desc = e_desc->FindValueByName("YES");
+ EXPECT_TRUE(yes_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("9:3-9:13", PrintSourceLocation(loc));
+
+ const ServiceDescriptor *s_desc = file_desc->FindServiceByName("S");
+ EXPECT_TRUE(s_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("13:1-16:2", PrintSourceLocation(loc));
+
+ const MethodDescriptor *m_desc = s_desc->FindMethodByName("Method");
+ EXPECT_TRUE(m_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("14:3-14:31", PrintSourceLocation(loc));
+
+}
+
+TEST_F(SourceLocationTest, ExtensionSourceLocation) {
+ SourceLocation loc;
+
+ const FileDescriptor *file_desc =
+ GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+
+ const FieldDescriptor *int32_extension_desc =
+ file_desc->FindExtensionByName("int32_extension");
+ EXPECT_TRUE(int32_extension_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("21:3-21:41", PrintSourceLocation(loc));
+
+ const Descriptor *c_desc = file_desc->FindMessageTypeByName("C");
+ EXPECT_TRUE(c_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("23:1-27:2", PrintSourceLocation(loc));
+
+ const FieldDescriptor *message_extension_desc =
+ c_desc->FindExtensionByName("message_extension");
+ EXPECT_TRUE(message_extension_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("25:5-25:41", PrintSourceLocation(loc));
+}
+
+// Missing SourceCodeInfo doesn't cause crash:
+TEST_F(SourceLocationTest, GetSourceLocation_MissingSourceCodeInfo) {
+ SourceLocation loc;
+
+ const FileDescriptor *file_desc =
+ GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+
+ FileDescriptorProto proto;
+ file_desc->CopyTo(&proto); // Note, this discards the SourceCodeInfo.
+ EXPECT_FALSE(proto.has_source_code_info());
+
+ DescriptorPool bad1_pool(&pool_);
+ const FileDescriptor* bad1_file_desc =
+ GOOGLE_CHECK_NOTNULL(bad1_pool.BuildFile(proto));
+ const Descriptor *bad1_a_desc = bad1_file_desc->FindMessageTypeByName("A");
+ EXPECT_FALSE(bad1_a_desc->GetSourceLocation(&loc));
+}
+
+// Corrupt SourceCodeInfo doesn't cause crash:
+TEST_F(SourceLocationTest, GetSourceLocation_BogusSourceCodeInfo) {
+ SourceLocation loc;
+
+ const FileDescriptor *file_desc =
+ GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+
+ FileDescriptorProto proto;
+ file_desc->CopyTo(&proto); // Note, this discards the SourceCodeInfo.
+ EXPECT_FALSE(proto.has_source_code_info());
+ SourceCodeInfo_Location *loc_msg =
+ proto.mutable_source_code_info()->add_location();
+ loc_msg->add_path(1);
+ loc_msg->add_path(2);
+ loc_msg->add_path(3);
+ loc_msg->add_span(4);
+ loc_msg->add_span(5);
+ loc_msg->add_span(6);
+
+ DescriptorPool bad2_pool(&pool_);
+ const FileDescriptor* bad2_file_desc =
+ GOOGLE_CHECK_NOTNULL(bad2_pool.BuildFile(proto));
+ const Descriptor *bad2_a_desc = bad2_file_desc->FindMessageTypeByName("A");
+ EXPECT_FALSE(bad2_a_desc->GetSourceLocation(&loc));
+}
+
+// ===================================================================
+
+const char* const kCopySourceCodeInfoToTestInput =
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n";
+
+// Required since source code information is not preserved by
+// FileDescriptorTest.
+class CopySourceCodeInfoToTest : public testing::Test {
+ public:
+ CopySourceCodeInfoToTest()
+ : source_tree_("/test/test.proto", kCopySourceCodeInfoToTestInput),
+ db_(&source_tree_),
+ pool_(&db_, &collector_) {}
+
+ private:
+ AbortingErrorCollector collector_;
+ SingletonSourceTree source_tree_;
+ compiler::SourceTreeDescriptorDatabase db_;
+
+ protected:
+ DescriptorPool pool_;
+};
+
+TEST_F(CopySourceCodeInfoToTest, CopyTo_DoesNotCopySourceCodeInfo) {
+ const FileDescriptor* file_desc =
+ GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+ FileDescriptorProto file_desc_proto;
+ ASSERT_FALSE(file_desc_proto.has_source_code_info());
+
+ file_desc->CopyTo(&file_desc_proto);
+ EXPECT_FALSE(file_desc_proto.has_source_code_info());
+}
+
+TEST_F(CopySourceCodeInfoToTest, CopySourceCodeInfoTo) {
+ const FileDescriptor* file_desc =
+ GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+ FileDescriptorProto file_desc_proto;
+ ASSERT_FALSE(file_desc_proto.has_source_code_info());
+
+ file_desc->CopySourceCodeInfoTo(&file_desc_proto);
+ const SourceCodeInfo& info = file_desc_proto.source_code_info();
+ ASSERT_EQ(3, info.location_size());
+ // Get the Foo message location
+ const SourceCodeInfo_Location& foo_location = info.location(1);
+ ASSERT_EQ(2, foo_location.path_size());
+ EXPECT_EQ(FileDescriptorProto::kMessageTypeFieldNumber, foo_location.path(0));
+ EXPECT_EQ(0, foo_location.path(1)); // Foo is the first message defined
+ ASSERT_EQ(3, foo_location.span_size()); // Foo spans one line
+ EXPECT_EQ(1, foo_location.span(0)); // Foo is declared on line 1
+ EXPECT_EQ(0, foo_location.span(1)); // Foo starts at column 0
+ EXPECT_EQ(14, foo_location.span(2)); // Foo ends on column 14
+}
+
+// ===================================================================
+
} // namespace descriptor_unittest
} // namespace protobuf
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc
index c711a2d..4cca986 100644
--- a/src/google/protobuf/dynamic_message.cc
+++ b/src/google/protobuf/dynamic_message.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -123,7 +123,9 @@ int FieldSpaceUsed(const FieldDescriptor* field) {
case FD::CPPTYPE_FLOAT : return sizeof(float );
case FD::CPPTYPE_BOOL : return sizeof(bool );
case FD::CPPTYPE_ENUM : return sizeof(int );
- case FD::CPPTYPE_MESSAGE: return sizeof(Message*);
+
+ case FD::CPPTYPE_MESSAGE:
+ return sizeof(Message*);
case FD::CPPTYPE_STRING:
switch (field->options().ctype()) {
@@ -139,11 +141,42 @@ int FieldSpaceUsed(const FieldDescriptor* field) {
return 0;
}
+// Compute the byte size of in-memory representation of the oneof fields
+// in default oneof instance.
+int OneofFieldSpaceUsed(const FieldDescriptor* field) {
+ typedef FieldDescriptor FD; // avoid line wrapping
+ switch (field->cpp_type()) {
+ case FD::CPPTYPE_INT32 : return sizeof(int32 );
+ case FD::CPPTYPE_INT64 : return sizeof(int64 );
+ case FD::CPPTYPE_UINT32 : return sizeof(uint32 );
+ case FD::CPPTYPE_UINT64 : return sizeof(uint64 );
+ case FD::CPPTYPE_DOUBLE : return sizeof(double );
+ case FD::CPPTYPE_FLOAT : return sizeof(float );
+ case FD::CPPTYPE_BOOL : return sizeof(bool );
+ case FD::CPPTYPE_ENUM : return sizeof(int );
+
+ case FD::CPPTYPE_MESSAGE:
+ return sizeof(Message*);
+
+ case FD::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default:
+ case FieldOptions::STRING:
+ return sizeof(string*);
+ }
+ break;
+ }
+
+ GOOGLE_LOG(DFATAL) << "Can't get here.";
+ return 0;
+}
+
inline int DivideRoundingUp(int i, int j) {
return (i + (j - 1)) / j;
}
static const int kSafeAlignment = sizeof(uint64);
+static const int kMaxOneofUnionSize = sizeof(uint64);
inline int AlignTo(int offset, int alignment) {
return DivideRoundingUp(offset, alignment) * alignment;
@@ -166,6 +199,7 @@ class DynamicMessage : public Message {
struct TypeInfo {
int size;
int has_bits_offset;
+ int oneof_case_offset;
int unknown_fields_offset;
int extensions_offset;
@@ -178,7 +212,19 @@ class DynamicMessage : public Message {
// important (the prototype must be deleted *before* the offsets).
scoped_array<int> offsets;
scoped_ptr<const GeneratedMessageReflection> reflection;
- scoped_ptr<const DynamicMessage> prototype;
+ // Don't use a scoped_ptr to hold the prototype: the destructor for
+ // DynamicMessage needs to know whether it is the prototype, and does so by
+ // looking back at this field. This would assume details about the
+ // implementation of scoped_ptr.
+ const DynamicMessage* prototype;
+ void* default_oneof_instance;
+
+ TypeInfo() : prototype(NULL), default_oneof_instance(NULL) {}
+
+ ~TypeInfo() {
+ delete prototype;
+ operator delete(default_oneof_instance);
+ }
};
DynamicMessage(const TypeInfo* type_info);
@@ -196,6 +242,7 @@ class DynamicMessage : public Message {
Metadata GetMetadata() const;
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
@@ -233,6 +280,12 @@ DynamicMessage::DynamicMessage(const TypeInfo* type_info)
const Descriptor* descriptor = type_info_->type;
+ // Initialize oneof cases.
+ for (int i = 0 ; i < descriptor->oneof_decl_count(); ++i) {
+ new(OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i))
+ uint32(0);
+ }
+
new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet;
if (type_info_->extensions_offset != -1) {
@@ -242,6 +295,9 @@ DynamicMessage::DynamicMessage(const TypeInfo* type_info)
for (int i = 0; i < descriptor->field_count(); i++) {
const FieldDescriptor* field = descriptor->field(i);
void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
+ if (field->containing_oneof()) {
+ continue;
+ }
switch (field->cpp_type()) {
#define HANDLE_TYPE(CPPTYPE, TYPE) \
case FieldDescriptor::CPPTYPE_##CPPTYPE: \
@@ -315,12 +371,35 @@ 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.
+ // 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
// need to delete them, UNLESS we are the prototype message of this type,
// in which case any embedded messages are other prototypes and shouldn't
// be touched.
for (int i = 0; i < descriptor->field_count(); i++) {
const FieldDescriptor* field = descriptor->field(i);
+ if (field->containing_oneof()) {
+ void* field_ptr = OffsetToPointer(
+ type_info_->oneof_case_offset
+ + sizeof(uint32) * field->containing_oneof()->index());
+ if (*(reinterpret_cast<const uint32*>(field_ptr)) ==
+ field->number()) {
+ field_ptr = OffsetToPointer(type_info_->offsets[
+ descriptor->field_count() + field->containing_oneof()->index()]);
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ switch (field->options().ctype()) {
+ default:
+ case FieldOptions::STRING:
+ delete *reinterpret_cast<string**>(field_ptr);
+ break;
+ }
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ delete *reinterpret_cast<Message**>(field_ptr);
+ }
+ }
+ continue;
+ }
void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
if (field->is_repeated()) {
@@ -368,11 +447,12 @@ DynamicMessage::~DynamicMessage() {
break;
}
}
- } else if ((field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) &&
- !is_prototype()) {
- Message* message = *reinterpret_cast<Message**>(field_ptr);
- if (message != NULL) {
- delete message;
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (!is_prototype()) {
+ Message* message = *reinterpret_cast<Message**>(field_ptr);
+ if (message != NULL) {
+ delete message;
+ }
}
}
}
@@ -389,6 +469,10 @@ void DynamicMessage::CrossLinkPrototypes() {
for (int i = 0; i < descriptor->field_count(); i++) {
const FieldDescriptor* field = descriptor->field(i);
void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
+ if (field->containing_oneof()) {
+ field_ptr = reinterpret_cast<uint8*>(
+ type_info_->default_oneof_instance) + type_info_->offsets[i];
+ }
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
!field->is_repeated()) {
@@ -403,7 +487,7 @@ void DynamicMessage::CrossLinkPrototypes() {
}
Message* DynamicMessage::New() const {
- void* new_base = reinterpret_cast<uint8*>(operator new(type_info_->size));
+ void* new_base = operator new(type_info_->size);
memset(new_base, 0, type_info_->size);
return new(new_base) DynamicMessage(type_info_);
}
@@ -416,7 +500,9 @@ void DynamicMessage::SetCachedSize(int size) const {
// This is theoretically not thread-compatible, but in practice it works
// because if multiple threads write this simultaneously, they will be
// writing the exact same value.
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
cached_byte_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
Metadata DynamicMessage::GetMetadata() const {
@@ -446,6 +532,9 @@ DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool)
DynamicMessageFactory::~DynamicMessageFactory() {
for (PrototypeMap::Map::iterator iter = prototypes_->map_.begin();
iter != prototypes_->map_.end(); ++iter) {
+ DeleteDefaultOneofInstance(iter->second->type,
+ iter->second->offsets.get(),
+ iter->second->default_oneof_instance);
delete iter->second;
}
}
@@ -465,7 +554,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
const DynamicMessage::TypeInfo** target = &prototypes_->map_[type];
if (*target != NULL) {
// Already exists.
- return (*target)->prototype.get();
+ return (*target)->prototype;
}
DynamicMessage::TypeInfo* type_info = new DynamicMessage::TypeInfo;
@@ -484,7 +573,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
// or not that field is set.
// Compute size and offsets.
- int* offsets = new int[type->field_count()];
+ int* offsets = new int[type->field_count() + type->oneof_decl_count()];
type_info->offsets.reset(offsets);
// Decide all field offsets by packing in order.
@@ -500,6 +589,13 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
size += has_bits_array_size * sizeof(uint32);
size = AlignOffset(size);
+ // The oneof_case, if any. It is an array of uint32s.
+ if (type->oneof_decl_count() > 0) {
+ type_info->oneof_case_offset = size;
+ size += type->oneof_decl_count() * sizeof(uint32);
+ size = AlignOffset(size);
+ }
+
// The ExtensionSet, if any.
if (type->extension_range_count() > 0) {
type_info->extensions_offset = size;
@@ -513,10 +609,20 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
// All the fields.
for (int i = 0; i < type->field_count(); i++) {
// Make sure field is aligned to avoid bus errors.
- int field_size = FieldSpaceUsed(type->field(i));
- size = AlignTo(size, min(kSafeAlignment, field_size));
- offsets[i] = size;
- size += field_size;
+ // 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));
+ offsets[i] = size;
+ size += field_size;
+ }
+ }
+
+ // The oneofs.
+ for (int i = 0; i < type->oneof_decl_count(); i++) {
+ size = AlignTo(size, kSafeAlignment);
+ offsets[type->field_count() + i] = size;
+ size += kMaxOneofUnionSize;
}
// Add the UnknownFieldSet to the end.
@@ -533,26 +639,126 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
void* base = operator new(size);
memset(base, 0, size);
DynamicMessage* prototype = new(base) DynamicMessage(type_info);
- type_info->prototype.reset(prototype);
+ type_info->prototype = prototype;
// Construct the reflection object.
- type_info->reflection.reset(
- new GeneratedMessageReflection(
- type_info->type,
- type_info->prototype.get(),
- type_info->offsets.get(),
- type_info->has_bits_offset,
- type_info->unknown_fields_offset,
- type_info->extensions_offset,
- type_info->pool,
- this,
- type_info->size));
-
+ if (type->oneof_decl_count() > 0) {
+ // Compute the size of default oneof instance and offsets of default
+ // oneof fields.
+ int oneof_size = 0;
+ for (int i = 0; i < type->oneof_decl_count(); i++) {
+ 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));
+ offsets[field->index()] = oneof_size;
+ oneof_size += field_size;
+ }
+ }
+ // Construct default oneof instance.
+ type_info->default_oneof_instance = ::operator new(oneof_size);
+ ConstructDefaultOneofInstance(type_info->type,
+ type_info->offsets.get(),
+ type_info->default_oneof_instance);
+ type_info->reflection.reset(
+ new GeneratedMessageReflection(
+ type_info->type,
+ type_info->prototype,
+ type_info->offsets.get(),
+ type_info->has_bits_offset,
+ type_info->unknown_fields_offset,
+ type_info->extensions_offset,
+ type_info->default_oneof_instance,
+ type_info->oneof_case_offset,
+ type_info->pool,
+ this,
+ type_info->size));
+ } else {
+ type_info->reflection.reset(
+ new GeneratedMessageReflection(
+ type_info->type,
+ type_info->prototype,
+ type_info->offsets.get(),
+ type_info->has_bits_offset,
+ type_info->unknown_fields_offset,
+ type_info->extensions_offset,
+ type_info->pool,
+ this,
+ type_info->size));
+ }
// Cross link prototypes.
prototype->CrossLinkPrototypes();
return prototype;
}
+void DynamicMessageFactory::ConstructDefaultOneofInstance(
+ const Descriptor* type,
+ const int offsets[],
+ void* default_oneof_instance) {
+ for (int i = 0; i < type->oneof_decl_count(); i++) {
+ for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
+ const FieldDescriptor* field = type->oneof_decl(i)->field(j);
+ void* field_ptr = reinterpret_cast<uint8*>(
+ default_oneof_instance) + offsets[field->index()];
+ switch (field->cpp_type()) {
+#define HANDLE_TYPE(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ new(field_ptr) TYPE(field->default_value_##TYPE()); \
+ break;
+
+ HANDLE_TYPE(INT32 , int32 );
+ HANDLE_TYPE(INT64 , int64 );
+ HANDLE_TYPE(UINT32, uint32);
+ HANDLE_TYPE(UINT64, uint64);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE(FLOAT , float );
+ HANDLE_TYPE(BOOL , bool );
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::CPPTYPE_ENUM:
+ new(field_ptr) int(field->default_value_enum()->number());
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default:
+ case FieldOptions::STRING:
+ if (field->has_default_value()) {
+ new(field_ptr) const string*(&field->default_value_string());
+ } else {
+ new(field_ptr) string*(
+ const_cast<string*>(&internal::GetEmptyString()));
+ }
+ break;
+ }
+ break;
+
+ case FieldDescriptor::CPPTYPE_MESSAGE: {
+ new(field_ptr) Message*(NULL);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void DynamicMessageFactory::DeleteDefaultOneofInstance(
+ const Descriptor* type,
+ const int offsets[],
+ void* default_oneof_instance) {
+ for (int i = 0; i < type->oneof_decl_count(); i++) {
+ for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
+ const FieldDescriptor* field = type->oneof_decl(i)->field(j);
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ switch (field->options().ctype()) {
+ default:
+ case FieldOptions::STRING:
+ break;
+ }
+ }
+ }
+ }
+}
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/dynamic_message.h b/src/google/protobuf/dynamic_message.h
index 81dd2c6..10ed700 100644
--- a/src/google/protobuf/dynamic_message.h
+++ b/src/google/protobuf/dynamic_message.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -38,6 +38,8 @@
#ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
#define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
+#include <memory>
+
#include <google/protobuf/message.h>
#include <google/protobuf/stubs/common.h>
@@ -68,7 +70,7 @@ class DescriptorPool; // descriptor.h
class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
public:
// Construct a DynamicMessageFactory that will search for extensions in
- // the DescriptorPool in which the exendee is defined.
+ // the DescriptorPool in which the extendee is defined.
DynamicMessageFactory();
// Construct a DynamicMessageFactory that will search for extensions in
@@ -102,7 +104,7 @@ class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
// object. The returned object remains property of the factory and will
// be destroyed when the factory is destroyed. Also, any objects created
// by calling the prototype's New() method share some data with the
- // prototype, so these must be destoyed before the DynamicMessageFactory
+ // prototype, so these must be destroyed before the DynamicMessageFactory
// is destroyed.
//
// The given descriptor must outlive the returned message, and hence must
@@ -127,6 +129,16 @@ class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
friend class DynamicMessage;
const Message* GetPrototypeNoLock(const Descriptor* type);
+ // Construct default oneof instance for reflection usage if oneof
+ // is defined.
+ static void ConstructDefaultOneofInstance(const Descriptor* type,
+ const int offsets[],
+ void* default_oneof_instance);
+ // Delete default oneof instance. Called by ~DynamicMessageFactory.
+ static void DeleteDefaultOneofInstance(const Descriptor* type,
+ const int offsets[],
+ void* default_oneof_instance);
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory);
};
diff --git a/src/google/protobuf/dynamic_message_unittest.cc b/src/google/protobuf/dynamic_message_unittest.cc
index 41b89ab..a1c1661 100644
--- a/src/google/protobuf/dynamic_message_unittest.cc
+++ b/src/google/protobuf/dynamic_message_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -63,6 +63,8 @@ class DynamicMessageTest : public testing::Test {
const Message* extensions_prototype_;
const Descriptor* packed_descriptor_;
const Message* packed_prototype_;
+ const Descriptor* oneof_descriptor_;
+ const Message* oneof_prototype_;
DynamicMessageTest(): factory_(&pool_) {}
@@ -73,11 +75,15 @@ class DynamicMessageTest : public testing::Test {
// unittest_import.proto.
FileDescriptorProto unittest_file;
FileDescriptorProto unittest_import_file;
+ FileDescriptorProto unittest_import_public_file;
unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file);
unittest_import::ImportMessage::descriptor()->file()->CopyTo(
&unittest_import_file);
+ unittest_import::PublicImportMessage::descriptor()->file()->CopyTo(
+ &unittest_import_public_file);
+ ASSERT_TRUE(pool_.BuildFile(unittest_import_public_file) != NULL);
ASSERT_TRUE(pool_.BuildFile(unittest_import_file) != NULL);
ASSERT_TRUE(pool_.BuildFile(unittest_file) != NULL);
@@ -94,6 +100,11 @@ class DynamicMessageTest : public testing::Test {
pool_.FindMessageTypeByName("protobuf_unittest.TestPackedTypes");
ASSERT_TRUE(packed_descriptor_ != NULL);
packed_prototype_ = factory_.GetPrototype(packed_descriptor_);
+
+ oneof_descriptor_ =
+ pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2");
+ ASSERT_TRUE(oneof_descriptor_ != NULL);
+ oneof_prototype_ = factory_.GetPrototype(oneof_descriptor_);
}
};
@@ -143,6 +154,63 @@ TEST_F(DynamicMessageTest, PackedFields) {
reflection_tester.ExpectPackedFieldsSetViaReflection(*message);
}
+TEST_F(DynamicMessageTest, Oneof) {
+ // Check that oneof fields work properly.
+ scoped_ptr<Message> message(oneof_prototype_->New());
+
+ // Check default values.
+ const Descriptor* descriptor = message->GetDescriptor();
+ const Reflection* reflection = message->GetReflection();
+ EXPECT_EQ(0, reflection->GetInt32(
+ *message, descriptor->FindFieldByName("foo_int")));
+ EXPECT_EQ("", reflection->GetString(
+ *message, descriptor->FindFieldByName("foo_string")));
+ EXPECT_EQ("", reflection->GetString(
+ *message, descriptor->FindFieldByName("foo_cord")));
+ EXPECT_EQ("", reflection->GetString(
+ *message, descriptor->FindFieldByName("foo_string_piece")));
+ EXPECT_EQ("", reflection->GetString(
+ *message, descriptor->FindFieldByName("foo_bytes")));
+ EXPECT_EQ(unittest::TestOneof2::FOO, reflection->GetEnum(
+ *message, descriptor->FindFieldByName("foo_enum"))->number());
+ const Descriptor* nested_descriptor;
+ const Message* nested_prototype;
+ nested_descriptor =
+ pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2.NestedMessage");
+ nested_prototype = factory_.GetPrototype(nested_descriptor);
+ EXPECT_EQ(nested_prototype,
+ &reflection->GetMessage(
+ *message, descriptor->FindFieldByName("foo_message")));
+ const Descriptor* foogroup_descriptor;
+ const Message* foogroup_prototype;
+ foogroup_descriptor =
+ pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2.FooGroup");
+ foogroup_prototype = factory_.GetPrototype(foogroup_descriptor);
+ EXPECT_EQ(foogroup_prototype,
+ &reflection->GetMessage(
+ *message, descriptor->FindFieldByName("foogroup")));
+ EXPECT_NE(foogroup_prototype,
+ &reflection->GetMessage(
+ *message, descriptor->FindFieldByName("foo_lazy_message")));
+ EXPECT_EQ(5, reflection->GetInt32(
+ *message, descriptor->FindFieldByName("bar_int")));
+ EXPECT_EQ("STRING", reflection->GetString(
+ *message, descriptor->FindFieldByName("bar_string")));
+ EXPECT_EQ("CORD", reflection->GetString(
+ *message, descriptor->FindFieldByName("bar_cord")));
+ EXPECT_EQ("SPIECE", reflection->GetString(
+ *message, descriptor->FindFieldByName("bar_string_piece")));
+ EXPECT_EQ("BYTES", reflection->GetString(
+ *message, descriptor->FindFieldByName("bar_bytes")));
+ EXPECT_EQ(unittest::TestOneof2::BAR, reflection->GetEnum(
+ *message, descriptor->FindFieldByName("bar_enum"))->number());
+
+ // Check set functions.
+ TestUtil::ReflectionTester reflection_tester(oneof_descriptor_);
+ reflection_tester.SetOneofViaReflection(message.get());
+ reflection_tester.ExpectOneofSetViaReflection(*message);
+}
+
TEST_F(DynamicMessageTest, SpaceUsed) {
// Test that SpaceUsed() works properly
diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc
index 6084885..274554b 100644
--- a/src/google/protobuf/extension_set.cc
+++ b/src/google/protobuf/extension_set.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -38,10 +38,9 @@
#include <google/protobuf/extension_set.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/repeated_field.h>
-#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/map_util.h>
namespace google {
namespace protobuf {
@@ -58,6 +57,22 @@ inline WireFormatLite::CppType cpp_type(FieldType type) {
return WireFormatLite::FieldTypeToCppType(real_type(type));
}
+inline bool is_packable(WireFormatLite::WireType type) {
+ switch (type) {
+ case WireFormatLite::WIRETYPE_VARINT:
+ case WireFormatLite::WIRETYPE_FIXED64:
+ case WireFormatLite::WIRETYPE_FIXED32:
+ return true;
+ case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
+ case WireFormatLite::WIRETYPE_START_GROUP:
+ case WireFormatLite::WIRETYPE_END_GROUP:
+ return false;
+
+ // Do not add a default statement. Let the compiler complain when someone
+ // adds a new wire type.
+ }
+}
+
// Registry stuff.
typedef hash_map<pair<const MessageLite*, int>,
ExtensionInfo> ExtensionRegistry;
@@ -71,7 +86,7 @@ void DeleteRegistry() {
void InitRegistry() {
registry_ = new ExtensionRegistry;
- internal::OnShutdown(&DeleteRegistry);
+ OnShutdown(&DeleteRegistry);
}
// This function is only called at startup, so there is no need for thread-
@@ -180,12 +195,35 @@ bool ExtensionSet::Has(int number) const {
return !iter->second.is_cleared;
}
+int ExtensionSet::NumExtensions() const {
+ int result = 0;
+ for (map<int, Extension>::const_iterator iter = extensions_.begin();
+ iter != extensions_.end(); ++iter) {
+ if (!iter->second.is_cleared) {
+ ++result;
+ }
+ }
+ return result;
+}
+
int ExtensionSet::ExtensionSize(int number) const {
map<int, Extension>::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);
+ if (iter == extensions_.end()) {
+ GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
+ return 0;
+ }
+ if (iter->second.is_cleared) {
+ GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
+ }
+ return iter->second.type;
+}
+
void ExtensionSet::ClearExtension(int number) {
map<int, Extension>::iterator iter = extensions_.find(number);
if (iter == extensions_.end()) return;
@@ -281,6 +319,80 @@ PRIMITIVE_ACCESSORS( BOOL, bool, Bool)
#undef PRIMITIVE_ACCESSORS
+const void* ExtensionSet::GetRawRepeatedField(int number,
+ const void* default_value) const {
+ map<int, Extension>::const_iterator iter = extensions_.find(number);
+ if (iter == extensions_.end()) {
+ return default_value;
+ }
+ // We assume that all the RepeatedField<>* pointers have the same
+ // size and alignment within the anonymous union in Extension.
+ return iter->second.repeated_int32_value;
+}
+
+void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type,
+ bool packed,
+ const FieldDescriptor* desc) {
+ Extension* extension;
+
+ // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this
+ // extension.
+ if (MaybeNewExtension(number, desc, &extension)) {
+ extension->is_repeated = true;
+ extension->type = field_type;
+ extension->is_packed = packed;
+
+ switch (WireFormatLite::FieldTypeToCppType(
+ static_cast<WireFormatLite::FieldType>(field_type))) {
+ case WireFormatLite::CPPTYPE_INT32:
+ extension->repeated_int32_value = new RepeatedField<int32>();
+ break;
+ case WireFormatLite::CPPTYPE_INT64:
+ extension->repeated_int64_value = new RepeatedField<int64>();
+ break;
+ case WireFormatLite::CPPTYPE_UINT32:
+ extension->repeated_uint32_value = new RepeatedField<uint32>();
+ break;
+ case WireFormatLite::CPPTYPE_UINT64:
+ extension->repeated_uint64_value = new RepeatedField<uint64>();
+ break;
+ case WireFormatLite::CPPTYPE_DOUBLE:
+ extension->repeated_double_value = new RepeatedField<double>();
+ break;
+ case WireFormatLite::CPPTYPE_FLOAT:
+ extension->repeated_float_value = new RepeatedField<float>();
+ break;
+ case WireFormatLite::CPPTYPE_BOOL:
+ extension->repeated_bool_value = new RepeatedField<bool>();
+ break;
+ case WireFormatLite::CPPTYPE_ENUM:
+ extension->repeated_enum_value = new RepeatedField<int>();
+ break;
+ case WireFormatLite::CPPTYPE_STRING:
+ extension->repeated_string_value = new RepeatedPtrField< ::std::string>();
+ break;
+ case WireFormatLite::CPPTYPE_MESSAGE:
+ extension->repeated_message_value = new RepeatedPtrField<MessageLite>();
+ break;
+ }
+ }
+
+ // We assume that all the RepeatedField<>* pointers have the same
+ // size and alignment within the anonymous union in Extension.
+ return extension->repeated_int32_value;
+}
+
+// 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);
+ 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.
+ return iter->second.repeated_int32_value;
+}
+
+
// -------------------------------------------------------------------
// Enums
@@ -410,7 +522,11 @@ const MessageLite& ExtensionSet::GetMessage(
return default_value;
} else {
GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
- return *iter->second.message_value;
+ if (iter->second.is_lazy) {
+ return iter->second.lazymessage_value->GetMessage(default_value);
+ } else {
+ return *iter->second.message_value;
+ }
}
}
@@ -427,12 +543,19 @@ MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
extension->type = type;
GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
extension->is_repeated = false;
+ extension->is_lazy = false;
extension->message_value = prototype.New();
+ extension->is_cleared = false;
+ return extension->message_value;
} else {
GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
+ extension->is_cleared = false;
+ if (extension->is_lazy) {
+ return extension->lazymessage_value->MutableMessage(prototype);
+ } else {
+ return extension->message_value;
+ }
}
- extension->is_cleared = false;
- return extension->message_value;
}
// Defined in extension_set_heavy.cc.
@@ -440,6 +563,56 @@ MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
// const Descriptor* message_type,
// MessageFactory* factory)
+void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
+ const FieldDescriptor* descriptor,
+ MessageLite* message) {
+ if (message == NULL) {
+ ClearExtension(number);
+ return;
+ }
+ Extension* extension;
+ if (MaybeNewExtension(number, descriptor, &extension)) {
+ extension->type = type;
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
+ extension->is_repeated = false;
+ extension->is_lazy = false;
+ extension->message_value = message;
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
+ if (extension->is_lazy) {
+ extension->lazymessage_value->SetAllocatedMessage(message);
+ } else {
+ delete extension->message_value;
+ extension->message_value = message;
+ }
+ }
+ extension->is_cleared = false;
+}
+
+MessageLite* ExtensionSet::ReleaseMessage(int number,
+ const MessageLite& prototype) {
+ map<int, Extension>::iterator iter = extensions_.find(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->ReleaseMessage(prototype);
+ delete iter->second.lazymessage_value;
+ } else {
+ ret = iter->second.message_value;
+ }
+ extensions_.erase(number);
+ return ret;
+ }
+}
+
+// Defined in extension_set_heavy.cc.
+// MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
+// MessageFactory* factory);
+
const MessageLite& ExtensionSet::GetRepeatedMessage(
int number, int index) const {
map<int, Extension>::const_iterator iter = extensions_.find(number);
@@ -472,7 +645,7 @@ MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
// RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
// allocate an abstract object, so we have to be tricky.
MessageLite* result = extension->repeated_message_value
- ->AddFromCleared<internal::GenericTypeHandler<MessageLite> >();
+ ->AddFromCleared<GenericTypeHandler<MessageLite> >();
if (result == NULL) {
result = prototype.New();
extension->repeated_message_value->AddAllocated(result);
@@ -528,6 +701,16 @@ void ExtensionSet::RemoveLast(int number) {
}
}
+MessageLite* ExtensionSet::ReleaseLast(int number) {
+ map<int, Extension>::iterator iter = extensions_.find(number);
+ GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+
+ Extension* extension = &iter->second;
+ GOOGLE_DCHECK(extension->is_repeated);
+ GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE);
+ return extension->repeated_message_value->ReleaseLast();
+}
+
void ExtensionSet::SwapElements(int number, int index1, int index2) {
map<int, Extension>::iterator iter = extensions_.find(number);
GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
@@ -590,9 +773,11 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) {
if (is_new) {
// Extension did not already exist in set.
extension->type = other_extension.type;
+ extension->is_packed = other_extension.is_packed;
extension->is_repeated = true;
} else {
GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
+ GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
GOOGLE_DCHECK(extension->is_repeated);
}
@@ -663,12 +848,55 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) {
*other_extension.string_value,
other_extension.descriptor);
break;
- case WireFormatLite::CPPTYPE_MESSAGE:
- MutableMessage(iter->first, other_extension.type,
- *other_extension.message_value,
- other_extension.descriptor)
- ->CheckTypeAndMergeFrom(*other_extension.message_value);
+ case WireFormatLite::CPPTYPE_MESSAGE: {
+ Extension* extension;
+ bool is_new = MaybeNewExtension(iter->first,
+ other_extension.descriptor,
+ &extension);
+ if (is_new) {
+ extension->type = other_extension.type;
+ extension->is_packed = other_extension.is_packed;
+ extension->is_repeated = false;
+ if (other_extension.is_lazy) {
+ extension->is_lazy = true;
+ extension->lazymessage_value =
+ other_extension.lazymessage_value->New();
+ extension->lazymessage_value->MergeFrom(
+ *other_extension.lazymessage_value);
+ } else {
+ extension->is_lazy = false;
+ extension->message_value =
+ other_extension.message_value->New();
+ extension->message_value->CheckTypeAndMergeFrom(
+ *other_extension.message_value);
+ }
+ } else {
+ GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
+ GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed);
+ GOOGLE_DCHECK(!extension->is_repeated);
+ if (other_extension.is_lazy) {
+ if (extension->is_lazy) {
+ extension->lazymessage_value->MergeFrom(
+ *other_extension.lazymessage_value);
+ } else {
+ extension->message_value->CheckTypeAndMergeFrom(
+ other_extension.lazymessage_value->GetMessage(
+ *extension->message_value));
+ }
+ } else {
+ if (extension->is_lazy) {
+ extension->lazymessage_value->MutableMessage(
+ *other_extension.message_value)->CheckTypeAndMergeFrom(
+ *other_extension.message_value);
+ } else {
+ extension->message_value->CheckTypeAndMergeFrom(
+ *other_extension.message_value);
+ }
+ }
+ }
+ extension->is_cleared = false;
break;
+ }
}
}
}
@@ -679,6 +907,36 @@ void ExtensionSet::Swap(ExtensionSet* x) {
extensions_.swap(x->extensions_);
}
+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);
+
+ if (this_iter == extensions_.end() &&
+ other_iter == other->extensions_.end()) {
+ return;
+ }
+
+ if (this_iter != extensions_.end() &&
+ other_iter != other->extensions_.end()) {
+ std::swap(this_iter->second, other_iter->second);
+ return;
+ }
+
+ if (this_iter == extensions_.end()) {
+ extensions_.insert(make_pair(number, other_iter->second));
+ other->extensions_.erase(number);
+ return;
+ }
+
+ if (other_iter == other->extensions_.end()) {
+ other->extensions_.insert(make_pair(number, this_iter->second));
+ extensions_.erase(number);
+ return;
+ }
+}
+
bool ExtensionSet::IsInitialized() const {
// Extensions are never required. However, we need to check that all
// embedded messages are initialized.
@@ -694,7 +952,11 @@ bool ExtensionSet::IsInitialized() const {
}
} else {
if (!extension.is_cleared) {
- if (!extension.message_value->IsInitialized()) return false;
+ if (extension.is_lazy) {
+ if (!extension.lazymessage_value->IsInitialized()) return false;
+ } else {
+ if (!extension.message_value->IsInitialized()) return false;
+ }
}
}
}
@@ -703,27 +965,60 @@ bool ExtensionSet::IsInitialized() const {
return true;
}
+bool ExtensionSet::FindExtensionInfoFromTag(
+ uint32 tag, ExtensionFinder* extension_finder, int* field_number,
+ ExtensionInfo* extension, bool* was_packed_on_wire) {
+ *field_number = WireFormatLite::GetTagFieldNumber(tag);
+ WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
+ return FindExtensionInfoFromFieldNumber(wire_type, *field_number,
+ extension_finder, extension,
+ was_packed_on_wire);
+}
+
+bool ExtensionSet::FindExtensionInfoFromFieldNumber(
+ int wire_type, int field_number, ExtensionFinder* extension_finder,
+ ExtensionInfo* extension, bool* was_packed_on_wire) {
+ if (!extension_finder->Find(field_number, extension)) {
+ return false;
+ }
+
+ WireFormatLite::WireType expected_wire_type =
+ WireFormatLite::WireTypeForFieldType(real_type(extension->type));
+
+ // Check if this is a packed field.
+ *was_packed_on_wire = false;
+ if (extension->is_repeated &&
+ wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
+ is_packable(expected_wire_type)) {
+ *was_packed_on_wire = true;
+ return true;
+ }
+ // Otherwise the wire type must match.
+ return expected_wire_type == wire_type;
+}
+
bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
ExtensionFinder* extension_finder,
FieldSkipper* field_skipper) {
- int number = WireFormatLite::GetTagFieldNumber(tag);
- WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
-
+ int number;
+ bool was_packed_on_wire;
ExtensionInfo extension;
- bool is_unknown;
- if (!extension_finder->Find(number, &extension)) {
- is_unknown = true;
- } else if (extension.is_packed) {
- is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+ if (!FindExtensionInfoFromTag(
+ tag, extension_finder, &number, &extension, &was_packed_on_wire)) {
+ return field_skipper->SkipField(input, tag);
} else {
- WireFormatLite::WireType expected_wire_type =
- WireFormatLite::WireTypeForFieldType(real_type(extension.type));
- is_unknown = (wire_type != expected_wire_type);
+ return ParseFieldWithExtensionInfo(
+ number, was_packed_on_wire, extension, input, field_skipper);
}
+}
- if (is_unknown) {
- field_skipper->SkipField(input, tag);
- } else if (extension.is_packed) {
+bool ExtensionSet::ParseFieldWithExtensionInfo(
+ int number, bool was_packed_on_wire, const ExtensionInfo& extension,
+ io::CodedInputStream* input,
+ FieldSkipper* field_skipper) {
+ // Explicitly not read extension.is_packed, instead check whether the field
+ // was encoded in packed form on the wire.
+ if (was_packed_on_wire) {
uint32 size;
if (!input->ReadVarint32(&size)) return false;
io::CodedInputStream::Limit limit = input->PushLimit(size);
@@ -737,7 +1032,8 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
input, &value)) return false; \
Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
- true, value, extension.descriptor); \
+ extension.is_packed, value, \
+ extension.descriptor); \
} \
break
@@ -763,8 +1059,8 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
input, &value)) return false;
if (extension.enum_validity_check.func(
extension.enum_validity_check.arg, value)) {
- AddEnum(number, WireFormatLite::TYPE_ENUM, true, value,
- extension.descriptor);
+ AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed,
+ value, extension.descriptor);
}
}
break;
@@ -786,9 +1082,10 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
if (!WireFormatLite::ReadPrimitive< \
CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
input, &value)) return false; \
- if (extension.is_repeated) { \
+ if (extension.is_repeated) { \
Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
- false, value, extension.descriptor); \
+ extension.is_packed, value, \
+ extension.descriptor); \
} else { \
Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
extension.descriptor); \
@@ -820,7 +1117,7 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
// Invalid value. Treat as unknown.
field_skipper->SkipUnknownEnum(number, value);
} else if (extension.is_repeated) {
- AddEnum(number, WireFormatLite::TYPE_ENUM, false, value,
+ AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
extension.descriptor);
} else {
SetEnum(number, WireFormatLite::TYPE_ENUM, value,
@@ -840,8 +1137,8 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
case WireFormatLite::TYPE_BYTES: {
string* value = extension.is_repeated ?
- AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
- MutableString(number, WireFormatLite::TYPE_STRING,
+ AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) :
+ MutableString(number, WireFormatLite::TYPE_BYTES,
extension.descriptor);
if (!WireFormatLite::ReadBytes(input, value)) return false;
break;
@@ -879,125 +1176,24 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
return ParseField(tag, input, &finder, &skipper);
}
+bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
+ const MessageLite* containing_type,
+ io::CodedOutputStream* unknown_fields) {
+ CodedOutputStreamFieldSkipper skipper(unknown_fields);
+ GeneratedExtensionFinder finder(containing_type);
+ return ParseField(tag, input, &finder, &skipper);
+}
+
// Defined in extension_set_heavy.cc.
// bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
// const MessageLite* containing_type,
// UnknownFieldSet* unknown_fields)
-bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
- ExtensionFinder* extension_finder,
- FieldSkipper* field_skipper) {
- while (true) {
- uint32 tag = input->ReadTag();
- switch (tag) {
- case 0:
- return true;
- case WireFormatLite::kMessageSetItemStartTag:
- if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
- return false;
- }
- break;
- default:
- if (!ParseField(tag, input, extension_finder, field_skipper)) {
- return false;
- }
- break;
- }
- }
-}
-
-bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
- const MessageLite* containing_type) {
- FieldSkipper skipper;
- GeneratedExtensionFinder finder(containing_type);
- return ParseMessageSet(input, &finder, &skipper);
-}
-
// Defined in extension_set_heavy.cc.
// bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
// const MessageLite* containing_type,
// UnknownFieldSet* unknown_fields);
-bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
- ExtensionFinder* extension_finder,
- FieldSkipper* field_skipper) {
- // TODO(kenton): It would be nice to share code between this and
- // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
- // differences would be hard to factor out.
-
- // This method parses a group which should contain two fields:
- // required int32 type_id = 2;
- // required data message = 3;
-
- // Once we see a type_id, we'll construct a fake tag for this extension
- // which is the tag it would have had under the proto2 extensions wire
- // format.
- uint32 fake_tag = 0;
-
- // If we see message data before the type_id, we'll append it to this so
- // we can parse it later. This will probably never happen in practice,
- // as no MessageSet encoder I know of writes the message before the type ID.
- // But, it's technically valid so we should allow it.
- // TODO(kenton): Use a Cord instead? Do I care?
- string message_data;
-
- while (true) {
- uint32 tag = input->ReadTag();
- if (tag == 0) return false;
-
- switch (tag) {
- case WireFormatLite::kMessageSetTypeIdTag: {
- uint32 type_id;
- if (!input->ReadVarint32(&type_id)) return false;
- fake_tag = WireFormatLite::MakeTag(type_id,
- WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
-
- if (!message_data.empty()) {
- // We saw some message data before the type_id. Have to parse it
- // now.
- io::CodedInputStream sub_input(
- reinterpret_cast<const uint8*>(message_data.data()),
- message_data.size());
- if (!ParseField(fake_tag, &sub_input,
- extension_finder, field_skipper)) {
- return false;
- }
- message_data.clear();
- }
-
- break;
- }
-
- case WireFormatLite::kMessageSetMessageTag: {
- if (fake_tag == 0) {
- // We haven't seen a type_id yet. Append this data to message_data.
- string temp;
- uint32 length;
- if (!input->ReadVarint32(&length)) return false;
- if (!input->ReadString(&temp, length)) return false;
- message_data.append(temp);
- } else {
- // Already saw type_id, so we can parse this directly.
- if (!ParseField(fake_tag, input,
- extension_finder, field_skipper)) {
- return false;
- }
- }
-
- break;
- }
-
- case WireFormatLite::kMessageSetItemEndTag: {
- return true;
- }
-
- default: {
- if (!field_skipper->SkipField(input, tag)) return false;
- }
- }
- }
-}
-
void ExtensionSet::SerializeWithCachedSizes(
int start_field_number, int end_field_number,
io::CodedOutputStream* output) const {
@@ -1009,14 +1205,6 @@ void ExtensionSet::SerializeWithCachedSizes(
}
}
-void ExtensionSet::SerializeMessageSetWithCachedSizes(
- io::CodedOutputStream* output) const {
- map<int, Extension>::const_iterator iter;
- for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
- iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
- }
-}
-
int ExtensionSet::ByteSize() const {
int total_size = 0;
@@ -1028,17 +1216,6 @@ int ExtensionSet::ByteSize() const {
return total_size;
}
-int ExtensionSet::MessageSetByteSize() const {
- int total_size = 0;
-
- for (map<int, Extension>::const_iterator iter = extensions_.begin();
- iter != extensions_.end(); ++iter) {
- total_size += iter->second.MessageSetItemByteSize(iter->first);
- }
-
- return total_size;
-}
-
// Defined in extension_set_heavy.cc.
// int ExtensionSet::SpaceUsedExcludingSelf() const
@@ -1082,7 +1259,11 @@ void ExtensionSet::Extension::Clear() {
string_value->clear();
break;
case WireFormatLite::CPPTYPE_MESSAGE:
- message_value->Clear();
+ if (is_lazy) {
+ lazymessage_value->Clear();
+ } else {
+ message_value->Clear();
+ }
break;
default:
// No need to do anything. Get*() will return the default value
@@ -1194,40 +1375,18 @@ void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
HANDLE_TYPE( BYTES, Bytes, *string_value);
HANDLE_TYPE( ENUM, Enum, enum_value);
HANDLE_TYPE( GROUP, Group, *message_value);
- HANDLE_TYPE( MESSAGE, Message, *message_value);
#undef HANDLE_TYPE
+ case WireFormatLite::TYPE_MESSAGE:
+ if (is_lazy) {
+ lazymessage_value->WriteMessage(number, output);
+ } else {
+ WireFormatLite::WriteMessage(number, *message_value, output);
+ }
+ break;
}
}
}
-void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
- int number,
- io::CodedOutputStream* output) const {
- if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
- // Not a valid MessageSet extension, but serialize it the normal way.
- SerializeFieldWithCachedSizes(number, output);
- return;
- }
-
- if (is_cleared) return;
-
- // Start group.
- output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
-
- // Write type ID.
- WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
- number,
- output);
- // Write message.
- WireFormatLite::WriteMessageMaybeToArray(
- WireFormatLite::kMessageSetMessageNumber,
- *message_value,
- output);
-
- // End group.
- output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
-}
-
int ExtensionSet::Extension::ByteSize(int number) const {
int result = 0;
@@ -1341,8 +1500,16 @@ int ExtensionSet::Extension::ByteSize(int number) const {
HANDLE_TYPE( BYTES, Bytes, *string_value);
HANDLE_TYPE( ENUM, Enum, enum_value);
HANDLE_TYPE( GROUP, Group, *message_value);
- HANDLE_TYPE( MESSAGE, Message, *message_value);
#undef HANDLE_TYPE
+ case WireFormatLite::TYPE_MESSAGE: {
+ if (is_lazy) {
+ int size = lazymessage_value->ByteSize();
+ result += io::CodedOutputStream::VarintSize32(size) + size;
+ } else {
+ result += WireFormatLite::MessageSize(*message_value);
+ }
+ break;
+ }
// Stuff with fixed size.
#define HANDLE_TYPE(UPPERCASE, CAMELCASE) \
@@ -1363,29 +1530,6 @@ int ExtensionSet::Extension::ByteSize(int number) const {
return result;
}
-int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
- if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
- // Not a valid MessageSet extension, but compute the byte size for it the
- // normal way.
- return ByteSize(number);
- }
-
- if (is_cleared) return 0;
-
- int our_size = WireFormatLite::kMessageSetItemTagsSize;
-
- // type_id
- our_size += io::CodedOutputStream::VarintSize32(number);
-
- // message
- int message_size = message_value->ByteSize();
-
- our_size += io::CodedOutputStream::VarintSize32(message_size);
- our_size += message_size;
-
- return our_size;
-}
-
int ExtensionSet::Extension::GetSize() const {
GOOGLE_DCHECK(is_repeated);
switch (cpp_type(type)) {
@@ -1436,7 +1580,11 @@ void ExtensionSet::Extension::Free() {
delete string_value;
break;
case WireFormatLite::CPPTYPE_MESSAGE:
- delete message_value;
+ if (is_lazy) {
+ delete lazymessage_value;
+ } else {
+ delete message_value;
+ }
break;
default:
break;
@@ -1447,6 +1595,69 @@ void ExtensionSet::Extension::Free() {
// Defined in extension_set_heavy.cc.
// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
+// ==================================================================
+// Default repeated field instances for iterator-compatible accessors
+
+const RepeatedStringTypeTraits::RepeatedFieldType*
+RepeatedStringTypeTraits::default_repeated_field_ = NULL;
+
+const RepeatedMessageGenericTypeTraits::RepeatedFieldType*
+RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL;
+
+#define PROTOBUF_DEFINE_DEFAULT_REPEATED(TYPE) \
+ const RepeatedField<TYPE>* \
+ RepeatedPrimitiveGenericTypeTraits::default_repeated_field_##TYPE##_ = NULL;
+
+PROTOBUF_DEFINE_DEFAULT_REPEATED(int32)
+PROTOBUF_DEFINE_DEFAULT_REPEATED(int64)
+PROTOBUF_DEFINE_DEFAULT_REPEATED(uint32)
+PROTOBUF_DEFINE_DEFAULT_REPEATED(uint64)
+PROTOBUF_DEFINE_DEFAULT_REPEATED(double)
+PROTOBUF_DEFINE_DEFAULT_REPEATED(float)
+PROTOBUF_DEFINE_DEFAULT_REPEATED(bool)
+
+#undef PROTOBUF_DEFINE_DEFAULT_REPEATED
+
+struct StaticDefaultRepeatedFieldsInitializer {
+ StaticDefaultRepeatedFieldsInitializer() {
+ InitializeDefaultRepeatedFields();
+ OnShutdown(&DestroyDefaultRepeatedFields);
+ }
+} static_repeated_fields_initializer;
+
+void InitializeDefaultRepeatedFields() {
+ RepeatedStringTypeTraits::default_repeated_field_ =
+ new RepeatedStringTypeTraits::RepeatedFieldType;
+ RepeatedMessageGenericTypeTraits::default_repeated_field_ =
+ new RepeatedMessageGenericTypeTraits::RepeatedFieldType;
+ RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ =
+ new RepeatedField<int32>;
+ RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ =
+ new RepeatedField<int64>;
+ RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ =
+ new RepeatedField<uint32>;
+ RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ =
+ new RepeatedField<uint64>;
+ RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ =
+ new RepeatedField<double>;
+ RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ =
+ new RepeatedField<float>;
+ RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ =
+ new RepeatedField<bool>;
+}
+
+void DestroyDefaultRepeatedFields() {
+ delete RepeatedStringTypeTraits::default_repeated_field_;
+ delete RepeatedMessageGenericTypeTraits::default_repeated_field_;
+ delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_;
+ delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_;
+ delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_;
+ delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_;
+ delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_;
+ delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_;
+ delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_;
+}
+
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index 14d5d15..d6fc45d 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -39,13 +39,15 @@
#define GOOGLE_PROTOBUF_EXTENSION_SET_H__
#include <vector>
-#include <stack>
#include <map>
#include <utility>
#include <string>
+
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/repeated_field.h>
+
namespace google {
namespace protobuf {
@@ -62,10 +64,7 @@ namespace protobuf {
}
namespace internal {
class FieldSkipper; // wire_format_lite.h
- class RepeatedPtrFieldBase; // repeated_field.h
}
- template <typename Element> class RepeatedField; // repeated_field.h
- template <typename Element> class RepeatedPtrField; // repeated_field.h
}
namespace protobuf {
@@ -89,8 +88,8 @@ typedef bool EnumValidityFuncWithArg(const void* arg, int number);
// Information about a registered extension.
struct ExtensionInfo {
inline ExtensionInfo() {}
- inline ExtensionInfo(FieldType type, bool is_repeated, bool is_packed)
- : type(type), is_repeated(is_repeated), is_packed(is_packed),
+ inline ExtensionInfo(FieldType type_param, bool isrepeated, bool ispacked)
+ : type(type_param), is_repeated(isrepeated), is_packed(ispacked),
descriptor(NULL) {}
FieldType type;
@@ -138,6 +137,9 @@ class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder {
const MessageLite* containing_type_;
};
+// A FieldSkipper used for parsing MessageSet.
+class MessageSetFieldSkipper;
+
// Note: extension_set_heavy.cc defines DescriptorPoolExtensionFinder for
// finding extensions from a DescriptorPool.
@@ -180,7 +182,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
// is useful to implement Reflection::ListFields().
void AppendToList(const Descriptor* containing_type,
const DescriptorPool* pool,
- vector<const FieldDescriptor*>* output) const;
+ std::vector<const FieldDescriptor*>* output) const;
// =================================================================
// Accessors
@@ -214,6 +216,8 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
bool Has(int number) const;
int ExtensionSize(int number) const; // Size of a repeated extension.
+ int NumExtensions() const; // The number of extensions
+ FieldType ExtensionType(int number) const;
void ClearExtension(int number);
// singular fields -------------------------------------------------
@@ -250,10 +254,35 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
const MessageLite& prototype, desc);
MessageLite* MutableMessage(const FieldDescriptor* decsriptor,
MessageFactory* factory);
+ // Adds the given message to the ExtensionSet, taking ownership of the
+ // message object. Existing message with the same number will be deleted.
+ // If "message" is NULL, this is equivalent to "ClearExtension(number)".
+ void SetAllocatedMessage(int number, FieldType type,
+ const FieldDescriptor* descriptor,
+ MessageLite* message);
+ MessageLite* ReleaseMessage(int number, const MessageLite& prototype);
+ MessageLite* ReleaseMessage(const FieldDescriptor* descriptor,
+ MessageFactory* factory);
#undef desc
// repeated fields -------------------------------------------------
+ // Fetches a RepeatedField extension by number; returns |default_value|
+ // if no such extension exists. User should not touch this directly; it is
+ // used by the GetRepeatedExtension() method.
+ const void* GetRawRepeatedField(int number, const void* default_value) const;
+ // Fetches a mutable version of a RepeatedField extension by number,
+ // instantiating one if none exists. Similar to above, user should not use
+ // this directly; it underlies MutableRepeatedExtension().
+ void* MutableRawRepeatedField(int number, FieldType field_type,
+ bool packed, const FieldDescriptor* desc);
+
+ // This is an overload of MutableRawRepeatedField to maintain compatibility
+ // with old code using a previous API. This version of
+ // MutableRawRepeatedField() will GOOGLE_CHECK-fail on a missing extension.
+ // (E.g.: borg/clients/internal/proto1/proto2_reflection.cc.)
+ void* MutableRawRepeatedField(int number);
+
int32 GetRepeatedInt32 (int number, int index) const;
int64 GetRepeatedInt64 (int number, int index) const;
uint32 GetRepeatedUInt32(int number, int index) const;
@@ -295,6 +324,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
#undef desc
void RemoveLast(int number);
+ MessageLite* ReleaseLast(int number);
void SwapElements(int number, int index1, int index2);
// -----------------------------------------------------------------
@@ -309,31 +339,35 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
void Clear();
void MergeFrom(const ExtensionSet& other);
void Swap(ExtensionSet* other);
+ void SwapExtension(ExtensionSet* other, int number);
bool IsInitialized() const;
- // Parses a single extension from the input. The input should start out
- // positioned immediately after the tag. |containing_type| is the default
- // instance for the containing message; it is used only to look up the
- // extension by number. See RegisterExtension(), above. Unlike the other
- // methods of ExtensionSet, this only works for generated message types --
- // it looks up extensions registered using RegisterExtension().
+ // Parses a single extension from the input. The input should start out
+ // positioned immediately after the tag.
bool ParseField(uint32 tag, io::CodedInputStream* input,
ExtensionFinder* extension_finder,
FieldSkipper* field_skipper);
// Specific versions for lite or full messages (constructs the appropriate
- // FieldSkipper automatically).
+ // FieldSkipper automatically). |containing_type| is the default
+ // instance for the containing message; it is used only to look up the
+ // extension by number. See RegisterExtension(), above. Unlike the other
+ // methods of ExtensionSet, this only works for generated message types --
+ // it looks up extensions registered using RegisterExtension().
bool ParseField(uint32 tag, io::CodedInputStream* input,
const MessageLite* containing_type);
bool ParseField(uint32 tag, io::CodedInputStream* input,
const Message* containing_type,
UnknownFieldSet* unknown_fields);
+ bool ParseField(uint32 tag, io::CodedInputStream* input,
+ const MessageLite* containing_type,
+ io::CodedOutputStream* unknown_fields);
// Parse an entire message in MessageSet format. Such messages have no
// fields, only extensions.
bool ParseMessageSet(io::CodedInputStream* input,
ExtensionFinder* extension_finder,
- FieldSkipper* field_skipper);
+ MessageSetFieldSkipper* field_skipper);
// Specific versions for lite or full messages (constructs the appropriate
// FieldSkipper automatically).
@@ -381,18 +415,49 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
private:
+ // Interface of a lazily parsed singular message extension.
+ class LIBPROTOBUF_EXPORT LazyMessageExtension {
+ public:
+ LazyMessageExtension() {}
+ virtual ~LazyMessageExtension() {}
+
+ virtual LazyMessageExtension* New() const = 0;
+ virtual const MessageLite& GetMessage(
+ const MessageLite& prototype) const = 0;
+ virtual MessageLite* MutableMessage(const MessageLite& prototype) = 0;
+ virtual void SetAllocatedMessage(MessageLite *message) = 0;
+ virtual MessageLite* ReleaseMessage(const MessageLite& prototype) = 0;
+
+ virtual bool IsInitialized() const = 0;
+ virtual int ByteSize() const = 0;
+ virtual int SpaceUsed() const = 0;
+
+ virtual void MergeFrom(const LazyMessageExtension& other) = 0;
+ virtual void Clear() = 0;
+
+ virtual bool ReadMessage(const MessageLite& prototype,
+ io::CodedInputStream* input) = 0;
+ virtual void WriteMessage(int number,
+ io::CodedOutputStream* output) const = 0;
+ virtual uint8* WriteMessageToArray(int number, uint8* target) const = 0;
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyMessageExtension);
+ };
struct Extension {
+ // The order of these fields packs Extension into 24 bytes when using 8
+ // byte alignment. Consider this when adding or removing fields here.
union {
- int32 int32_value;
- int64 int64_value;
- uint32 uint32_value;
- uint64 uint64_value;
- float float_value;
- double double_value;
- bool bool_value;
- int enum_value;
- string* string_value;
- MessageLite* message_value;
+ int32 int32_value;
+ int64 int64_value;
+ uint32 uint32_value;
+ uint64 uint64_value;
+ float float_value;
+ double double_value;
+ bool bool_value;
+ int enum_value;
+ string* string_value;
+ MessageLite* message_value;
+ LazyMessageExtension* lazymessage_value;
RepeatedField <int32 >* repeated_int32_value;
RepeatedField <int64 >* repeated_int64_value;
@@ -415,21 +480,28 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
// removing it from the map, we just set is_cleared = true. This has no
// meaning for repeated types; for those, the size of the RepeatedField
// simply becomes zero when cleared.
- bool is_cleared;
+ bool is_cleared : 4;
+
+ // For singular message types, indicates whether lazy parsing is enabled
+ // for this extension. This field is only valid when type == TYPE_MESSAGE
+ // and !is_repeated because we only support lazy parsing for singular
+ // message types currently. If is_lazy = true, the extension is stored in
+ // lazymessage_value. Otherwise, the extension will be message_value.
+ bool is_lazy : 4;
// For repeated types, this indicates if the [packed=true] option is set.
bool is_packed;
- // The descriptor for this extension, if one exists and is known. May be
- // NULL. Must not be NULL if the descriptor for the extension does not
- // live in the same pool as the descriptor for the containing type.
- const FieldDescriptor* descriptor;
-
// For packed fields, the size of the packed data is recorded here when
// ByteSize() is called then used during serialization.
// TODO(kenton): Use atomic<int> when C++ supports it.
mutable int cached_size;
+ // The descriptor for this extension, if one exists and is known. May be
+ // NULL. Must not be NULL if the descriptor for the extension does not
+ // live in the same pool as the descriptor for the containing type.
+ const FieldDescriptor* descriptor;
+
// Some helper methods for operations on a single Extension.
void SerializeFieldWithCachedSizes(
int number,
@@ -451,6 +523,41 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
int SpaceUsedExcludingSelf() const;
};
+
+ // Returns true and fills field_number and extension if extension is found.
+ // Note to support packed repeated field compatibility, it also fills whether
+ // the tag on wire is packed, which can be different from
+ // extension->is_packed (whether packed=true is specified).
+ bool FindExtensionInfoFromTag(uint32 tag, ExtensionFinder* extension_finder,
+ int* field_number, ExtensionInfo* extension,
+ bool* was_packed_on_wire);
+
+ // Returns true and fills extension if extension is found.
+ // Note to support packed repeated field compatibility, it also fills whether
+ // the tag on wire is packed, which can be different from
+ // extension->is_packed (whether packed=true is specified).
+ bool FindExtensionInfoFromFieldNumber(int wire_type, int field_number,
+ ExtensionFinder* extension_finder,
+ ExtensionInfo* extension,
+ bool* was_packed_on_wire);
+
+ // Parses a single extension from the input. The input should start out
+ // positioned immediately after the wire tag. This method is called in
+ // ParseField() after field number and was_packed_on_wire is extracted from
+ // the wire tag and ExtensionInfo is found by the field number.
+ bool ParseFieldWithExtensionInfo(int field_number,
+ bool was_packed_on_wire,
+ const ExtensionInfo& extension,
+ io::CodedInputStream* input,
+ FieldSkipper* field_skipper);
+
+ // Like ParseField(), but this method may parse singular message extensions
+ // lazily depending on the value of FLAGS_eagerly_parse_message_sets.
+ bool ParseFieldMaybeLazily(int wire_type, int field_number,
+ io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ MessageSetFieldSkipper* field_skipper);
+
// Gets the extension with the given number, creating it if it does not
// already exist. Returns true if the extension did not already exist.
bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
@@ -460,7 +567,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
// tag has been read.
bool ParseMessageSetItem(io::CodedInputStream* input,
ExtensionFinder* extension_finder,
- FieldSkipper* field_skipper);
+ MessageSetFieldSkipper* field_skipper);
// Hack: RepeatedPtrFieldBase declares ExtensionSet as a friend. This
@@ -479,7 +586,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.
- map<int, Extension> extensions_;
+ std::map<int, Extension> extensions_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
};
@@ -515,6 +622,16 @@ inline void ExtensionSet::AddString(int number, FieldType type,
// public:
// typedef ? ConstType;
// typedef ? MutableType;
+// // TypeTraits for singular fields and repeated fields will define the
+// // symbol "Singular" or "Repeated" respectively. These two symbols will
+// // be used in extension accessors to distinguish between singular
+// // extensions and repeated extensions. If the TypeTraits for the passed
+// // in extension doesn't have the expected symbol defined, it means the
+// // user is passing a repeated extension to a singular accessor, or the
+// // opposite. In that case the C++ compiler will generate an error
+// // message "no matching member function" to inform the user.
+// typedef ? Singular
+// typedef ? Repeated
//
// static inline ConstType Get(int number, const ExtensionSet& set);
// static inline void Set(int number, ConstType value, ExtensionSet* set);
@@ -553,6 +670,8 @@ template <typename Type>
class PrimitiveTypeTraits {
public:
typedef Type ConstType;
+ typedef Type MutableType;
+ typedef PrimitiveTypeTraits<Type> Singular;
static inline ConstType Get(int number, const ExtensionSet& set,
ConstType default_value);
@@ -564,11 +683,41 @@ template <typename Type>
class RepeatedPrimitiveTypeTraits {
public:
typedef Type ConstType;
+ typedef Type MutableType;
+ typedef RepeatedPrimitiveTypeTraits<Type> Repeated;
+
+ typedef RepeatedField<Type> RepeatedFieldType;
static inline Type Get(int number, const ExtensionSet& set, int index);
static inline void Set(int number, int index, Type value, ExtensionSet* set);
static inline void Add(int number, FieldType field_type,
bool is_packed, Type value, ExtensionSet* set);
+
+ static inline const RepeatedField<ConstType>&
+ GetRepeated(int number, const ExtensionSet& set);
+ static inline RepeatedField<Type>*
+ MutableRepeated(int number, FieldType field_type,
+ bool is_packed, ExtensionSet* set);
+
+ static const RepeatedFieldType* GetDefaultRepeatedField();
+};
+
+// Declared here so that this can be friended below.
+void InitializeDefaultRepeatedFields();
+void DestroyDefaultRepeatedFields();
+
+class LIBPROTOBUF_EXPORT RepeatedPrimitiveGenericTypeTraits {
+ private:
+ template<typename Type> friend class RepeatedPrimitiveTypeTraits;
+ friend void InitializeDefaultRepeatedFields();
+ friend void DestroyDefaultRepeatedFields();
+ static const RepeatedField<int32>* default_repeated_field_int32_;
+ static const RepeatedField<int64>* default_repeated_field_int64_;
+ static const RepeatedField<uint32>* default_repeated_field_uint32_;
+ static const RepeatedField<uint64>* default_repeated_field_uint64_;
+ static const RepeatedField<double>* default_repeated_field_double_;
+ static const RepeatedField<float>* default_repeated_field_float_;
+ static const RepeatedField<bool>* default_repeated_field_bool_;
};
#define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD) \
@@ -593,6 +742,26 @@ template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add( \
int number, FieldType field_type, bool is_packed, \
TYPE value, ExtensionSet* set) { \
set->Add##METHOD(number, field_type, is_packed, value, NULL); \
+} \
+template<> inline const RepeatedField<TYPE>* \
+ RepeatedPrimitiveTypeTraits<TYPE>::GetDefaultRepeatedField() { \
+ return RepeatedPrimitiveGenericTypeTraits:: \
+ default_repeated_field_##TYPE##_; \
+} \
+template<> inline const RepeatedField<TYPE>& \
+ RepeatedPrimitiveTypeTraits<TYPE>::GetRepeated(int number, \
+ const ExtensionSet& set) { \
+ return *reinterpret_cast<const RepeatedField<TYPE>*>( \
+ set.GetRawRepeatedField( \
+ number, GetDefaultRepeatedField())); \
+} \
+template<> inline RepeatedField<TYPE>* \
+ RepeatedPrimitiveTypeTraits<TYPE>::MutableRepeated(int number, \
+ FieldType field_type, \
+ bool is_packed, \
+ ExtensionSet* set) { \
+ return reinterpret_cast<RepeatedField<TYPE>*>( \
+ set->MutableRawRepeatedField(number, field_type, is_packed, NULL)); \
}
PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32, Int32)
@@ -613,6 +782,7 @@ class LIBPROTOBUF_EXPORT StringTypeTraits {
public:
typedef const string& ConstType;
typedef string* MutableType;
+ typedef StringTypeTraits Singular;
static inline const string& Get(int number, const ExtensionSet& set,
ConstType default_value) {
@@ -632,6 +802,9 @@ class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
public:
typedef const string& ConstType;
typedef string* MutableType;
+ typedef RepeatedStringTypeTraits Repeated;
+
+ typedef RepeatedPtrField<string> RepeatedFieldType;
static inline const string& Get(int number, const ExtensionSet& set,
int index) {
@@ -653,6 +826,28 @@ class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
ExtensionSet* set) {
return set->AddString(number, field_type, NULL);
}
+ static inline const RepeatedPtrField<string>&
+ GetRepeated(int number, const ExtensionSet& set) {
+ return *reinterpret_cast<const RepeatedPtrField<string>*>(
+ set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
+ }
+
+ static inline RepeatedPtrField<string>*
+ MutableRepeated(int number, FieldType field_type,
+ bool is_packed, ExtensionSet* set) {
+ return reinterpret_cast<RepeatedPtrField<string>*>(
+ set->MutableRawRepeatedField(number, field_type,
+ is_packed, NULL));
+ }
+
+ static const RepeatedFieldType* GetDefaultRepeatedField() {
+ return default_repeated_field_;
+ }
+
+ private:
+ friend void InitializeDefaultRepeatedFields();
+ friend void DestroyDefaultRepeatedFields();
+ static const RepeatedFieldType *default_repeated_field_;
};
// -------------------------------------------------------------------
@@ -664,6 +859,8 @@ template <typename Type, bool IsValid(int)>
class EnumTypeTraits {
public:
typedef Type ConstType;
+ typedef Type MutableType;
+ typedef EnumTypeTraits<Type, IsValid> Singular;
static inline ConstType Get(int number, const ExtensionSet& set,
ConstType default_value) {
@@ -680,6 +877,10 @@ template <typename Type, bool IsValid(int)>
class RepeatedEnumTypeTraits {
public:
typedef Type ConstType;
+ typedef Type MutableType;
+ typedef RepeatedEnumTypeTraits<Type, IsValid> Repeated;
+
+ typedef RepeatedField<Type> RepeatedFieldType;
static inline ConstType Get(int number, const ExtensionSet& set, int index) {
return static_cast<Type>(set.GetRepeatedEnum(number, index));
@@ -694,6 +895,35 @@ class RepeatedEnumTypeTraits {
GOOGLE_DCHECK(IsValid(value));
set->AddEnum(number, field_type, is_packed, value, NULL);
}
+ static inline const RepeatedField<Type>& GetRepeated(int number,
+ const ExtensionSet&
+ set) {
+ // Hack: the `Extension` struct stores a RepeatedField<int> for enums.
+ // RepeatedField<int> cannot implicitly convert to RepeatedField<EnumType>
+ // so we need to do some casting magic. See message.h for similar
+ // contortions for non-extension fields.
+ return *reinterpret_cast<const RepeatedField<Type>*>(
+ set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
+ }
+
+ static inline RepeatedField<Type>* MutableRepeated(int number,
+ FieldType field_type,
+ bool is_packed,
+ ExtensionSet* set) {
+ return reinterpret_cast<RepeatedField<Type>*>(
+ set->MutableRawRepeatedField(number, field_type, is_packed, NULL));
+ }
+
+ static const RepeatedFieldType* GetDefaultRepeatedField() {
+ // Hack: as noted above, repeated enum fields are internally stored as a
+ // RepeatedField<int>. We need to be able to instantiate global static
+ // objects to return as default (empty) repeated fields on non-existent
+ // extensions. We would not be able to know a-priori all of the enum types
+ // (values of |Type|) to instantiate all of these, so we just re-use int32's
+ // default repeated field object.
+ return reinterpret_cast<const RepeatedField<Type>*>(
+ RepeatedPrimitiveTypeTraits<int32>::GetDefaultRepeatedField());
+ }
};
// -------------------------------------------------------------------
@@ -707,6 +937,7 @@ class MessageTypeTraits {
public:
typedef const Type& ConstType;
typedef Type* MutableType;
+ typedef MessageTypeTraits<Type> Singular;
static inline ConstType Get(int number, const ExtensionSet& set,
ConstType default_value) {
@@ -718,13 +949,28 @@ class MessageTypeTraits {
return static_cast<Type*>(
set->MutableMessage(number, field_type, Type::default_instance(), NULL));
}
+ static inline void SetAllocated(int number, FieldType field_type,
+ MutableType message, ExtensionSet* set) {
+ set->SetAllocatedMessage(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()));
+ }
};
+// forward declaration
+class RepeatedMessageGenericTypeTraits;
+
template <typename Type>
class RepeatedMessageTypeTraits {
public:
typedef const Type& ConstType;
typedef Type* MutableType;
+ typedef RepeatedMessageTypeTraits<Type> Repeated;
+
+ typedef RepeatedPtrField<Type> RepeatedFieldType;
static inline ConstType Get(int number, const ExtensionSet& set, int index) {
return static_cast<const Type&>(set.GetRepeatedMessage(number, index));
@@ -737,8 +983,47 @@ class RepeatedMessageTypeTraits {
return static_cast<Type*>(
set->AddMessage(number, field_type, Type::default_instance(), NULL));
}
+ static inline const RepeatedPtrField<Type>& GetRepeated(int number,
+ const ExtensionSet&
+ set) {
+ // See notes above in RepeatedEnumTypeTraits::GetRepeated(): same
+ // casting hack applies here, because a RepeatedPtrField<MessageLite>
+ // cannot naturally become a RepeatedPtrType<Type> even though Type is
+ // presumably a message. google::protobuf::Message goes through similar contortions
+ // with a reinterpret_cast<>.
+ return *reinterpret_cast<const RepeatedPtrField<Type>*>(
+ set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
+ }
+ static inline RepeatedPtrField<Type>* MutableRepeated(int number,
+ FieldType field_type,
+ bool is_packed,
+ ExtensionSet* set) {
+ return reinterpret_cast<RepeatedPtrField<Type>*>(
+ set->MutableRawRepeatedField(number, field_type, is_packed, NULL));
+ }
+
+ static const RepeatedFieldType* GetDefaultRepeatedField();
};
+// This class exists only to hold a generic default empty repeated field for all
+// message-type repeated field extensions.
+class LIBPROTOBUF_EXPORT RepeatedMessageGenericTypeTraits {
+ public:
+ typedef RepeatedPtrField< ::google::protobuf::MessageLite*> RepeatedFieldType;
+ private:
+ template<typename Type> friend class RepeatedMessageTypeTraits;
+ friend void InitializeDefaultRepeatedFields();
+ friend void DestroyDefaultRepeatedFields();
+ static const RepeatedFieldType* default_repeated_field_;
+};
+
+template<typename Type> inline
+ const typename RepeatedMessageTypeTraits<Type>::RepeatedFieldType*
+ RepeatedMessageTypeTraits<Type>::GetDefaultRepeatedField() {
+ return reinterpret_cast<const RepeatedFieldType*>(
+ RepeatedMessageGenericTypeTraits::default_repeated_field_);
+}
+
// -------------------------------------------------------------------
// ExtensionIdentifier
@@ -785,114 +1070,161 @@ class ExtensionIdentifier {
// causes problems if the class has a nested message or enum type with that
// name and "_TypeTraits" is technically reserved for the C++ library since
// it starts with an underscore followed by a capital letter.
+//
+// For similar reason, we use "_field_type" and "_is_packed" as parameter names
+// below, so that "field_type" and "is_packed" can be used as field names.
#define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME) \
/* Has, Size, Clear */ \
template <typename _proto_TypeTraits, \
- ::google::protobuf::internal::FieldType field_type, \
- bool is_packed> \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
inline bool HasExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
- CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \
return _extensions_.Has(id.number()); \
} \
\
template <typename _proto_TypeTraits, \
- ::google::protobuf::internal::FieldType field_type, \
- bool is_packed> \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
inline void ClearExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
- CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \
_extensions_.ClearExtension(id.number()); \
} \
\
template <typename _proto_TypeTraits, \
- ::google::protobuf::internal::FieldType field_type, \
- bool is_packed> \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
inline int ExtensionSize( \
const ::google::protobuf::internal::ExtensionIdentifier< \
- CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \
return _extensions_.ExtensionSize(id.number()); \
} \
\
/* Singular accessors */ \
template <typename _proto_TypeTraits, \
- ::google::protobuf::internal::FieldType field_type, \
- bool is_packed> \
- inline typename _proto_TypeTraits::ConstType GetExtension( \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
+ inline typename _proto_TypeTraits::Singular::ConstType GetExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
- CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \
return _proto_TypeTraits::Get(id.number(), _extensions_, \
id.default_value()); \
} \
\
template <typename _proto_TypeTraits, \
- ::google::protobuf::internal::FieldType field_type, \
- bool is_packed> \
- inline typename _proto_TypeTraits::MutableType MutableExtension( \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
+ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
- CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \
- return _proto_TypeTraits::Mutable(id.number(), field_type, &_extensions_);\
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \
+ return _proto_TypeTraits::Mutable(id.number(), _field_type, \
+ &_extensions_); \
} \
\
template <typename _proto_TypeTraits, \
- ::google::protobuf::internal::FieldType field_type, \
- bool is_packed> \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
inline void SetExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
- CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
- typename _proto_TypeTraits::ConstType value) { \
- _proto_TypeTraits::Set(id.number(), field_type, value, &_extensions_); \
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \
+ typename _proto_TypeTraits::Singular::ConstType value) { \
+ _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); \
+ } \
+ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
+ inline void SetAllocatedExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \
+ typename _proto_TypeTraits::Singular::MutableType value) { \
+ _proto_TypeTraits::SetAllocated(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_); \
} \
\
/* Repeated accessors */ \
template <typename _proto_TypeTraits, \
- ::google::protobuf::internal::FieldType field_type, \
- bool is_packed> \
- inline typename _proto_TypeTraits::ConstType GetExtension( \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
+ inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
- CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \
int index) const { \
return _proto_TypeTraits::Get(id.number(), _extensions_, index); \
} \
\
template <typename _proto_TypeTraits, \
- ::google::protobuf::internal::FieldType field_type, \
- bool is_packed> \
- inline typename _proto_TypeTraits::MutableType MutableExtension( \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
+ inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
- CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \
int index) { \
return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); \
} \
\
template <typename _proto_TypeTraits, \
- ::google::protobuf::internal::FieldType field_type, \
- bool is_packed> \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
inline void SetExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
- CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
- int index, typename _proto_TypeTraits::ConstType value) { \
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \
+ int index, typename _proto_TypeTraits::Repeated::ConstType value) { \
_proto_TypeTraits::Set(id.number(), index, value, &_extensions_); \
} \
\
template <typename _proto_TypeTraits, \
- ::google::protobuf::internal::FieldType field_type, \
- bool is_packed> \
- inline typename _proto_TypeTraits::MutableType AddExtension( \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
+ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
- CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \
- return _proto_TypeTraits::Add(id.number(), field_type, &_extensions_); \
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \
+ return _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); \
} \
\
template <typename _proto_TypeTraits, \
- ::google::protobuf::internal::FieldType field_type, \
- bool is_packed> \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
inline void AddExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
- CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
- typename _proto_TypeTraits::ConstType value) { \
- _proto_TypeTraits::Add(id.number(), field_type, is_packed, \
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \
+ typename _proto_TypeTraits::Repeated::ConstType value) { \
+ _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, \
value, &_extensions_); \
+ } \
+ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
+ inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& \
+ GetRepeatedExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, _field_type, \
+ _is_packed>& id) const { \
+ return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); \
+ } \
+ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
+ inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* \
+ MutableRepeatedExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, _field_type, \
+ _is_packed>& id) { \
+ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, \
+ _is_packed, &_extensions_); \
}
} // namespace internal
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc
index 2721f15..a50efac 100644
--- a/src/google/protobuf/extension_set_heavy.cc
+++ b/src/google/protobuf/extension_set_heavy.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,17 +35,43 @@
// Contains methods defined in extension_set.h which cannot be part of the
// lite library because they use descriptors or reflection.
-#include <google/protobuf/extension_set.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/extension_set.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/wire_format_lite_inl.h>
namespace google {
+
namespace protobuf {
namespace internal {
+// A FieldSkipper used to store unknown MessageSet fields into UnknownFieldSet.
+class MessageSetFieldSkipper
+ : public UnknownFieldSetFieldSkipper {
+ public:
+ explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields)
+ : UnknownFieldSetFieldSkipper(unknown_fields) {}
+ virtual ~MessageSetFieldSkipper() {}
+
+ virtual bool SkipMessageSetField(io::CodedInputStream* input,
+ int field_number);
+};
+bool MessageSetFieldSkipper::SkipMessageSetField(
+ io::CodedInputStream* input, int field_number) {
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ if (unknown_fields_ == NULL) {
+ return input->Skip(length);
+ } else {
+ return input->ReadString(
+ unknown_fields_->AddLengthDelimited(field_number), length);
+ }
+}
+
+
// Implementation of ExtensionFinder which finds extensions in a given
// DescriptorPool, using the given MessageFactory to construct sub-objects.
// This class is implemented in extension_set_heavy.cc.
@@ -67,7 +93,7 @@ class DescriptorPoolExtensionFinder : public ExtensionFinder {
void ExtensionSet::AppendToList(const Descriptor* containing_type,
const DescriptorPool* pool,
- vector<const FieldDescriptor*>* output) const {
+ std::vector<const FieldDescriptor*>* output) const {
for (map<int, Extension>::const_iterator iter = extensions_.begin();
iter != extensions_.end(); ++iter) {
bool has = false;
@@ -103,6 +129,11 @@ inline FieldDescriptor::CppType cpp_type(FieldType type) {
static_cast<FieldDescriptor::Type>(type));
}
+inline WireFormatLite::FieldType field_type(FieldType type) {
+ GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
+ return static_cast<WireFormatLite::FieldType>(type);
+}
+
#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \
: FieldDescriptor::LABEL_OPTIONAL, \
@@ -118,7 +149,12 @@ const MessageLite& ExtensionSet::GetMessage(int number,
return *factory->GetPrototype(message_type);
} else {
GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
- return *iter->second.message_value;
+ if (iter->second.is_lazy) {
+ return iter->second.lazymessage_value->GetMessage(
+ *factory->GetPrototype(message_type));
+ } else {
+ return *iter->second.message_value;
+ }
}
}
@@ -132,13 +168,41 @@ MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
extension->is_packed = false;
const MessageLite* prototype =
factory->GetPrototype(descriptor->message_type());
- GOOGLE_CHECK(prototype != NULL);
+ extension->is_lazy = false;
extension->message_value = prototype->New();
+ extension->is_cleared = false;
+ return extension->message_value;
} else {
GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
+ extension->is_cleared = false;
+ if (extension->is_lazy) {
+ return extension->lazymessage_value->MutableMessage(
+ *factory->GetPrototype(descriptor->message_type()));
+ } else {
+ return extension->message_value;
+ }
+ }
+}
+
+MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
+ MessageFactory* factory) {
+ map<int, Extension>::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->ReleaseMessage(
+ *factory->GetPrototype(descriptor->message_type()));
+ delete iter->second.lazymessage_value;
+ } else {
+ ret = iter->second.message_value;
+ }
+ extensions_.erase(descriptor->number());
+ return ret;
}
- extension->is_cleared = false;
- return extension->message_value;
}
MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
@@ -157,7 +221,7 @@ MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
// RepeatedPtrField<Message> does not know how to Add() since it cannot
// allocate an abstract object, so we have to be tricky.
MessageLite* result = extension->repeated_message_value
- ->AddFromCleared<internal::GenericTypeHandler<MessageLite> >();
+ ->AddFromCleared<GenericTypeHandler<MessageLite> >();
if (result == NULL) {
const MessageLite* prototype;
if (extension->repeated_message_value->size() == 0) {
@@ -220,7 +284,7 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
const Message* containing_type,
UnknownFieldSet* unknown_fields) {
- UnknownFieldSetFieldSkipper skipper(unknown_fields);
+ MessageSetFieldSkipper skipper(unknown_fields);
if (input->GetExtensionPool() == NULL) {
GeneratedExtensionFinder finder(containing_type);
return ParseMessageSet(input, &finder, &skipper);
@@ -286,7 +350,11 @@ int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
StringSpaceUsedExcludingSelf(*string_value);
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
- total_size += down_cast<Message*>(message_value)->SpaceUsed();
+ if (is_lazy) {
+ total_size += lazymessage_value->SpaceUsed();
+ } else {
+ total_size += down_cast<Message*>(message_value)->SpaceUsed();
+ }
break;
default:
// No extra storage costs for primitive types.
@@ -419,8 +487,15 @@ uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray(
HANDLE_TYPE( BYTES, Bytes, *string_value);
HANDLE_TYPE( ENUM, Enum, enum_value);
HANDLE_TYPE( GROUP, Group, *message_value);
- HANDLE_TYPE( MESSAGE, Message, *message_value);
#undef HANDLE_TYPE
+ case FieldDescriptor::TYPE_MESSAGE:
+ if (is_lazy) {
+ target = lazymessage_value->WriteMessageToArray(number, target);
+ } else {
+ target = WireFormatLite::WriteMessageToArray(
+ number, *message_value, target);
+ }
+ break;
}
}
return target;
@@ -444,14 +519,216 @@ uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray(
target = WireFormatLite::WriteUInt32ToArray(
WireFormatLite::kMessageSetTypeIdNumber, number, target);
// Write message.
- target = WireFormatLite::WriteMessageToArray(
- WireFormatLite::kMessageSetMessageNumber, *message_value, target);
+ if (is_lazy) {
+ target = lazymessage_value->WriteMessageToArray(
+ WireFormatLite::kMessageSetMessageNumber, target);
+ } else {
+ target = WireFormatLite::WriteMessageToArray(
+ WireFormatLite::kMessageSetMessageNumber, *message_value, target);
+ }
// End group.
target = io::CodedOutputStream::WriteTagToArray(
WireFormatLite::kMessageSetItemEndTag, target);
return target;
}
+
+bool ExtensionSet::ParseFieldMaybeLazily(
+ int wire_type, int field_number, io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ MessageSetFieldSkipper* field_skipper) {
+ return ParseField(WireFormatLite::MakeTag(
+ field_number, static_cast<WireFormatLite::WireType>(wire_type)),
+ input, extension_finder, field_skipper);
+}
+
+bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ MessageSetFieldSkipper* field_skipper) {
+ while (true) {
+ const uint32 tag = input->ReadTag();
+ switch (tag) {
+ case 0:
+ return true;
+ case WireFormatLite::kMessageSetItemStartTag:
+ if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
+ return false;
+ }
+ break;
+ default:
+ if (!ParseField(tag, input, extension_finder, field_skipper)) {
+ return false;
+ }
+ break;
+ }
+ }
+}
+
+bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
+ const MessageLite* containing_type) {
+ MessageSetFieldSkipper skipper(NULL);
+ GeneratedExtensionFinder finder(containing_type);
+ return ParseMessageSet(input, &finder, &skipper);
+}
+
+bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ MessageSetFieldSkipper* field_skipper) {
+ // TODO(kenton): It would be nice to share code between this and
+ // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
+ // differences would be hard to factor out.
+
+ // This method parses a group which should contain two fields:
+ // required int32 type_id = 2;
+ // required data message = 3;
+
+ uint32 last_type_id = 0;
+
+ // If we see message data before the type_id, we'll append it to this so
+ // we can parse it later.
+ string message_data;
+
+ while (true) {
+ const uint32 tag = input->ReadTag();
+ if (tag == 0) return false;
+
+ switch (tag) {
+ case WireFormatLite::kMessageSetTypeIdTag: {
+ uint32 type_id;
+ if (!input->ReadVarint32(&type_id)) return false;
+ last_type_id = type_id;
+
+ if (!message_data.empty()) {
+ // We saw some message data before the type_id. Have to parse it
+ // now.
+ io::CodedInputStream sub_input(
+ reinterpret_cast<const uint8*>(message_data.data()),
+ message_data.size());
+ if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ last_type_id, &sub_input,
+ extension_finder, field_skipper)) {
+ return false;
+ }
+ message_data.clear();
+ }
+
+ break;
+ }
+
+ case WireFormatLite::kMessageSetMessageTag: {
+ if (last_type_id == 0) {
+ // We haven't seen a type_id yet. Append this data to message_data.
+ string temp;
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ if (!input->ReadString(&temp, length)) return false;
+ io::StringOutputStream output_stream(&message_data);
+ io::CodedOutputStream coded_output(&output_stream);
+ coded_output.WriteVarint32(length);
+ coded_output.WriteString(temp);
+ } else {
+ // Already saw type_id, so we can parse this directly.
+ if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ last_type_id, input,
+ extension_finder, field_skipper)) {
+ return false;
+ }
+ }
+
+ break;
+ }
+
+ case WireFormatLite::kMessageSetItemEndTag: {
+ return true;
+ }
+
+ default: {
+ if (!field_skipper->SkipField(input, tag)) return false;
+ }
+ }
+ }
+}
+
+void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
+ int number,
+ io::CodedOutputStream* output) const {
+ if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
+ // Not a valid MessageSet extension, but serialize it the normal way.
+ SerializeFieldWithCachedSizes(number, output);
+ return;
+ }
+
+ if (is_cleared) return;
+
+ // Start group.
+ output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
+
+ // Write type ID.
+ WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
+ number,
+ output);
+ // Write message.
+ if (is_lazy) {
+ lazymessage_value->WriteMessage(
+ WireFormatLite::kMessageSetMessageNumber, output);
+ } else {
+ WireFormatLite::WriteMessageMaybeToArray(
+ WireFormatLite::kMessageSetMessageNumber,
+ *message_value,
+ output);
+ }
+
+ // End group.
+ output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
+}
+
+int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
+ if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
+ // Not a valid MessageSet extension, but compute the byte size for it the
+ // normal way.
+ return ByteSize(number);
+ }
+
+ if (is_cleared) return 0;
+
+ int our_size = WireFormatLite::kMessageSetItemTagsSize;
+
+ // type_id
+ our_size += io::CodedOutputStream::VarintSize32(number);
+
+ // message
+ int message_size = 0;
+ if (is_lazy) {
+ message_size = lazymessage_value->ByteSize();
+ } else {
+ message_size = message_value->ByteSize();
+ }
+
+ our_size += io::CodedOutputStream::VarintSize32(message_size);
+ our_size += message_size;
+
+ return our_size;
+}
+
+void ExtensionSet::SerializeMessageSetWithCachedSizes(
+ io::CodedOutputStream* output) const {
+ for (map<int, Extension>::const_iterator iter = extensions_.begin();
+ iter != extensions_.end(); ++iter) {
+ iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
+ }
+}
+
+int ExtensionSet::MessageSetByteSize() const {
+ int total_size = 0;
+
+ for (map<int, Extension>::const_iterator iter = extensions_.begin();
+ iter != extensions_.end(); ++iter) {
+ total_size += iter->second.MessageSetItemByteSize(iter->first);
+ }
+
+ return total_size;
+}
+
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc
index 000f846..8a00baf 100644
--- a/src/google/protobuf/extension_set_unittest.cc
+++ b/src/google/protobuf/extension_set_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -34,6 +34,7 @@
#include <google/protobuf/extension_set.h>
#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_mset.pb.h>
#include <google/protobuf/test_util.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
@@ -46,9 +47,10 @@
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
+
namespace protobuf {
namespace internal {
namespace {
@@ -140,23 +142,98 @@ TEST(ExtensionSetTest, ClearOneField) {
TestUtil::ExpectAllExtensionsSet(message);
}
+TEST(ExtensionSetTest, SetAllocatedExtension) {
+ unittest::TestAllExtensions message;
+ EXPECT_FALSE(message.HasExtension(
+ unittest::optional_foreign_message_extension));
+ // Add a extension using SetAllocatedExtension
+ unittest::ForeignMessage* foreign_message = new unittest::ForeignMessage();
+ message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
+ foreign_message);
+ EXPECT_TRUE(message.HasExtension(
+ unittest::optional_foreign_message_extension));
+ EXPECT_EQ(foreign_message,
+ message.MutableExtension(
+ unittest::optional_foreign_message_extension));
+ EXPECT_EQ(foreign_message,
+ &message.GetExtension(
+ unittest::optional_foreign_message_extension));
+
+ // SetAllocatedExtension should delete the previously existing extension.
+ // (We reply on unittest to check memory leaks for this case)
+ message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
+ new unittest::ForeignMessage());
+
+ // SetAllocatedExtension with a NULL parameter is equivalent to ClearExtenion.
+ message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
+ NULL);
+ EXPECT_FALSE(message.HasExtension(
+ unittest::optional_foreign_message_extension));
+}
+
+TEST(ExtensionSetTest, ReleaseExtension) {
+ unittest::TestMessageSet message;
+ EXPECT_FALSE(message.HasExtension(
+ unittest::TestMessageSetExtension1::message_set_extension));
+ // Add a extension using SetAllocatedExtension
+ unittest::TestMessageSetExtension1* extension =
+ new unittest::TestMessageSetExtension1();
+ message.SetAllocatedExtension(
+ unittest::TestMessageSetExtension1::message_set_extension,
+ extension);
+ EXPECT_TRUE(message.HasExtension(
+ unittest::TestMessageSetExtension1::message_set_extension));
+ // Release the extension using ReleaseExtension
+ unittest::TestMessageSetExtension1* released_extension =
+ message.ReleaseExtension(
+ unittest::TestMessageSetExtension1::message_set_extension);
+ EXPECT_EQ(extension, released_extension);
+ EXPECT_FALSE(message.HasExtension(
+ unittest::TestMessageSetExtension1::message_set_extension));
+ // ReleaseExtension will return the underlying object even after
+ // ClearExtension is called.
+ message.SetAllocatedExtension(
+ unittest::TestMessageSetExtension1::message_set_extension,
+ extension);
+ message.ClearExtension(
+ unittest::TestMessageSetExtension1::message_set_extension);
+ released_extension = message.ReleaseExtension(
+ unittest::TestMessageSetExtension1::message_set_extension);
+ EXPECT_TRUE(released_extension != NULL);
+ delete released_extension;
+}
+
+
TEST(ExtensionSetTest, CopyFrom) {
unittest::TestAllExtensions message1, message2;
- string data;
TestUtil::SetAllExtensions(&message1);
message2.CopyFrom(message1);
TestUtil::ExpectAllExtensionsSet(message2);
+ message2.CopyFrom(message1); // exercise copy when fields already exist
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ExtensioSetTest, CopyFromPacked) {
+ unittest::TestPackedExtensions message1, message2;
+
+ TestUtil::SetPackedExtensions(&message1);
+ message2.CopyFrom(message1);
+ TestUtil::ExpectPackedExtensionsSet(message2);
+ message2.CopyFrom(message1); // exercise copy when fields already exist
+ TestUtil::ExpectPackedExtensionsSet(message2);
}
TEST(ExtensionSetTest, CopyFromUpcasted) {
unittest::TestAllExtensions message1, message2;
- string data;
const Message& upcasted_message = message1;
TestUtil::SetAllExtensions(&message1);
message2.CopyFrom(upcasted_message);
TestUtil::ExpectAllExtensionsSet(message2);
+ // exercise copy when fields already exist
+ message2.CopyFrom(upcasted_message);
+ TestUtil::ExpectAllExtensionsSet(message2);
}
TEST(ExtensionSetTest, SwapWithEmpty) {
@@ -179,6 +256,82 @@ TEST(ExtensionSetTest, SwapWithSelf) {
TestUtil::ExpectAllExtensionsSet(message);
}
+TEST(ExtensionSetTest, SwapExtension) {
+ unittest::TestAllExtensions message1;
+ unittest::TestAllExtensions message2;
+
+ TestUtil::SetAllExtensions(&message1);
+ vector<const FieldDescriptor*> fields;
+
+ // Swap empty fields.
+ const Reflection* reflection = message1.GetReflection();
+ reflection->SwapFields(&message1, &message2, fields);
+ TestUtil::ExpectAllExtensionsSet(message1);
+ TestUtil::ExpectExtensionsClear(message2);
+
+ // Swap two extensions.
+ fields.push_back(
+ reflection->FindKnownExtensionByNumber(12));
+ fields.push_back(
+ reflection->FindKnownExtensionByNumber(25));
+ reflection->SwapFields(&message1, &message2, fields);
+
+ EXPECT_TRUE(message1.HasExtension(unittest::optional_int32_extension));
+ EXPECT_FALSE(message1.HasExtension(unittest::optional_double_extension));
+ EXPECT_FALSE(message1.HasExtension(unittest::optional_cord_extension));
+
+ EXPECT_FALSE(message2.HasExtension(unittest::optional_int32_extension));
+ EXPECT_TRUE(message2.HasExtension(unittest::optional_double_extension));
+ EXPECT_TRUE(message2.HasExtension(unittest::optional_cord_extension));
+}
+
+TEST(ExtensionSetTest, SwapExtensionWithEmpty) {
+ unittest::TestAllExtensions message1;
+ unittest::TestAllExtensions message2;
+ unittest::TestAllExtensions message3;
+
+ TestUtil::SetAllExtensions(&message3);
+
+ const Reflection* reflection = message3.GetReflection();
+ vector<const FieldDescriptor*> fields;
+ reflection->ListFields(message3, &fields);
+
+ reflection->SwapFields(&message1, &message2, fields);
+
+ TestUtil::ExpectExtensionsClear(message1);
+ TestUtil::ExpectExtensionsClear(message2);
+}
+
+TEST(ExtensionSetTest, SwapExtensionBothFull) {
+ unittest::TestAllExtensions message1;
+ unittest::TestAllExtensions message2;
+
+ TestUtil::SetAllExtensions(&message1);
+ TestUtil::SetAllExtensions(&message2);
+
+ const Reflection* reflection = message1.GetReflection();
+ vector<const FieldDescriptor*> fields;
+ reflection->ListFields(message1, &fields);
+
+ reflection->SwapFields(&message1, &message2, fields);
+
+ TestUtil::ExpectAllExtensionsSet(message1);
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ExtensionSetTest, SwapExtensionWithSelf) {
+ unittest::TestAllExtensions message1;
+
+ TestUtil::SetAllExtensions(&message1);
+
+ vector<const FieldDescriptor*> fields;
+ const Reflection* reflection = message1.GetReflection();
+ reflection->ListFields(message1, &fields);
+ reflection->SwapFields(&message1, &message1, fields);
+
+ TestUtil::ExpectAllExtensionsSet(message1);
+}
+
TEST(ExtensionSetTest, SerializationToArray) {
// Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
// compatibility of extensions.
@@ -276,6 +429,7 @@ TEST(ExtensionSetTest, Parsing) {
TestUtil::SetAllFields(&source);
source.SerializeToString(&data);
EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::SetOneofFields(&destination);
TestUtil::ExpectAllExtensionsSet(destination);
}
@@ -291,6 +445,48 @@ TEST(ExtensionSetTest, PackedParsing) {
TestUtil::ExpectPackedExtensionsSet(destination);
}
+TEST(ExtensionSetTest, PackedToUnpackedParsing) {
+ unittest::TestPackedTypes source;
+ unittest::TestUnpackedExtensions destination;
+ string data;
+
+ TestUtil::SetPackedFields(&source);
+ source.SerializeToString(&data);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectUnpackedExtensionsSet(destination);
+
+ // Reserialize
+ unittest::TestUnpackedTypes unpacked;
+ TestUtil::SetUnpackedFields(&unpacked);
+ EXPECT_TRUE(unpacked.SerializeAsString() == destination.SerializeAsString());
+
+ // Make sure we can add extensions.
+ destination.AddExtension(unittest::unpacked_int32_extension, 1);
+ destination.AddExtension(unittest::unpacked_enum_extension,
+ protobuf_unittest::FOREIGN_BAR);
+}
+
+TEST(ExtensionSetTest, UnpackedToPackedParsing) {
+ unittest::TestUnpackedTypes source;
+ unittest::TestPackedExtensions destination;
+ string data;
+
+ TestUtil::SetUnpackedFields(&source);
+ source.SerializeToString(&data);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectPackedExtensionsSet(destination);
+
+ // Reserialize
+ unittest::TestPackedTypes packed;
+ TestUtil::SetPackedFields(&packed);
+ EXPECT_TRUE(packed.SerializeAsString() == destination.SerializeAsString());
+
+ // Make sure we can add extensions.
+ destination.AddExtension(unittest::packed_int32_extension, 1);
+ destination.AddExtension(unittest::packed_enum_extension,
+ protobuf_unittest::FOREIGN_BAR);
+}
+
TEST(ExtensionSetTest, IsInitialized) {
// Test that IsInitialized() returns false if required fields in nested
// extensions are missing.
@@ -418,7 +614,8 @@ TEST(ExtensionSetTest, SpaceUsedExcludingSelf) {
for (int i = 0; i < 16; ++i) { \
message.AddExtension(unittest::repeated_##type##_extension, value); \
} \
- int expected_size = sizeof(cpptype) * 16 + empty_repeated_field_size; \
+ int expected_size = sizeof(cpptype) * (16 - \
+ kMinRepeatedFieldAllocationSize) + empty_repeated_field_size; \
EXPECT_EQ(expected_size, message.SpaceUsed()) << #type; \
} while (0)
@@ -450,7 +647,8 @@ TEST(ExtensionSetTest, SpaceUsedExcludingSelf) {
for (int i = 0; i < 16; ++i) {
message.AddExtension(unittest::repeated_string_extension, value);
}
- min_expected_size += (sizeof(value) + value.size()) * 16;
+ min_expected_size += (sizeof(value) + value.size()) *
+ (16 - kMinRepeatedFieldAllocationSize);
EXPECT_LE(min_expected_size, message.SpaceUsed());
}
// Repeated messages
@@ -465,12 +663,263 @@ TEST(ExtensionSetTest, SpaceUsedExcludingSelf) {
message.AddExtension(unittest::repeated_foreign_message_extension)->
CopyFrom(prototype);
}
- min_expected_size += 16 * prototype.SpaceUsed();
+ min_expected_size +=
+ (16 - kMinRepeatedFieldAllocationSize) * prototype.SpaceUsed();
EXPECT_LE(min_expected_size, message.SpaceUsed());
}
}
-#ifdef GTEST_HAS_DEATH_TEST
+// N.B.: We do not test range-based for here because we remain C++03 compatible.
+template<typename T, typename M, typename ID>
+inline T SumAllExtensions(const M& message, ID extension, T zero) {
+ T sum = zero;
+ typename RepeatedField<T>::const_iterator iter =
+ message.GetRepeatedExtension(extension).begin();
+ typename RepeatedField<T>::const_iterator end =
+ message.GetRepeatedExtension(extension).end();
+ for (; iter != end; ++iter) {
+ sum += *iter;
+ }
+ return sum;
+}
+
+template<typename T, typename M, typename ID>
+inline void IncAllExtensions(M* message, ID extension,
+ T val) {
+ typename RepeatedField<T>::iterator iter =
+ message->MutableRepeatedExtension(extension)->begin();
+ typename RepeatedField<T>::iterator end =
+ message->MutableRepeatedExtension(extension)->end();
+ for (; iter != end; ++iter) {
+ *iter += val;
+ }
+}
+
+TEST(ExtensionSetTest, RepeatedFields) {
+ unittest::TestAllExtensions message;
+
+ // Test empty repeated-field case (b/12926163)
+ ASSERT_EQ(0, message.GetRepeatedExtension(
+ unittest::repeated_int32_extension).size());
+ ASSERT_EQ(0, message.GetRepeatedExtension(
+ unittest::repeated_nested_enum_extension).size());
+ ASSERT_EQ(0, message.GetRepeatedExtension(
+ unittest::repeated_string_extension).size());
+ ASSERT_EQ(0, message.GetRepeatedExtension(
+ unittest::repeated_nested_message_extension).size());
+
+ unittest::TestAllTypes::NestedMessage nested_message;
+ nested_message.set_bb(42);
+ unittest::TestAllTypes::NestedEnum nested_enum =
+ unittest::TestAllTypes::NestedEnum_MIN;
+
+ for (int i = 0; i < 10; ++i) {
+ message.AddExtension(unittest::repeated_int32_extension, 1);
+ message.AddExtension(unittest::repeated_int64_extension, 2);
+ message.AddExtension(unittest::repeated_uint32_extension, 3);
+ message.AddExtension(unittest::repeated_uint64_extension, 4);
+ message.AddExtension(unittest::repeated_sint32_extension, 5);
+ message.AddExtension(unittest::repeated_sint64_extension, 6);
+ message.AddExtension(unittest::repeated_fixed32_extension, 7);
+ message.AddExtension(unittest::repeated_fixed64_extension, 8);
+ message.AddExtension(unittest::repeated_sfixed32_extension, 7);
+ message.AddExtension(unittest::repeated_sfixed64_extension, 8);
+ message.AddExtension(unittest::repeated_float_extension, 9.0);
+ message.AddExtension(unittest::repeated_double_extension, 10.0);
+ message.AddExtension(unittest::repeated_bool_extension, true);
+ message.AddExtension(unittest::repeated_nested_enum_extension, nested_enum);
+ message.AddExtension(unittest::repeated_string_extension,
+ ::std::string("test"));
+ message.AddExtension(unittest::repeated_bytes_extension,
+ ::std::string("test\xFF"));
+ message.AddExtension(
+ unittest::repeated_nested_message_extension)->CopyFrom(nested_message);
+ message.AddExtension(unittest::repeated_nested_enum_extension,
+ nested_enum);
+ }
+
+ ASSERT_EQ(10, SumAllExtensions<int32>(
+ message, unittest::repeated_int32_extension, 0));
+ IncAllExtensions<int32>(
+ &message, unittest::repeated_int32_extension, 1);
+ ASSERT_EQ(20, SumAllExtensions<int32>(
+ message, unittest::repeated_int32_extension, 0));
+
+ ASSERT_EQ(20, SumAllExtensions<int64>(
+ message, unittest::repeated_int64_extension, 0));
+ IncAllExtensions<int64>(
+ &message, unittest::repeated_int64_extension, 1);
+ ASSERT_EQ(30, SumAllExtensions<int64>(
+ message, unittest::repeated_int64_extension, 0));
+
+ ASSERT_EQ(30, SumAllExtensions<uint32>(
+ message, unittest::repeated_uint32_extension, 0));
+ IncAllExtensions<uint32>(
+ &message, unittest::repeated_uint32_extension, 1);
+ ASSERT_EQ(40, SumAllExtensions<uint32>(
+ message, unittest::repeated_uint32_extension, 0));
+
+ ASSERT_EQ(40, SumAllExtensions<uint64>(
+ message, unittest::repeated_uint64_extension, 0));
+ IncAllExtensions<uint64>(
+ &message, unittest::repeated_uint64_extension, 1);
+ ASSERT_EQ(50, SumAllExtensions<uint64>(
+ message, unittest::repeated_uint64_extension, 0));
+
+ ASSERT_EQ(50, SumAllExtensions<int32>(
+ message, unittest::repeated_sint32_extension, 0));
+ IncAllExtensions<int32>(
+ &message, unittest::repeated_sint32_extension, 1);
+ ASSERT_EQ(60, SumAllExtensions<int32>(
+ message, unittest::repeated_sint32_extension, 0));
+
+ ASSERT_EQ(60, SumAllExtensions<int64>(
+ message, unittest::repeated_sint64_extension, 0));
+ IncAllExtensions<int64>(
+ &message, unittest::repeated_sint64_extension, 1);
+ ASSERT_EQ(70, SumAllExtensions<int64>(
+ message, unittest::repeated_sint64_extension, 0));
+
+ ASSERT_EQ(70, SumAllExtensions<uint32>(
+ message, unittest::repeated_fixed32_extension, 0));
+ IncAllExtensions<uint32>(
+ &message, unittest::repeated_fixed32_extension, 1);
+ ASSERT_EQ(80, SumAllExtensions<uint32>(
+ message, unittest::repeated_fixed32_extension, 0));
+
+ ASSERT_EQ(80, SumAllExtensions<uint64>(
+ message, unittest::repeated_fixed64_extension, 0));
+ IncAllExtensions<uint64>(
+ &message, unittest::repeated_fixed64_extension, 1);
+ ASSERT_EQ(90, SumAllExtensions<uint64>(
+ message, unittest::repeated_fixed64_extension, 0));
+
+ // Usually, floating-point arithmetic cannot be trusted to be exact, so it is
+ // a Bad Idea to assert equality in a test like this. However, we're dealing
+ // with integers with a small number of significant mantissa bits, so we
+ // should actually have exact precision here.
+ ASSERT_EQ(90, SumAllExtensions<float>(
+ message, unittest::repeated_float_extension, 0));
+ IncAllExtensions<float>(
+ &message, unittest::repeated_float_extension, 1);
+ ASSERT_EQ(100, SumAllExtensions<float>(
+ message, unittest::repeated_float_extension, 0));
+
+ ASSERT_EQ(100, SumAllExtensions<double>(
+ message, unittest::repeated_double_extension, 0));
+ IncAllExtensions<double>(
+ &message, unittest::repeated_double_extension, 1);
+ ASSERT_EQ(110, SumAllExtensions<double>(
+ message, unittest::repeated_double_extension, 0));
+
+ RepeatedPtrField< ::std::string>::iterator string_iter;
+ RepeatedPtrField< ::std::string>::iterator string_end;
+ for (string_iter = message.MutableRepeatedExtension(
+ unittest::repeated_string_extension)->begin(),
+ string_end = message.MutableRepeatedExtension(
+ unittest::repeated_string_extension)->end();
+ string_iter != string_end; ++string_iter) {
+ *string_iter += "test";
+ }
+ RepeatedPtrField< ::std::string>::const_iterator string_const_iter;
+ RepeatedPtrField< ::std::string>::const_iterator string_const_end;
+ for (string_const_iter = message.GetRepeatedExtension(
+ unittest::repeated_string_extension).begin(),
+ string_const_end = message.GetRepeatedExtension(
+ unittest::repeated_string_extension).end();
+ string_iter != string_end; ++string_iter) {
+ ASSERT_TRUE(*string_iter == "testtest");
+ }
+
+ RepeatedField<unittest::TestAllTypes_NestedEnum>::iterator enum_iter;
+ RepeatedField<unittest::TestAllTypes_NestedEnum>::iterator enum_end;
+ for (enum_iter = message.MutableRepeatedExtension(
+ unittest::repeated_nested_enum_extension)->begin(),
+ enum_end = message.MutableRepeatedExtension(
+ unittest::repeated_nested_enum_extension)->end();
+ enum_iter != enum_end; ++enum_iter) {
+ *enum_iter = unittest::TestAllTypes::NestedEnum_MAX;
+ }
+ RepeatedField<unittest::TestAllTypes_NestedEnum>::const_iterator
+ enum_const_iter;
+ RepeatedField<unittest::TestAllTypes_NestedEnum>::const_iterator
+ enum_const_end;
+ for (enum_const_iter = message.GetRepeatedExtension(
+ unittest::repeated_nested_enum_extension).begin(),
+ enum_const_end = message.GetRepeatedExtension(
+ unittest::repeated_nested_enum_extension).end();
+ enum_iter != enum_end; ++enum_iter) {
+ ASSERT_EQ(*enum_const_iter, unittest::TestAllTypes::NestedEnum_MAX);
+ }
+
+ RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::iterator
+ msg_iter;
+ RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::iterator
+ msg_end;
+ for (msg_iter = message.MutableRepeatedExtension(
+ unittest::repeated_nested_message_extension)->begin(),
+ msg_end = message.MutableRepeatedExtension(
+ unittest::repeated_nested_message_extension)->end();
+ msg_iter != msg_end; ++msg_iter) {
+ msg_iter->set_bb(1234);
+ }
+ RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::
+ const_iterator msg_const_iter;
+ RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::
+ const_iterator msg_const_end;
+ for (msg_const_iter = message.GetRepeatedExtension(
+ unittest::repeated_nested_message_extension).begin(),
+ msg_const_end = message.GetRepeatedExtension(
+ unittest::repeated_nested_message_extension).end();
+ msg_const_iter != msg_const_end; ++msg_const_iter) {
+ ASSERT_EQ(msg_const_iter->bb(), 1234);
+ }
+
+ // Test range-based for as well, but only if compiled as C++11.
+#if __cplusplus >= 201103L
+ // Test one primitive field.
+ for (auto& x : *message.MutableRepeatedExtension(
+ unittest::repeated_int32_extension)) {
+ x = 4321;
+ }
+ for (const auto& x : message.GetRepeatedExtension(
+ unittest::repeated_int32_extension)) {
+ ASSERT_EQ(x, 4321);
+ }
+ // Test one string field.
+ for (auto& x : *message.MutableRepeatedExtension(
+ unittest::repeated_string_extension)) {
+ x = "test_range_based_for";
+ }
+ for (const auto& x : message.GetRepeatedExtension(
+ unittest::repeated_string_extension)) {
+ ASSERT_TRUE(x == "test_range_based_for");
+ }
+ // Test one message field.
+ for (auto& x : *message.MutableRepeatedExtension(
+ unittest::repeated_nested_message_extension)) {
+ x.set_bb(4321);
+ }
+ for (const auto& x : *message.MutableRepeatedExtension(
+ unittest::repeated_nested_message_extension)) {
+ ASSERT_EQ(x.bb(), 4321);
+ }
+#endif
+}
+
+// From b/12926163
+TEST(ExtensionSetTest, AbsentExtension) {
+ unittest::TestAllExtensions message;
+ message.MutableRepeatedExtension(unittest::repeated_nested_message_extension)
+ ->Add()->set_bb(123);
+ ASSERT_EQ(1, message.ExtensionSize(
+ unittest::repeated_nested_message_extension));
+ EXPECT_EQ(
+ 123, message.GetExtension(
+ unittest::repeated_nested_message_extension, 0).bb());
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
TEST(ExtensionSetTest, InvalidEnumDeath) {
unittest::TestAllExtensions message;
@@ -480,7 +929,7 @@ TEST(ExtensionSetTest, InvalidEnumDeath) {
"IsValid");
}
-#endif // GTEST_HAS_DEATH_TEST
+#endif // PROTOBUF_HAS_DEATH_TEST
TEST(ExtensionSetTest, DynamicExtensions) {
// Test adding a dynamic extension to a compiled-in message object.
@@ -615,7 +1064,11 @@ TEST(ExtensionSetTest, DynamicExtensions) {
const Message& sub_message =
message.GetReflection()->GetMessage(message, message_extension);
const unittest::ForeignMessage* typed_sub_message =
+#ifdef GOOGLE_PROTOBUF_NO_RTTI
+ static_cast<const unittest::ForeignMessage*>(&sub_message);
+#else
dynamic_cast<const unittest::ForeignMessage*>(&sub_message);
+#endif
ASSERT_TRUE(typed_sub_message != NULL);
EXPECT_EQ(456, typed_sub_message->c());
}
diff --git a/src/google/protobuf/generated_enum_reflection.h b/src/google/protobuf/generated_enum_reflection.h
new file mode 100644
index 0000000..3852cea
--- /dev/null
+++ b/src/google/protobuf/generated_enum_reflection.h
@@ -0,0 +1,91 @@
+// 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: jasonh@google.com (Jason Hsueh)
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+// It provides reflection support for generated enums, and is included in
+// generated .pb.h files and should have minimal dependencies. The methods are
+// implemented in generated_message_reflection.cc.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
+#define GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
+
+#include <string>
+
+#include <google/protobuf/stubs/template_util.h>
+
+namespace google {
+namespace protobuf {
+ class EnumDescriptor;
+} // namespace protobuf
+
+namespace protobuf {
+
+// This type trait can be used to cause templates to only match proto2 enum
+// types.
+template <typename T> struct is_proto_enum : ::google::protobuf::internal::false_type {};
+
+// Returns the EnumDescriptor for enum type E, which must be a
+// proto-declared enum type. Code generated by the protocol compiler
+// will include specializations of this template for each enum type declared.
+template <typename E>
+const EnumDescriptor* GetEnumDescriptor();
+
+namespace internal {
+
+// Helper for EnumType_Parse functions: try to parse the string 'name' as an
+// enum name of the given type, returning true and filling in value on success,
+// or returning false and leaving value unchanged on failure.
+LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor,
+ const string& name,
+ int* value);
+
+template<typename EnumType>
+bool ParseNamedEnum(const EnumDescriptor* descriptor,
+ const string& name,
+ EnumType* value) {
+ int tmp;
+ if (!ParseNamedEnum(descriptor, name, &tmp)) return false;
+ *value = static_cast<EnumType>(tmp);
+ return true;
+}
+
+// Just a wrapper around printing the name of a value. The main point of this
+// function is not to be inlined, so that you can do this without including
+// descriptor.h.
+LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value);
+
+} // namespace internal
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index 0f065ff..536de7d 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,25 +33,26 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <algorithm>
+#include <set>
+#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/descriptor.h>
-#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/stubs/common.h>
+#define GOOGLE_PROTOBUF_HAS_ONEOF
+
namespace google {
namespace protobuf {
namespace internal {
-namespace { const string kEmptyString; }
-
int StringSpaceUsedExcludingSelf(const string& str) {
const void* start = &str;
const void* end = &str + 1;
- if (start <= str.data() && str.data() <= end) {
+ if (start <= str.data() && str.data() < end) {
// The string's data is stored inside the string object itself.
return 0;
} else {
@@ -69,9 +70,8 @@ bool ParseNamedEnum(const EnumDescriptor* descriptor,
}
const string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
- static string kEmptyString;
const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
- return (d == NULL ? kEmptyString : d->name());
+ return (d == NULL ? GetEmptyString() : d->name());
}
// ===================================================================
@@ -191,6 +191,33 @@ GeneratedMessageReflection::GeneratedMessageReflection(
message_factory_ (factory) {
}
+GeneratedMessageReflection::GeneratedMessageReflection(
+ const Descriptor* descriptor,
+ const Message* default_instance,
+ const int offsets[],
+ int has_bits_offset,
+ int unknown_fields_offset,
+ int extensions_offset,
+ const void* default_oneof_instance,
+ int oneof_case_offset,
+ const DescriptorPool* descriptor_pool,
+ MessageFactory* factory,
+ int object_size)
+ : descriptor_ (descriptor),
+ default_instance_ (default_instance),
+ default_oneof_instance_ (default_oneof_instance),
+ offsets_ (offsets),
+ has_bits_offset_ (has_bits_offset),
+ oneof_case_offset_(oneof_case_offset),
+ unknown_fields_offset_(unknown_fields_offset),
+ extensions_offset_(extensions_offset),
+ object_size_ (object_size),
+ descriptor_pool_ ((descriptor_pool == NULL) ?
+ DescriptorPool::generated_pool() :
+ descriptor_pool),
+ message_factory_ (factory) {
+}
+
GeneratedMessageReflection::~GeneratedMessageReflection() {}
const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields(
@@ -257,6 +284,9 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
break;
}
} else {
+ if (field->containing_oneof() && !HasOneofField(message, field)) {
+ continue;
+ }
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32 :
case FieldDescriptor::CPPTYPE_INT64 :
@@ -309,6 +339,195 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
return total_size;
}
+void GeneratedMessageReflection::SwapField(
+ Message* message1,
+ Message* message2,
+ const FieldDescriptor* field) const {
+ if (field->is_repeated()) {
+ switch (field->cpp_type()) {
+#define SWAP_ARRAYS(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ MutableRaw<RepeatedField<TYPE> >(message1, field)->Swap( \
+ MutableRaw<RepeatedField<TYPE> >(message2, field)); \
+ break;
+
+ SWAP_ARRAYS(INT32 , int32 );
+ SWAP_ARRAYS(INT64 , int64 );
+ SWAP_ARRAYS(UINT32, uint32);
+ SWAP_ARRAYS(UINT64, uint64);
+ SWAP_ARRAYS(FLOAT , float );
+ SWAP_ARRAYS(DOUBLE, double);
+ SWAP_ARRAYS(BOOL , bool );
+ SWAP_ARRAYS(ENUM , int );
+#undef SWAP_ARRAYS
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ MutableRaw<RepeatedPtrFieldBase>(message1, field)->Swap(
+ MutableRaw<RepeatedPtrFieldBase>(message2, field));
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
+ }
+ } else {
+ switch (field->cpp_type()) {
+#define SWAP_VALUES(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ std::swap(*MutableRaw<TYPE>(message1, field), \
+ *MutableRaw<TYPE>(message2, field)); \
+ break;
+
+ SWAP_VALUES(INT32 , int32 );
+ SWAP_VALUES(INT64 , int64 );
+ SWAP_VALUES(UINT32, uint32);
+ SWAP_VALUES(UINT64, uint64);
+ SWAP_VALUES(FLOAT , float );
+ SWAP_VALUES(DOUBLE, double);
+ SWAP_VALUES(BOOL , bool );
+ SWAP_VALUES(ENUM , int );
+#undef SWAP_VALUES
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ std::swap(*MutableRaw<Message*>(message1, field),
+ *MutableRaw<Message*>(message2, field));
+ break;
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ std::swap(*MutableRaw<string*>(message1, field),
+ *MutableRaw<string*>(message2, field));
+ break;
+ }
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
+ }
+ }
+}
+
+void GeneratedMessageReflection::SwapOneofField(
+ Message* message1,
+ Message* message2,
+ const OneofDescriptor* oneof_descriptor) const {
+ uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor);
+ uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor);
+
+ int32 temp_int32;
+ int64 temp_int64;
+ uint32 temp_uint32;
+ uint64 temp_uint64;
+ float temp_float;
+ double temp_double;
+ bool temp_bool;
+ int temp_int;
+ Message* temp_message;
+ string temp_string;
+
+ // Stores message1's oneof field to a temp variable.
+ const FieldDescriptor* field1;
+ if (oneof_case1 > 0) {
+ field1 = descriptor_->FindFieldByNumber(oneof_case1);
+ //oneof_descriptor->field(oneof_case1);
+ switch (field1->cpp_type()) {
+#define GET_TEMP_VALUE(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ temp_##TYPE = GetField<TYPE>(*message1, field1); \
+ break;
+
+ GET_TEMP_VALUE(INT32 , int32 );
+ GET_TEMP_VALUE(INT64 , int64 );
+ GET_TEMP_VALUE(UINT32, uint32);
+ GET_TEMP_VALUE(UINT64, uint64);
+ GET_TEMP_VALUE(FLOAT , float );
+ GET_TEMP_VALUE(DOUBLE, double);
+ GET_TEMP_VALUE(BOOL , bool );
+ GET_TEMP_VALUE(ENUM , int );
+#undef GET_TEMP_VALUE
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ temp_message = ReleaseMessage(message1, field1);
+ break;
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ temp_string = GetString(*message1, field1);
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
+ }
+ }
+
+ // Sets message1's oneof field from the message2's oneof field.
+ if (oneof_case2 > 0) {
+ const FieldDescriptor* field2 =
+ descriptor_->FindFieldByNumber(oneof_case2);
+ switch (field2->cpp_type()) {
+#define SET_ONEOF_VALUE1(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ SetField<TYPE>(message1, field2, GetField<TYPE>(*message2, field2)); \
+ break;
+
+ SET_ONEOF_VALUE1(INT32 , int32 );
+ SET_ONEOF_VALUE1(INT64 , int64 );
+ SET_ONEOF_VALUE1(UINT32, uint32);
+ SET_ONEOF_VALUE1(UINT64, uint64);
+ SET_ONEOF_VALUE1(FLOAT , float );
+ SET_ONEOF_VALUE1(DOUBLE, double);
+ SET_ONEOF_VALUE1(BOOL , bool );
+ SET_ONEOF_VALUE1(ENUM , int );
+#undef SET_ONEOF_VALUE1
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ SetAllocatedMessage(message1,
+ ReleaseMessage(message2, field2),
+ field2);
+ break;
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ SetString(message1, field2, GetString(*message2, field2));
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Unimplemented type: " << field2->cpp_type();
+ }
+ } else {
+ ClearOneof(message1, oneof_descriptor);
+ }
+
+ // Sets message2's oneof field from the temp variable.
+ if (oneof_case1 > 0) {
+ switch (field1->cpp_type()) {
+#define SET_ONEOF_VALUE2(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ SetField<TYPE>(message2, field1, temp_##TYPE); \
+ break;
+
+ SET_ONEOF_VALUE2(INT32 , int32 );
+ SET_ONEOF_VALUE2(INT64 , int64 );
+ SET_ONEOF_VALUE2(UINT32, uint32);
+ SET_ONEOF_VALUE2(UINT64, uint64);
+ SET_ONEOF_VALUE2(FLOAT , float );
+ SET_ONEOF_VALUE2(DOUBLE, double);
+ SET_ONEOF_VALUE2(BOOL , bool );
+ SET_ONEOF_VALUE2(ENUM , int );
+#undef SET_ONEOF_VALUE2
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ SetAllocatedMessage(message2, temp_message, field1);
+ break;
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ SetString(message2, field1, temp_string);
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
+ }
+ } else {
+ ClearOneof(message2, oneof_descriptor);
+ }
+}
+
void GeneratedMessageReflection::Swap(
Message* message1,
Message* message2) const {
@@ -324,7 +543,7 @@ void GeneratedMessageReflection::Swap(
"descriptor.";
GOOGLE_CHECK_EQ(message2->GetReflection(), this)
<< "Second argument to Swap() (of type \""
- << message1->GetDescriptor()->full_name()
+ << message2->GetDescriptor()->full_name()
<< "\") is not compatible with this reflection object (which is for type \""
<< descriptor_->full_name()
<< "\"). Note that the exact same class is required; not just the same "
@@ -340,73 +559,69 @@ void GeneratedMessageReflection::Swap(
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
- if (field->is_repeated()) {
- switch (field->cpp_type()) {
-#define SWAP_ARRAYS(CPPTYPE, TYPE) \
- case FieldDescriptor::CPPTYPE_##CPPTYPE: \
- MutableRaw<RepeatedField<TYPE> >(message1, field)->Swap( \
- MutableRaw<RepeatedField<TYPE> >(message2, field)); \
- break;
+ if (!field->containing_oneof()) {
+ SwapField(message1, message2, field);
+ }
+ }
- SWAP_ARRAYS(INT32 , int32 );
- SWAP_ARRAYS(INT64 , int64 );
- SWAP_ARRAYS(UINT32, uint32);
- SWAP_ARRAYS(UINT64, uint64);
- SWAP_ARRAYS(FLOAT , float );
- SWAP_ARRAYS(DOUBLE, double);
- SWAP_ARRAYS(BOOL , bool );
- SWAP_ARRAYS(ENUM , int );
-#undef SWAP_ARRAYS
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ SwapOneofField(message1, message2, descriptor_->oneof_decl(i));
+ }
- case FieldDescriptor::CPPTYPE_STRING:
- case FieldDescriptor::CPPTYPE_MESSAGE:
- MutableRaw<RepeatedPtrFieldBase>(message1, field)->Swap(
- MutableRaw<RepeatedPtrFieldBase>(message2, field));
- break;
+ if (extensions_offset_ != -1) {
+ MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
+ }
- default:
- GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
- }
- } else {
- switch (field->cpp_type()) {
-#define SWAP_VALUES(CPPTYPE, TYPE) \
- case FieldDescriptor::CPPTYPE_##CPPTYPE: \
- std::swap(*MutableRaw<TYPE>(message1, field), \
- *MutableRaw<TYPE>(message2, field)); \
- break;
+ MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
+}
- SWAP_VALUES(INT32 , int32 );
- SWAP_VALUES(INT64 , int64 );
- SWAP_VALUES(UINT32, uint32);
- SWAP_VALUES(UINT64, uint64);
- SWAP_VALUES(FLOAT , float );
- SWAP_VALUES(DOUBLE, double);
- SWAP_VALUES(BOOL , bool );
- SWAP_VALUES(ENUM , int );
- SWAP_VALUES(MESSAGE, Message*);
-#undef SWAP_VALUES
+void GeneratedMessageReflection::SwapFields(
+ Message* message1,
+ Message* message2,
+ const vector<const FieldDescriptor*>& fields) const {
+ if (message1 == message2) return;
- case FieldDescriptor::CPPTYPE_STRING:
- switch (field->options().ctype()) {
- default: // TODO(kenton): Support other string reps.
- case FieldOptions::STRING:
- std::swap(*MutableRaw<string*>(message1, field),
- *MutableRaw<string*>(message2, field));
- break;
- }
- break;
+ // TODO(kenton): Other Reflection methods should probably check this too.
+ GOOGLE_CHECK_EQ(message1->GetReflection(), this)
+ << "First argument to SwapFields() (of type \""
+ << message1->GetDescriptor()->full_name()
+ << "\") is not compatible with this reflection object (which is for type \""
+ << descriptor_->full_name()
+ << "\"). Note that the exact same class is required; not just the same "
+ "descriptor.";
+ GOOGLE_CHECK_EQ(message2->GetReflection(), this)
+ << "Second argument to SwapFields() (of type \""
+ << message2->GetDescriptor()->full_name()
+ << "\") is not compatible with this reflection object (which is for type \""
+ << descriptor_->full_name()
+ << "\"). Note that the exact same class is required; not just the same "
+ "descriptor.";
- default:
- GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
+ std::set<int> swapped_oneof;
+
+ for (int i = 0; i < fields.size(); i++) {
+ const FieldDescriptor* field = fields[i];
+ if (field->is_extension()) {
+ MutableExtensionSet(message1)->SwapExtension(
+ MutableExtensionSet(message2),
+ field->number());
+ } else {
+ if (field->containing_oneof()) {
+ int oneof_index = field->containing_oneof()->index();
+ // Only swap the oneof field once.
+ if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) {
+ continue;
+ }
+ swapped_oneof.insert(oneof_index);
+ SwapOneofField(message1, message2, field->containing_oneof());
+ } else {
+ // Swap has bit.
+ SwapBit(message1, message2, field);
+ // Swap field.
+ SwapField(message1, message2, field);
}
}
}
-
- if (extensions_offset_ != -1) {
- MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
- }
-
- MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
}
// -------------------------------------------------------------------
@@ -419,7 +634,11 @@ bool GeneratedMessageReflection::HasField(const Message& message,
if (field->is_extension()) {
return GetExtensionSet(message).Has(field->number());
} else {
- return HasBit(message, field);
+ if (field->containing_oneof()) {
+ return HasOneofField(message, field);
+ } else {
+ return HasBit(message, field);
+ }
}
}
@@ -463,6 +682,11 @@ void GeneratedMessageReflection::ClearField(
if (field->is_extension()) {
MutableExtensionSet(message)->ClearExtension(field->number());
} else if (!field->is_repeated()) {
+ if (field->containing_oneof()) {
+ ClearOneofField(message, field);
+ return;
+ }
+
if (HasBit(*message, field)) {
ClearBit(message, field);
@@ -591,6 +815,20 @@ void GeneratedMessageReflection::RemoveLast(
}
}
+Message* GeneratedMessageReflection::ReleaseLast(
+ Message* message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE);
+
+ if (field->is_extension()) {
+ return static_cast<Message*>(
+ MutableExtensionSet(message)->ReleaseLast(field->number()));
+ } else {
+ return MutableRaw<RepeatedPtrFieldBase>(message, field)
+ ->ReleaseLast<GenericTypeHandler<Message> >();
+ }
+}
+
void GeneratedMessageReflection::SwapElements(
Message* message,
const FieldDescriptor* field,
@@ -653,7 +891,11 @@ void GeneratedMessageReflection::ListFields(
output->push_back(field);
}
} else {
- if (HasBit(message, field)) {
+ if (field->containing_oneof()) {
+ if (HasOneofField(message, field)) {
+ output->push_back(field);
+ }
+ } else if (HasBit(message, field)) {
output->push_back(field);
}
}
@@ -757,7 +999,7 @@ string GeneratedMessageReflection::GetString(
}
GOOGLE_LOG(FATAL) << "Can't get here.";
- return kEmptyString; // Make compiler happy.
+ return GetEmptyString(); // Make compiler happy.
}
}
@@ -776,7 +1018,7 @@ const string& GeneratedMessageReflection::GetStringReference(
}
GOOGLE_LOG(FATAL) << "Can't get here.";
- return kEmptyString; // Make compiler happy.
+ return GetEmptyString(); // Make compiler happy.
}
}
@@ -792,6 +1034,10 @@ void GeneratedMessageReflection::SetString(
switch (field->options().ctype()) {
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING: {
+ if (field->containing_oneof() && !HasOneofField(*message, field)) {
+ ClearOneof(message, field->containing_oneof());
+ *MutableField<string*>(message, field) = new string;
+ }
string** ptr = MutableField<string*>(message, field);
if (*ptr == DefaultRaw<const string*>(field)) {
*ptr = new string(value);
@@ -818,7 +1064,7 @@ string GeneratedMessageReflection::GetRepeatedString(
}
GOOGLE_LOG(FATAL) << "Can't get here.";
- return kEmptyString; // Make compiler happy.
+ return GetEmptyString(); // Make compiler happy.
}
}
@@ -836,7 +1082,7 @@ const string& GeneratedMessageReflection::GetRepeatedStringReference(
}
GOOGLE_LOG(FATAL) << "Can't get here.";
- return kEmptyString; // Make compiler happy.
+ return GetEmptyString(); // Make compiler happy.
}
}
@@ -892,7 +1138,9 @@ const EnumValueDescriptor* GeneratedMessageReflection::GetEnum(
}
const EnumValueDescriptor* result =
field->enum_type()->FindValueByNumber(value);
- GOOGLE_CHECK(result != NULL);
+ GOOGLE_CHECK(result != NULL) << "Value " << value << " is not valid for field "
+ << field->full_name() << " of type "
+ << field->enum_type()->full_name() << ".";
return result;
}
@@ -922,7 +1170,9 @@ const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum(
}
const EnumValueDescriptor* result =
field->enum_type()->FindValueByNumber(value);
- GOOGLE_CHECK(result != NULL);
+ GOOGLE_CHECK(result != NULL) << "Value " << value << " is not valid for field "
+ << field->full_name() << " of type "
+ << field->enum_type()->full_name() << ".";
return result;
}
@@ -963,13 +1213,15 @@ const Message& GeneratedMessageReflection::GetMessage(
MessageFactory* factory) const {
USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
+ if (factory == NULL) factory = message_factory_;
+
if (field->is_extension()) {
return static_cast<const Message&>(
GetExtensionSet(message).GetMessage(
- field->number(), field->message_type(),
- factory == NULL ? message_factory_ : factory));
+ field->number(), field->message_type(), factory));
} else {
- const Message* result = GetRaw<const Message*>(message, field);
+ const Message* result;
+ result = GetRaw<const Message*>(message, field);
if (result == NULL) {
result = DefaultRaw<const Message*>(field);
}
@@ -980,19 +1232,91 @@ const Message& GeneratedMessageReflection::GetMessage(
Message* GeneratedMessageReflection::MutableMessage(
Message* message, const FieldDescriptor* field,
MessageFactory* factory) const {
- USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
+ if (factory == NULL) factory = message_factory_;
if (field->is_extension()) {
return static_cast<Message*>(
- MutableExtensionSet(message)->MutableMessage(field,
- factory == NULL ? message_factory_ : factory));
+ MutableExtensionSet(message)->MutableMessage(field, factory));
} else {
- Message** result = MutableField<Message*>(message, field);
- if (*result == NULL) {
+ Message* result;
+ Message** result_holder = MutableRaw<Message*>(message, field);
+
+ if (field->containing_oneof()) {
+ if (!HasOneofField(*message, field)) {
+ ClearOneof(message, field->containing_oneof());
+ result_holder = MutableField<Message*>(message, field);
+ const Message* default_message = DefaultRaw<const Message*>(field);
+ *result_holder = default_message->New();
+ }
+ } else {
+ SetBit(message, field);
+ }
+
+ if (*result_holder == NULL) {
const Message* default_message = DefaultRaw<const Message*>(field);
- *result = default_message->New();
+ *result_holder = default_message->New();
}
- return *result;
+ result = *result_holder;
+ return result;
+ }
+}
+
+void GeneratedMessageReflection::SetAllocatedMessage(
+ Message* message,
+ Message* sub_message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
+
+ if (field->is_extension()) {
+ MutableExtensionSet(message)->SetAllocatedMessage(
+ field->number(), field->type(), field, sub_message);
+ } else {
+ if (field->containing_oneof()) {
+ if (sub_message == NULL) {
+ ClearOneof(message, field->containing_oneof());
+ return;
+ }
+ ClearOneof(message, field->containing_oneof());
+ *MutableRaw<Message*>(message, field) = sub_message;
+ SetOneofCase(message, field);
+ return;
+ }
+
+ if (sub_message == NULL) {
+ ClearBit(message, field);
+ } else {
+ SetBit(message, field);
+ }
+ Message** sub_message_holder = MutableRaw<Message*>(message, field);
+ delete *sub_message_holder;
+ *sub_message_holder = sub_message;
+ }
+}
+
+Message* GeneratedMessageReflection::ReleaseMessage(
+ Message* message,
+ const FieldDescriptor* field,
+ MessageFactory* factory) const {
+ USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
+
+ if (factory == NULL) factory = message_factory_;
+
+ if (field->is_extension()) {
+ return static_cast<Message*>(
+ MutableExtensionSet(message)->ReleaseMessage(field, factory));
+ } else {
+ ClearBit(message, field);
+ if (field->containing_oneof()) {
+ if (HasOneofField(*message, field)) {
+ *MutableOneofCase(message, field->containing_oneof()) = 0;
+ } else {
+ return NULL;
+ }
+ }
+ Message** result = MutableRaw<Message*>(message, field);
+ Message* ret = *result;
+ *result = NULL;
+ return ret;
}
}
@@ -1037,7 +1361,7 @@ Message* GeneratedMessageReflection::AddMessage(
// We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
// know how to allocate one.
RepeatedPtrFieldBase* repeated =
- MutableRaw<RepeatedPtrFieldBase>(message, field);
+ MutableRaw<RepeatedPtrFieldBase>(message, field);
Message* result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
if (result == NULL) {
// We must allocate a new object.
@@ -1054,7 +1378,36 @@ Message* GeneratedMessageReflection::AddMessage(
}
}
-// -------------------------------------------------------------------
+void* GeneratedMessageReflection::MutableRawRepeatedField(
+ Message* message, const FieldDescriptor* field,
+ FieldDescriptor::CppType cpptype,
+ int ctype, const Descriptor* desc) const {
+ USAGE_CHECK_REPEATED("MutableRawRepeatedField");
+ if (field->cpp_type() != cpptype)
+ ReportReflectionUsageTypeError(descriptor_,
+ field, "MutableRawRepeatedField", cpptype);
+ if (ctype >= 0)
+ GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
+ if (desc != NULL)
+ GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
+ if (field->is_extension())
+ return MutableExtensionSet(message)->MutableRawRepeatedField(
+ field->number(), field->type(), field->is_packed(), field);
+ else
+ return reinterpret_cast<uint8*>(message) + offsets_[field->index()];
+}
+
+const FieldDescriptor* GeneratedMessageReflection::GetOneofFieldDescriptor(
+ const Message& message,
+ const OneofDescriptor* oneof_descriptor) const {
+ uint32 field_number = GetOneofCase(message, oneof_descriptor);
+ if (field_number == 0) {
+ return NULL;
+ }
+ return descriptor_->FindFieldByNumber(field_number);
+}
+
+// -----------------------------------------------------------------------------
const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
const string& name) const {
@@ -1100,23 +1453,35 @@ const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber(
template <typename Type>
inline const Type& GeneratedMessageReflection::GetRaw(
const Message& message, const FieldDescriptor* field) const {
+ if (field->containing_oneof() && !HasOneofField(message, field)) {
+ return DefaultRaw<Type>(field);
+ }
+ int index = field->containing_oneof() ?
+ descriptor_->field_count() + field->containing_oneof()->index() :
+ field->index();
const void* ptr = reinterpret_cast<const uint8*>(&message) +
- offsets_[field->index()];
+ offsets_[index];
return *reinterpret_cast<const Type*>(ptr);
}
template <typename Type>
inline Type* GeneratedMessageReflection::MutableRaw(
Message* message, const FieldDescriptor* field) const {
- void* ptr = reinterpret_cast<uint8*>(message) + offsets_[field->index()];
+ int index = field->containing_oneof() ?
+ descriptor_->field_count() + field->containing_oneof()->index() :
+ field->index();
+ void* ptr = reinterpret_cast<uint8*>(message) + offsets_[index];
return reinterpret_cast<Type*>(ptr);
}
template <typename Type>
inline const Type& GeneratedMessageReflection::DefaultRaw(
const FieldDescriptor* field) const {
- const void* ptr = reinterpret_cast<const uint8*>(default_instance_) +
- offsets_[field->index()];
+ const void* ptr = field->containing_oneof() ?
+ reinterpret_cast<const uint8*>(default_oneof_instance_) +
+ offsets_[field->index()] :
+ reinterpret_cast<const uint8*>(default_instance_) +
+ offsets_[field->index()];
return *reinterpret_cast<const Type*>(ptr);
}
@@ -1131,6 +1496,21 @@ inline uint32* GeneratedMessageReflection::MutableHasBits(
return reinterpret_cast<uint32*>(ptr);
}
+inline uint32 GeneratedMessageReflection::GetOneofCase(
+ const Message& message,
+ const OneofDescriptor* oneof_descriptor) const {
+ const void* ptr = reinterpret_cast<const uint8*>(&message)
+ + oneof_case_offset_;
+ return reinterpret_cast<const uint32*>(ptr)[oneof_descriptor->index()];
+}
+
+inline uint32* GeneratedMessageReflection::MutableOneofCase(
+ Message* message,
+ const OneofDescriptor* oneof_descriptor) const {
+ void* ptr = reinterpret_cast<uint8*>(message) + oneof_case_offset_;
+ return &(reinterpret_cast<uint32*>(ptr)[oneof_descriptor->index()]);
+}
+
inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet(
const Message& message) const {
GOOGLE_DCHECK_NE(extensions_offset_, -1);
@@ -1162,6 +1542,73 @@ inline void GeneratedMessageReflection::ClearBit(
MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32));
}
+inline void GeneratedMessageReflection::SwapBit(
+ Message* message1, Message* message2, const FieldDescriptor* field) const {
+ bool temp_has_bit = HasBit(*message1, field);
+ if (HasBit(*message2, field)) {
+ SetBit(message1, field);
+ } else {
+ ClearBit(message1, field);
+ }
+ if (temp_has_bit) {
+ SetBit(message2, field);
+ } else {
+ ClearBit(message2, field);
+ }
+}
+
+inline bool GeneratedMessageReflection::HasOneof(
+ const Message& message, const OneofDescriptor* oneof_descriptor) const {
+ return (GetOneofCase(message, oneof_descriptor) > 0);
+}
+
+inline bool GeneratedMessageReflection::HasOneofField(
+ const Message& message, const FieldDescriptor* field) const {
+ return (GetOneofCase(message, field->containing_oneof()) == field->number());
+}
+
+inline void GeneratedMessageReflection::SetOneofCase(
+ Message* message, const FieldDescriptor* field) const {
+ *MutableOneofCase(message, field->containing_oneof()) = field->number();
+}
+
+inline void GeneratedMessageReflection::ClearOneofField(
+ Message* message, const FieldDescriptor* field) const {
+ if (HasOneofField(*message, field)) {
+ ClearOneof(message, field->containing_oneof());
+ }
+}
+
+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
+ // a few oneof fields. Time/space tradeoff
+ uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
+ if (oneof_case > 0) {
+ const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_STRING: {
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ delete *MutableRaw<string*>(message, field);
+ break;
+ }
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ delete *MutableRaw<Message*>(message, field);
+ break;
+ default:
+ break;
+ }
+
+ *MutableOneofCase(message, oneof_descriptor) = 0;
+ }
+}
+
// Template implementations of basic accessors. Inline because each
// template instance is only called from one location. These are
// used for all types except messages.
@@ -1174,14 +1621,19 @@ inline const Type& GeneratedMessageReflection::GetField(
template <typename Type>
inline void GeneratedMessageReflection::SetField(
Message* message, const FieldDescriptor* field, const Type& value) const {
+ if (field->containing_oneof() && !HasOneofField(*message, field)) {
+ ClearOneof(message, field->containing_oneof());
+ }
*MutableRaw<Type>(message, field) = value;
- SetBit(message, field);
+ field->containing_oneof() ?
+ SetOneofCase(message, field) : SetBit(message, field);
}
template <typename Type>
inline Type* GeneratedMessageReflection::MutableField(
Message* message, const FieldDescriptor* field) const {
- SetBit(message, field);
+ field->containing_oneof() ?
+ SetOneofCase(message, field) : SetBit(message, field);
return MutableRaw<Type>(message, field);
}
diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h
index b545fa1..b6671ad 100644
--- a/src/google/protobuf/generated_message_reflection.h
+++ b/src/google/protobuf/generated_message_reflection.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -40,21 +40,28 @@
#include <string>
#include <vector>
+#include <google/protobuf/stubs/common.h>
+// TODO(jasonh): Remove this once the compiler change to directly include this
+// is released to components.
+#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/message.h>
#include <google/protobuf/unknown_field_set.h>
namespace google {
+namespace upb {
+namespace google_opensource {
+class GMR_Handlers;
+} // namespace google_opensource
+} // namespace upb
+
namespace protobuf {
class DescriptorPool;
- // Generated code needs these to have been forward-declared. Easier to do it
- // here than to print them inside every .pb.h file.
- class FileDescriptor;
- class EnumDescriptor;
}
namespace protobuf {
namespace internal {
+class DefaultEmptyOneof;
// Defined in this file.
class GeneratedMessageReflection;
@@ -128,6 +135,42 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
const DescriptorPool* pool,
MessageFactory* factory,
int object_size);
+
+ // Similar with the construction above. Call this construction if the
+ // message has oneof definition.
+ // Parameters:
+ // offsets: An array of ints giving the byte offsets.
+ // For each oneof field, the offset is relative to the
+ // default_oneof_instance. These can be computed at compile
+ // time using the
+ // PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET() macro.
+ // For each none oneof field, the offset is related to
+ // the start of the message object. These can be computed
+ // at compile time using the
+ // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro.
+ // Besides offsets for all fields, this array also contains
+ // offsets for oneof unions. The offset of the i-th oneof
+ // union is offsets[descriptor->field_count() + i].
+ // default_oneof_instance: The default instance of the oneofs. It is a
+ // struct holding the default value of all oneof fields
+ // for this message. It is only used to obtain pointers
+ // to default instances of oneof fields, which Get
+ // methods will return if the field is not set.
+ // oneof_case_offset: Offset in the message of an array of uint32s of
+ // size descriptor->oneof_decl_count(). Each uint32
+ // indicates what field is set for each oneof.
+ // other parameters are the same with the construction above.
+ GeneratedMessageReflection(const Descriptor* descriptor,
+ const Message* default_instance,
+ const int offsets[],
+ int has_bits_offset,
+ int unknown_fields_offset,
+ int extensions_offset,
+ const void* default_oneof_instance,
+ int oneof_case_offset,
+ const DescriptorPool* pool,
+ MessageFactory* factory,
+ int object_size);
~GeneratedMessageReflection();
// implements Reflection -------------------------------------------
@@ -140,10 +183,16 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
bool HasField(const Message& message, const FieldDescriptor* field) const;
int FieldSize(const Message& message, const FieldDescriptor* field) const;
void ClearField(Message* message, const FieldDescriptor* field) const;
+ bool HasOneof(const Message& message,
+ const OneofDescriptor* oneof_descriptor) const;
+ void ClearOneof(Message* message, const OneofDescriptor* field) const;
void RemoveLast(Message* message, const FieldDescriptor* field) const;
+ Message* ReleaseLast(Message* message, const FieldDescriptor* field) const;
void Swap(Message* message1, Message* message2) const;
+ void SwapFields(Message* message1, Message* message2,
+ const vector<const FieldDescriptor*>& fields) const;
void SwapElements(Message* message, const FieldDescriptor* field,
- int index1, int index2) const;
+ int index1, int index2) const;
void ListFields(const Message& message,
vector<const FieldDescriptor*>* output) const;
@@ -172,6 +221,11 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
const FieldDescriptor* field,
MessageFactory* factory = NULL) const;
+ const FieldDescriptor* GetOneofFieldDescriptor(
+ const Message& message,
+ const OneofDescriptor* oneof_descriptor) const;
+
+ public:
void SetInt32 (Message* message,
const FieldDescriptor* field, int32 value) const;
void SetInt64 (Message* message,
@@ -193,6 +247,11 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
const EnumValueDescriptor* value) const;
Message* MutableMessage(Message* message, const FieldDescriptor* field,
MessageFactory* factory = NULL) const;
+ void SetAllocatedMessage(Message* message,
+ Message* sub_message,
+ const FieldDescriptor* field) const;
+ Message* ReleaseMessage(Message* message, const FieldDescriptor* field,
+ MessageFactory* factory = NULL) const;
int32 GetRepeatedInt32 (const Message& message,
const FieldDescriptor* field, int index) const;
@@ -270,14 +329,25 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
+ protected:
+ virtual void* MutableRawRepeatedField(
+ Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
+ int ctype, const Descriptor* desc) const;
+
private:
friend class GeneratedMessage;
+ // To parse directly into a proto2 generated class, the class GMR_Handlers
+ // needs access to member offsets and hasbits.
+ friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers;
+
const Descriptor* descriptor_;
const Message* default_instance_;
+ const void* default_oneof_instance_;
const int* offsets_;
int has_bits_offset_;
+ int oneof_case_offset_;
int unknown_fields_offset_;
int extensions_offset_;
int object_size_;
@@ -293,10 +363,17 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
const FieldDescriptor* field) const;
template <typename Type>
inline const Type& DefaultRaw(const FieldDescriptor* field) const;
- inline const Message* GetMessagePrototype(const FieldDescriptor* field) const;
+ template <typename Type>
+ inline const Type& DefaultOneofRaw(const FieldDescriptor* field) const;
inline const uint32* GetHasBits(const Message& message) const;
inline uint32* MutableHasBits(Message* message) const;
+ inline uint32 GetOneofCase(
+ const Message& message,
+ const OneofDescriptor* oneof_descriptor) const;
+ inline uint32* MutableOneofCase(
+ Message* message,
+ const OneofDescriptor* oneof_descriptor) const;
inline const ExtensionSet& GetExtensionSet(const Message& message) const;
inline ExtensionSet* MutableExtensionSet(Message* message) const;
@@ -306,6 +383,26 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
const FieldDescriptor* field) const;
inline void ClearBit(Message* message,
const FieldDescriptor* field) const;
+ inline void SwapBit(Message* message1,
+ Message* message2,
+ const FieldDescriptor* field) const;
+
+ // This function only swaps the field. Should swap corresponding has_bit
+ // before or after using this function.
+ void SwapField(Message* message1,
+ Message* message2,
+ const FieldDescriptor* field) const;
+
+ void SwapOneofField(Message* message1,
+ Message* message2,
+ const OneofDescriptor* oneof_descriptor) const;
+
+ inline bool HasOneofField(const Message& message,
+ const FieldDescriptor* field) const;
+ inline void SetOneofCase(Message* message,
+ const FieldDescriptor* field) const;
+ inline void ClearOneofField(Message* message,
+ const FieldDescriptor* field) const;
template <typename Type>
inline const Type& GetField(const Message& message,
@@ -359,9 +456,14 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
// be confused by an unaligned pointer.
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \
static_cast<int>( \
- reinterpret_cast<const char*>( \
- &reinterpret_cast<const TYPE*>(16)->FIELD) - \
- reinterpret_cast<const char*>(16))
+ reinterpret_cast<const char*>( \
+ &reinterpret_cast<const TYPE*>(16)->FIELD) - \
+ reinterpret_cast<const char*>(16))
+
+#define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD) \
+ static_cast<int>( \
+ reinterpret_cast<const char*>(&(ONEOF->FIELD)) \
+ - reinterpret_cast<const char*>(ONEOF))
// There are some places in proto2 where dynamic_cast would be useful as an
// optimization. For example, take Message::MergeFrom(const Message& other).
@@ -395,28 +497,6 @@ inline To dynamic_cast_if_available(From from) {
#endif
}
-// Helper for EnumType_Parse functions: try to parse the string 'name' as an
-// enum name of the given type, returning true and filling in value on success,
-// or returning false and leaving value unchanged on failure.
-LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor,
- const string& name,
- int* value);
-
-template<typename EnumType>
-bool ParseNamedEnum(const EnumDescriptor* descriptor,
- const string& name,
- EnumType* value) {
- int tmp;
- if (!ParseNamedEnum(descriptor, name, &tmp)) return false;
- *value = static_cast<EnumType>(tmp);
- return true;
-}
-
-// Just a wrapper around printing the name of a value. The main point of this
-// function is not to be inlined, so that you can do this without including
-// descriptor.h.
-LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value);
-
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/generated_message_reflection_unittest.cc b/src/google/protobuf/generated_message_reflection_unittest.cc
index a03bcdb..ca1a291 100644
--- a/src/google/protobuf/generated_message_reflection_unittest.cc
+++ b/src/google/protobuf/generated_message_reflection_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -207,6 +207,111 @@ TEST(GeneratedMessageReflectionTest, SwapUnknown) {
EXPECT_EQ(1, message2.unknown_fields().field_count());
}
+TEST(GeneratedMessageReflectionTest, SwapFields) {
+ unittest::TestAllTypes message1, message2;
+ message1.set_optional_double(12.3);
+ message1.mutable_repeated_int32()->Add(10);
+ message1.mutable_repeated_int32()->Add(20);
+
+ message2.set_optional_string("hello");
+ message2.mutable_repeated_int64()->Add(30);
+
+ vector<const FieldDescriptor*> fields;
+ const Descriptor* descriptor = message1.GetDescriptor();
+ fields.push_back(descriptor->FindFieldByName("optional_double"));
+ fields.push_back(descriptor->FindFieldByName("repeated_int32"));
+ fields.push_back(descriptor->FindFieldByName("optional_string"));
+ fields.push_back(descriptor->FindFieldByName("optional_uint64"));
+
+ const Reflection* reflection = message1.GetReflection();
+ reflection->SwapFields(&message1, &message2, fields);
+
+ EXPECT_FALSE(message1.has_optional_double());
+ EXPECT_EQ(0, message1.repeated_int32_size());
+ EXPECT_TRUE(message1.has_optional_string());
+ EXPECT_EQ("hello", message1.optional_string());
+ EXPECT_EQ(0, message1.repeated_int64_size());
+ EXPECT_FALSE(message1.has_optional_uint64());
+
+ EXPECT_TRUE(message2.has_optional_double());
+ EXPECT_EQ(12.3, message2.optional_double());
+ EXPECT_EQ(2, message2.repeated_int32_size());
+ EXPECT_EQ(10, message2.repeated_int32(0));
+ EXPECT_EQ(20, message2.repeated_int32(1));
+ EXPECT_FALSE(message2.has_optional_string());
+ EXPECT_EQ(1, message2.repeated_int64_size());
+ EXPECT_FALSE(message2.has_optional_uint64());
+}
+
+TEST(GeneratedMessageReflectionTest, SwapFieldsAll) {
+ unittest::TestAllTypes message1;
+ unittest::TestAllTypes message2;
+
+ TestUtil::SetAllFields(&message2);
+
+ vector<const FieldDescriptor*> fields;
+ const Reflection* reflection = message1.GetReflection();
+ reflection->ListFields(message2, &fields);
+ reflection->SwapFields(&message1, &message2, fields);
+
+ TestUtil::ExpectAllFieldsSet(message1);
+ TestUtil::ExpectClear(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapFieldsAllExtension) {
+ unittest::TestAllExtensions message1;
+ unittest::TestAllExtensions message2;
+
+ TestUtil::SetAllExtensions(&message1);
+
+ vector<const FieldDescriptor*> fields;
+ const Reflection* reflection = message1.GetReflection();
+ reflection->ListFields(message1, &fields);
+ reflection->SwapFields(&message1, &message2, fields);
+
+ TestUtil::ExpectExtensionsClear(message1);
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapOneof) {
+ unittest::TestOneof2 message1, message2;
+ TestUtil::SetOneof1(&message1);
+
+ const Reflection* reflection = message1.GetReflection();
+ reflection->Swap(&message1, &message2);
+
+ TestUtil::ExpectOneofClear(message1);
+ TestUtil::ExpectOneofSet1(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapOneofBothSet) {
+ unittest::TestOneof2 message1, message2;
+ TestUtil::SetOneof1(&message1);
+ TestUtil::SetOneof2(&message2);
+
+ const Reflection* reflection = message1.GetReflection();
+ reflection->Swap(&message1, &message2);
+
+ TestUtil::ExpectOneofSet2(message1);
+ TestUtil::ExpectOneofSet1(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapFieldsOneof) {
+ unittest::TestOneof2 message1, message2;
+ TestUtil::SetOneof1(&message1);
+
+ vector<const FieldDescriptor*> fields;
+ const Descriptor* descriptor = message1.GetDescriptor();
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ fields.push_back(descriptor->field(i));
+ }
+ const Reflection* reflection = message1.GetReflection();
+ reflection->SwapFields(&message1, &message2, fields);
+
+ TestUtil::ExpectOneofClear(message1);
+ TestUtil::ExpectOneofSet1(message2);
+}
+
TEST(GeneratedMessageReflectionTest, RemoveLast) {
unittest::TestAllTypes message;
TestUtil::ReflectionTester reflection_tester(
@@ -225,11 +330,59 @@ TEST(GeneratedMessageReflectionTest, RemoveLastExtensions) {
unittest::TestAllExtensions::descriptor());
TestUtil::SetAllExtensions(&message);
+
reflection_tester.RemoveLastRepeatedsViaReflection(&message);
TestUtil::ExpectLastRepeatedExtensionsRemoved(message);
}
+TEST(GeneratedMessageReflectionTest, ReleaseLast) {
+ unittest::TestAllTypes message;
+ const Descriptor* descriptor = message.GetDescriptor();
+ TestUtil::ReflectionTester reflection_tester(descriptor);
+
+ TestUtil::SetAllFields(&message);
+
+ reflection_tester.ReleaseLastRepeatedsViaReflection(&message, false);
+
+ TestUtil::ExpectLastRepeatedsReleased(message);
+
+ // Now test that we actually release the right message.
+ message.Clear();
+ TestUtil::SetAllFields(&message);
+ ASSERT_EQ(2, message.repeated_foreign_message_size());
+ const protobuf_unittest::ForeignMessage* expected =
+ message.mutable_repeated_foreign_message(1);
+ scoped_ptr<Message> released(message.GetReflection()->ReleaseLast(
+ &message, descriptor->FindFieldByName("repeated_foreign_message")));
+ EXPECT_EQ(expected, released.get());
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseLastExtensions) {
+ unittest::TestAllExtensions message;
+ const Descriptor* descriptor = message.GetDescriptor();
+ TestUtil::ReflectionTester reflection_tester(descriptor);
+
+ TestUtil::SetAllExtensions(&message);
+
+ reflection_tester.ReleaseLastRepeatedsViaReflection(&message, true);
+
+ TestUtil::ExpectLastRepeatedExtensionsReleased(message);
+
+ // Now test that we actually release the right message.
+ message.Clear();
+ TestUtil::SetAllExtensions(&message);
+ ASSERT_EQ(2, message.ExtensionSize(
+ unittest::repeated_foreign_message_extension));
+ const protobuf_unittest::ForeignMessage* expected = message.MutableExtension(
+ unittest::repeated_foreign_message_extension, 1);
+ scoped_ptr<Message> released(message.GetReflection()->ReleaseLast(
+ &message, descriptor->file()->FindExtensionByName(
+ "repeated_foreign_message_extension")));
+ EXPECT_EQ(expected, released.get());
+
+}
+
TEST(GeneratedMessageReflectionTest, SwapRepeatedElements) {
unittest::TestAllTypes message;
TestUtil::ReflectionTester reflection_tester(
@@ -327,7 +480,265 @@ TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) {
FindKnownExtensionByName(extension1->full_name()) == NULL);
}
-#ifdef GTEST_HAS_DEATH_TEST
+TEST(GeneratedMessageReflectionTest, SetAllocatedMessageTest) {
+ unittest::TestAllTypes from_message1;
+ unittest::TestAllTypes from_message2;
+ unittest::TestAllTypes to_message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+ reflection_tester.SetAllFieldsViaReflection(&from_message1);
+ reflection_tester.SetAllFieldsViaReflection(&from_message2);
+
+ // Before moving fields, we expect the nested messages to be NULL.
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::IS_NULL);
+
+ // After fields are moved we should get non-NULL releases.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message1, &to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // Another move to make sure that we can SetAllocated several times.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message2, &to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the
+ // releases to be NULL again.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection(
+ &to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::IS_NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, SetAllocatedExtensionMessageTest) {
+ unittest::TestAllExtensions from_message1;
+ unittest::TestAllExtensions from_message2;
+ unittest::TestAllExtensions to_message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllExtensions::descriptor());
+ reflection_tester.SetAllFieldsViaReflection(&from_message1);
+ reflection_tester.SetAllFieldsViaReflection(&from_message2);
+
+ // Before moving fields, we expect the nested messages to be NULL.
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::IS_NULL);
+
+ // After fields are moved we should get non-NULL releases.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message1, &to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // Another move to make sure that we can SetAllocated several times.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message2, &to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the
+ // releases to be NULL again.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection(
+ &to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::IS_NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, ListFieldsOneOf) {
+ unittest::TestOneof2 message;
+ TestUtil::SetOneof1(&message);
+
+ const Reflection* reflection = message.GetReflection();
+ vector<const FieldDescriptor*> fields;
+ reflection->ListFields(message, &fields);
+ EXPECT_EQ(4, fields.size());
+}
+
+TEST(GeneratedMessageReflectionTest, Oneof) {
+ unittest::TestOneof2 message;
+ const Descriptor* descriptor = message.GetDescriptor();
+ const Reflection* reflection = message.GetReflection();
+
+ // Check default values.
+ EXPECT_EQ(0, reflection->GetInt32(
+ message, descriptor->FindFieldByName("foo_int")));
+ EXPECT_EQ("", reflection->GetString(
+ message, descriptor->FindFieldByName("foo_string")));
+ EXPECT_EQ("", reflection->GetString(
+ message, descriptor->FindFieldByName("foo_cord")));
+ EXPECT_EQ("", reflection->GetString(
+ message, descriptor->FindFieldByName("foo_string_piece")));
+ EXPECT_EQ("", reflection->GetString(
+ message, descriptor->FindFieldByName("foo_bytes")));
+ EXPECT_EQ(unittest::TestOneof2::FOO, reflection->GetEnum(
+ message, descriptor->FindFieldByName("foo_enum"))->number());
+ EXPECT_EQ(&unittest::TestOneof2::NestedMessage::default_instance(),
+ &reflection->GetMessage(
+ message, descriptor->FindFieldByName("foo_message")));
+ EXPECT_EQ(&unittest::TestOneof2::FooGroup::default_instance(),
+ &reflection->GetMessage(
+ message, descriptor->FindFieldByName("foogroup")));
+ EXPECT_NE(&unittest::TestOneof2::FooGroup::default_instance(),
+ &reflection->GetMessage(
+ message, descriptor->FindFieldByName("foo_lazy_message")));
+ EXPECT_EQ(5, reflection->GetInt32(
+ message, descriptor->FindFieldByName("bar_int")));
+ EXPECT_EQ("STRING", reflection->GetString(
+ message, descriptor->FindFieldByName("bar_string")));
+ EXPECT_EQ("CORD", reflection->GetString(
+ message, descriptor->FindFieldByName("bar_cord")));
+ EXPECT_EQ("SPIECE", reflection->GetString(
+ message, descriptor->FindFieldByName("bar_string_piece")));
+ EXPECT_EQ("BYTES", reflection->GetString(
+ message, descriptor->FindFieldByName("bar_bytes")));
+ EXPECT_EQ(unittest::TestOneof2::BAR, reflection->GetEnum(
+ message, descriptor->FindFieldByName("bar_enum"))->number());
+
+ // Check Set functions.
+ reflection->SetInt32(
+ &message, descriptor->FindFieldByName("foo_int"), 123);
+ EXPECT_EQ(123, reflection->GetInt32(
+ message, descriptor->FindFieldByName("foo_int")));
+ reflection->SetString(
+ &message, descriptor->FindFieldByName("foo_string"), "abc");
+ EXPECT_EQ("abc", reflection->GetString(
+ message, descriptor->FindFieldByName("foo_string")));
+ reflection->SetString(
+ &message, descriptor->FindFieldByName("foo_bytes"), "bytes");
+ EXPECT_EQ("bytes", reflection->GetString(
+ message, descriptor->FindFieldByName("foo_bytes")));
+ reflection->SetString(
+ &message, descriptor->FindFieldByName("bar_cord"), "change_cord");
+ EXPECT_EQ("change_cord", reflection->GetString(
+ message, descriptor->FindFieldByName("bar_cord")));
+ reflection->SetString(
+ &message, descriptor->FindFieldByName("bar_string_piece"),
+ "change_spiece");
+ EXPECT_EQ("change_spiece", reflection->GetString(
+ message, descriptor->FindFieldByName("bar_string_piece")));
+}
+
+TEST(GeneratedMessageReflectionTest, SetAllocatedOneofMessageTest) {
+ unittest::TestOneof2 from_message1;
+ unittest::TestOneof2 from_message2;
+ unittest::TestOneof2 to_message;
+ const Descriptor* descriptor = unittest::TestOneof2::descriptor();
+ const Reflection* reflection = to_message.GetReflection();
+
+ Message* released = reflection->ReleaseMessage(
+ &to_message, descriptor->FindFieldByName("foo_lazy_message"));
+ EXPECT_TRUE(released == NULL);
+ released = reflection->ReleaseMessage(
+ &to_message, descriptor->FindFieldByName("foo_message"));
+ EXPECT_TRUE(released == NULL);
+
+ TestUtil::ReflectionTester::SetOneofViaReflection(&from_message1);
+ TestUtil::ReflectionTester::ExpectOneofSetViaReflection(from_message1);
+
+ TestUtil::ReflectionTester::
+ SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message1, &to_message);
+ const Message& sub_message = reflection->GetMessage(
+ to_message, descriptor->FindFieldByName("foo_lazy_message"));
+ released = reflection->ReleaseMessage(
+ &to_message, descriptor->FindFieldByName("foo_lazy_message"));
+ EXPECT_TRUE(released != NULL);
+ EXPECT_EQ(&sub_message, released);
+ delete released;
+
+ TestUtil::ReflectionTester::SetOneofViaReflection(&from_message2);
+
+ reflection->MutableMessage(
+ &from_message2, descriptor->FindFieldByName("foo_message"));
+
+ TestUtil::ReflectionTester::
+ SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message2, &to_message);
+
+ const Message& sub_message2 = reflection->GetMessage(
+ to_message, descriptor->FindFieldByName("foo_message"));
+ released = reflection->ReleaseMessage(
+ &to_message, descriptor->FindFieldByName("foo_message"));
+ EXPECT_TRUE(released != NULL);
+ EXPECT_EQ(&sub_message2, released);
+ delete released;
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseMessageTest) {
+ unittest::TestAllTypes message;
+ 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 a different code path for setting after releasing.
+ TestUtil::SetAllFields(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseExtensionMessageTest) {
+ unittest::TestAllExtensions message;
+ 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 a different code path for setting after releasing.
+ TestUtil::SetAllExtensions(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseOneofMessageTest) {
+ unittest::TestOneof2 message;
+ TestUtil::ReflectionTester::SetOneofViaReflection(&message);
+
+ const Descriptor* descriptor = unittest::TestOneof2::descriptor();
+ const Reflection* reflection = message.GetReflection();
+ const Message& sub_message = reflection->GetMessage(
+ message, descriptor->FindFieldByName("foo_lazy_message"));
+ Message* released = reflection->ReleaseMessage(
+ &message, descriptor->FindFieldByName("foo_lazy_message"));
+
+ EXPECT_TRUE(released != NULL);
+ EXPECT_EQ(&sub_message, released);
+ delete released;
+
+ released = reflection->ReleaseMessage(
+ &message, descriptor->FindFieldByName("foo_lazy_message"));
+ EXPECT_TRUE(released == NULL);
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
TEST(GeneratedMessageReflectionTest, UsageErrors) {
unittest::TestAllTypes message;
@@ -376,7 +787,7 @@ TEST(GeneratedMessageReflectionTest, UsageErrors) {
#undef f
}
-#endif // GTEST_HAS_DEATH_TEST
+#endif // PROTOBUF_HAS_DEATH_TEST
} // namespace
diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc
index 7ac015d..0c20d81 100644
--- a/src/google/protobuf/generated_message_util.cc
+++ b/src/google/protobuf/generated_message_util.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -47,6 +47,18 @@ double NaN() {
return std::numeric_limits<double>::quiet_NaN();
}
+const ::std::string* empty_string_;
+GOOGLE_PROTOBUF_DECLARE_ONCE(empty_string_once_init_);
+
+void DeleteEmptyString() {
+ delete empty_string_;
+}
+
+void InitEmptyString() {
+ empty_string_ = new string;
+ OnShutdown(&DeleteEmptyString);
+}
+
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h
index daa16f7..678f92a 100644
--- a/src/google/protobuf/generated_message_util.h
+++ b/src/google/protobuf/generated_message_util.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -38,19 +38,18 @@
#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
-#include <google/protobuf/stubs/common.h>
+#include <assert.h>
+#include <string>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/stubs/common.h>
namespace google {
-namespace protobuf {
- namespace io {
- class CodedInputStream; // coded_stream.h
- }
-}
namespace protobuf {
namespace internal {
+
// Annotation for the compiler to emit a deprecation message if a field marked
// with option 'deprecated=true' is used in the code, or for other things in
// generated code which are deprecated.
@@ -58,17 +57,54 @@ namespace internal {
// For internal use in the pb.cc files, deprecation warnings are suppressed
// there.
#undef DEPRECATED_PROTOBUF_FIELD
-#if !defined(INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION)
-# define PROTOBUF_DEPRECATED GOOGLE_ATTRIBUTE_DEPRECATED
-#else
-# define PROTOBUF_DEPRECATED
-#endif
+#define PROTOBUF_DEPRECATED
// Constants for special floating point values.
LIBPROTOBUF_EXPORT double Infinity();
LIBPROTOBUF_EXPORT double NaN();
+// TODO(jieluo): Change to template. We have tried to use template,
+// but it causes net/rpc/python:rpcutil_test fail (the empty string will
+// init twice). It may related to swig. Change to template after we
+// found the solution.
+
+// Default empty string object. Don't use the pointer directly. Instead, call
+// GetEmptyString() to get the reference.
+LIBPROTOBUF_EXPORT extern const ::std::string* empty_string_;
+LIBPROTOBUF_EXPORT extern ProtobufOnceType empty_string_once_init_;
+LIBPROTOBUF_EXPORT void InitEmptyString();
+
+
+LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyStringAlreadyInited() {
+ assert(empty_string_ != NULL);
+ return *empty_string_;
+}
+LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() {
+ ::google::protobuf::GoogleOnceInit(&empty_string_once_init_, &InitEmptyString);
+ return GetEmptyStringAlreadyInited();
+}
+
+// Defined in generated_message_reflection.cc -- not actually part of the lite
+// library.
+//
+// TODO(jasonh): The various callers get this declaration from a variety of
+// places: probably in most cases repeated_field.h. Clean these up so they all
+// get the declaration from this file.
+LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str);
+
+
+// True if IsInitialized() is true for all elements of t. Type is expected
+// to be a RepeatedPtrField<some message type>. It's useful to have this
+// helper here to keep the protobuf compiler from ever having to emit loops in
+// IsInitialized() methods. We want the C++ compiler to inline this or not
+// as it sees fit.
+template <class Type> bool AllAreInitialized(const Type& t) {
+ for (int i = t.size(); --i >= 0; ) {
+ if (!t.Get(i).IsInitialized()) return false;
+ }
+ return true;
+}
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc
index 6a91a13..5344975 100644
--- a/src/google/protobuf/io/coded_stream.cc
+++ b/src/google/protobuf/io/coded_stream.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -43,7 +43,7 @@
#include <limits.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
@@ -56,10 +56,36 @@ static const int kMaxVarintBytes = 10;
static const int kMaxVarint32Bytes = 5;
+inline bool NextNonEmpty(ZeroCopyInputStream* input,
+ const void** data, int* size) {
+ bool success;
+ do {
+ success = input->Next(data, size);
+ } while (success && *size == 0);
+ return success;
+}
+
} // namespace
// CodedInputStream ==================================================
+CodedInputStream::~CodedInputStream() {
+ if (input_ != NULL) {
+ BackUpInputToCurrentPosition();
+ }
+
+ if (total_bytes_warning_threshold_ == -2) {
+ GOOGLE_LOG(WARNING) << "The total number of bytes read was " << total_bytes_read_;
+ }
+}
+
+// Static.
+int CodedInputStream::default_recursion_limit_ = 100;
+
+
+void CodedOutputStream::EnableAliasing(bool enabled) {
+ aliasing_enabled_ = enabled && output_->AllowsAliasing();
+}
void CodedInputStream::BackUpInputToCurrentPosition() {
int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_;
@@ -89,8 +115,7 @@ inline void CodedInputStream::RecomputeBufferLimits() {
CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) {
// Current position relative to the beginning of the stream.
- int current_position = total_bytes_read_ -
- (BufferSize() + buffer_size_after_limit_);
+ int current_position = CurrentPosition();
Limit old_limit = current_limit_;
@@ -124,10 +149,9 @@ void CodedInputStream::PopLimit(Limit limit) {
legitimate_message_end_ = false;
}
-int CodedInputStream::BytesUntilLimit() {
+int CodedInputStream::BytesUntilLimit() const {
if (current_limit_ == INT_MAX) return -1;
- int current_position = total_bytes_read_ -
- (BufferSize() + buffer_size_after_limit_);
+ int current_position = CurrentPosition();
return current_limit_ - current_position;
}
@@ -136,13 +160,22 @@ void CodedInputStream::SetTotalBytesLimit(
int total_bytes_limit, int warning_threshold) {
// Make sure the limit isn't already past, since this could confuse other
// code.
- int current_position = total_bytes_read_ -
- (BufferSize() + buffer_size_after_limit_);
+ int current_position = CurrentPosition();
total_bytes_limit_ = max(current_position, total_bytes_limit);
- total_bytes_warning_threshold_ = warning_threshold;
+ if (warning_threshold >= 0) {
+ total_bytes_warning_threshold_ = warning_threshold;
+ } else {
+ // warning_threshold is negative
+ total_bytes_warning_threshold_ = -1;
+ }
RecomputeBufferLimits();
}
+int CodedInputStream::BytesUntilTotalBytesLimit() const {
+ if (total_bytes_limit_ == INT_MAX) return -1;
+ return total_bytes_limit_ - CurrentPosition();
+}
+
void CodedInputStream::PrintTotalBytesLimitError() {
GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too "
"big (more than " << total_bytes_limit_
@@ -223,6 +256,14 @@ bool CodedInputStream::ReadStringFallback(string* buffer, int size) {
buffer->clear();
}
+ int closest_limit = 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) {
+ buffer->reserve(size);
+ }
+ }
+
int current_buffer_size;
while ((current_buffer_size = BufferSize()) < size) {
// Some STL implementations "helpfully" crash on buffer->append(NULL, 0).
@@ -289,11 +330,16 @@ inline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) {
uint32 b;
uint32 result;
- b = *(ptr++); result = (b & 0x7F) ; if (!(b & 0x80)) goto done;
- b = *(ptr++); result |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
- b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
- b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
- b = *(ptr++); result |= b << 28; if (!(b & 0x80)) goto done;
+ b = *(ptr++); result = b ; if (!(b & 0x80)) goto done;
+ result -= 0x80;
+ b = *(ptr++); result += b << 7; if (!(b & 0x80)) goto done;
+ result -= 0x80 << 7;
+ b = *(ptr++); result += b << 14; if (!(b & 0x80)) goto done;
+ result -= 0x80 << 14;
+ b = *(ptr++); result += b << 21; if (!(b & 0x80)) goto done;
+ result -= 0x80 << 21;
+ b = *(ptr++); result += b << 28; if (!(b & 0x80)) goto done;
+ // "result -= 0x80 << 28" is irrevelant.
// If the input is larger than 32 bits, we still need to read it all
// and discard the high-order bits.
@@ -323,8 +369,8 @@ bool CodedInputStream::ReadVarint32Slow(uint32* value) {
bool CodedInputStream::ReadVarint32Fallback(uint32* value) {
if (BufferSize() >= kMaxVarintBytes ||
- // Optimization: If the varint ends at exactly the end of the buffer,
- // we can detect that and still use the fast path.
+ // 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))) {
const uint8* end = ReadVarint32FromArray(buffer_, value);
if (end == NULL) return false;
@@ -359,16 +405,17 @@ uint32 CodedInputStream::ReadTagSlow() {
// For the slow path, just do a 64-bit read. Try to optimize for one-byte tags
// again, since we have now refreshed the buffer.
- uint64 result;
+ uint64 result = 0;
if (!ReadVarint64(&result)) return 0;
return static_cast<uint32>(result);
}
uint32 CodedInputStream::ReadTagFallback() {
- if (BufferSize() >= kMaxVarintBytes ||
- // Optimization: If the varint ends at exactly the end of the buffer,
- // we can detect that and still use the fast path.
- (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
+ const int buf_size = BufferSize();
+ if (buf_size >= kMaxVarintBytes ||
+ // Optimization: We're also safe if the buffer is non-empty and it ends
+ // with a byte that would terminate a varint.
+ (buf_size > 0 && !(buffer_end_[-1] & 0x80))) {
uint32 tag;
const uint8* end = ReadVarint32FromArray(buffer_, &tag);
if (end == NULL) {
@@ -379,7 +426,9 @@ uint32 CodedInputStream::ReadTagFallback() {
} else {
// We are commonly at a limit when attempting to read tags. Try to quickly
// detect this case without making another function call.
- if (buffer_ == buffer_end_ && buffer_size_after_limit_ > 0 &&
+ if ((buf_size == 0) &&
+ ((buffer_size_after_limit_ > 0) ||
+ (total_bytes_read_ == current_limit_)) &&
// Make sure that the limit we hit is not total_bytes_limit_, since
// in that case we still need to call Refresh() so that it prints an
// error.
@@ -417,8 +466,8 @@ bool CodedInputStream::ReadVarint64Slow(uint64* value) {
bool CodedInputStream::ReadVarint64Fallback(uint64* value) {
if (BufferSize() >= kMaxVarintBytes ||
- // Optimization: If the varint ends at exactly the end of the buffer,
- // we can detect that and still use the fast path.
+ // 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.
@@ -430,20 +479,30 @@ bool CodedInputStream::ReadVarint64Fallback(uint64* value) {
// processors.
uint32 part0 = 0, part1 = 0, part2 = 0;
- b = *(ptr++); part0 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
- b = *(ptr++); part0 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
- b = *(ptr++); part0 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
- b = *(ptr++); part0 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
- b = *(ptr++); part1 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
- b = *(ptr++); part1 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
- b = *(ptr++); part1 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
- b = *(ptr++); part1 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
- b = *(ptr++); part2 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
- b = *(ptr++); part2 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
+ 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 NULL;
+ return false;
done:
Advance(ptr - buffer_);
@@ -483,13 +542,13 @@ bool CodedInputStream::Refresh() {
"CodedInputStream::SetTotalBytesLimit() in "
"google/protobuf/io/coded_stream.h.";
- // Don't warn again for this stream.
- total_bytes_warning_threshold_ = -1;
+ // Don't warn again for this stream, and print total size at the end.
+ total_bytes_warning_threshold_ = -2;
}
const void* void_buffer;
int buffer_size;
- if (input_->Next(&void_buffer, &buffer_size)) {
+ if (NextNonEmpty(input_, &void_buffer, &buffer_size)) {
buffer_ = reinterpret_cast<const uint8*>(void_buffer);
buffer_end_ = buffer_ + buffer_size;
GOOGLE_CHECK_GE(buffer_size, 0);
@@ -528,7 +587,8 @@ CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
buffer_(NULL),
buffer_size_(0),
total_bytes_(0),
- had_error_(false) {
+ had_error_(false),
+ aliasing_enabled_(false) {
// Eagerly Refresh() so buffer space is immediately available.
Refresh();
// The Refresh() may have failed. If the client doesn't write any data,
@@ -582,6 +642,23 @@ uint8* CodedOutputStream::WriteRawToArray(
}
+void CodedOutputStream::WriteAliasedRaw(const void* data, int size) {
+ if (size < buffer_size_
+ ) {
+ WriteRaw(data, size);
+ } else {
+ if (buffer_size_ > 0) {
+ output_->BackUp(buffer_size_);
+ total_bytes_ -= buffer_size_;
+ buffer_ = NULL;
+ buffer_size_ = 0;
+ }
+
+ total_bytes_ += size;
+ had_error_ |= !output_->WriteAliasedRaw(data, size);
+ }
+}
+
void CodedOutputStream::WriteLittleEndian32(uint32 value) {
uint8 bytes[sizeof(value)];
@@ -825,6 +902,13 @@ int CodedOutputStream::VarintSize64(uint64 value) {
}
}
+uint8* CodedOutputStream::WriteStringWithSizeToArray(const string& str,
+ uint8* target) {
+ GOOGLE_DCHECK_LE(str.size(), kuint32max);
+ target = WriteVarint32ToArray(str.size(), target);
+ return WriteStringToArray(str, target);
+}
+
} // namespace io
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index e5f6161..81fabb1 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -110,14 +110,27 @@
#define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
#include <string>
-#ifndef _MSC_VER
-#include <sys/param.h>
-#endif // !_MSC_VER
+#ifdef _MSC_VER
+ #if defined(_M_IX86) && \
+ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+ #define PROTOBUF_LITTLE_ENDIAN 1
+ #endif
+ #if _MSC_VER >= 1300
+ // 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)
+ #endif
+#else
+ #include <sys/param.h> // __BYTE_ORDER
+ #if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN && \
+ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+ #define PROTOBUF_LITTLE_ENDIAN 1
+ #endif
+#endif
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/common.h> // for GOOGLE_PREDICT_TRUE macro
-namespace google {
+namespace google {
namespace protobuf {
class DescriptorPool;
@@ -157,6 +170,9 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// successfully and the stream's byte limit.
~CodedInputStream();
+ // Return true if this CodedInputStream reads from a flat array instead of
+ // a ZeroCopyInputStream.
+ inline bool IsFlat() const;
// Skips a number of bytes. Returns false if an underlying read error
// occurs.
@@ -217,11 +233,22 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// 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().
- // Always inline because this is only called in once place per parse loop
+ // Always inline because this is only called in one place per parse loop
// but it is called for every iteration of said loop, so it should be fast.
// GCC doesn't want to inline this by default.
uint32 ReadTag() GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ // This usually a faster alternative to ReadTag() when cutoff is a manifest
+ // constant. It does particularly well for cutoff >= 127. The first part
+ // of the return value is the tag that was read, though it can also be 0 in
+ // the cases where ReadTag() would return 0. If the second part is true
+ // then the tag is known to be in [0, cutoff]. If not, the tag either is
+ // above cutoff or is 0. (There's intentional wiggle room when tag is 0,
+ // because that can arise in several ways, and for best performance we want
+ // to avoid an extra "is tag == 0?" check here.)
+ inline std::pair<uint32, bool> ReadTagWithCutoff(uint32 cutoff)
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
// Usually returns true if calling ReadVarint32() now would produce the given
// value. Will always return false if ReadVarint32() would not return the
// given value. If ExpectTag() returns true, it also advances past
@@ -248,8 +275,8 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// zero, and ConsumedEntireMessage() will return true.
bool ExpectAtEnd();
- // If the last call to ReadTag() returned the given value, returns true.
- // Otherwise, returns false;
+ // If the last call to ReadTag() or ReadTagWithCutoff() returned the
+ // given value, returns true. Otherwise, returns false;
//
// This is needed because parsers for some types of embedded messages
// (with field type TYPE_GROUP) don't actually know that they've reached the
@@ -298,7 +325,10 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// Returns the number of bytes left until the nearest limit on the
// stack is hit, or -1 if no limits are in place.
- int BytesUntilLimit();
+ int BytesUntilLimit() const;
+
+ // Returns current position relative to the beginning of the input stream.
+ int CurrentPosition() const;
// Total Bytes Limit -----------------------------------------------
// To prevent malicious users from sending excessively large messages
@@ -314,8 +344,9 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// cause integer overflows is 512MB. The default limit is 64MB. Apps
// should set shorter limits if possible. If warning_threshold is not -1,
// a warning will be printed to stderr after warning_threshold bytes are
- // read. An error will always be printed to stderr if the limit is
- // reached.
+ // read. For backwards compatibility all negative values get squashed to -1,
+ // as other negative values might have special internal meanings.
+ // An error will always be printed to stderr if the limit is reached.
//
// This is unrelated to PushLimit()/PopLimit().
//
@@ -336,15 +367,20 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// something unusual.
void SetTotalBytesLimit(int total_bytes_limit, int warning_threshold);
+ // The Total Bytes Limit minus the Current Position, or -1 if there
+ // is no Total Bytes Limit.
+ int BytesUntilTotalBytesLimit() const;
+
// Recursion Limit -------------------------------------------------
// To prevent corrupt or malicious messages from causing stack overflows,
// we must keep track of the depth of recursion when parsing embedded
// messages and groups. CodedInputStream keeps track of this because it
// is the only object that is passed down the stack during parsing.
- // Sets the maximum recursion depth. The default is 64.
+ // Sets the maximum recursion depth. The default is 100.
void SetRecursionLimit(int limit);
+
// Increments the current recursion depth. Returns true if the depth is
// under the limit, false if it has gone over.
bool IncrementRecursionDepth();
@@ -420,7 +456,8 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
//
// Note that this feature is ignored when parsing "lite" messages as they do
// not have descriptors.
- void SetExtensionRegistry(DescriptorPool* pool, MessageFactory* factory);
+ void SetExtensionRegistry(const DescriptorPool* pool,
+ MessageFactory* factory);
// Get the DescriptorPool set via SetExtensionRegistry(), or NULL if no pool
// has been provided.
@@ -444,7 +481,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
int overflow_bytes_;
// LastTagWas() stuff.
- uint32 last_tag_; // result of last ReadTag().
+ uint32 last_tag_; // result of last ReadTag() or ReadTagWithCutoff().
// This is set true by ReadTag{Fallback/Slow}() if it is called when exactly
// at EOF, or by ExpectAtEnd() when it returns true. This happens when we
@@ -469,6 +506,11 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// Maximum number of bytes to read, period. This is unrelated to
// current_limit_. Set using SetTotalBytesLimit().
int total_bytes_limit_;
+
+ // If positive/0: Limit for bytes read after which a warning due to size
+ // should be logged.
+ // If -1: Printing of warning disabled. Can be set by client.
+ // If -2: Internal: Limit has been reached, print full size when destructing.
int total_bytes_warning_threshold_;
// Current recursion depth, controlled by IncrementRecursionDepth() and
@@ -521,12 +563,13 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
bool ReadStringFallback(string* buffer, int size);
// Return the size of the buffer.
- uint32 BufferSize() const;
+ int BufferSize() const;
static const int kDefaultTotalBytesLimit = 64 << 20; // 64MB
static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB
- static const int kDefaultRecursionLimit = 64;
+
+ static int default_recursion_limit_; // 100 by default.
};
// Class which encodes and writes binary data which is composed of varint-
@@ -554,7 +597,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// char text[] = "Hello world!";
//
// int coded_size = sizeof(magic_number) +
-// CodedOutputStream::Varint32Size(strlen(text)) +
+// CodedOutputStream::VarintSize32(strlen(text)) +
// strlen(text);
//
// uint8* buffer =
@@ -610,6 +653,9 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
// Write raw bytes, copying them from the given buffer.
void WriteRaw(const void* buffer, int size);
+ // Like WriteRaw() but will try to write aliased data if aliasing is
+ // turned on.
+ void WriteRawMaybeAliased(const void* data, int size);
// Like WriteRaw() but writing directly to the target array.
// This is _not_ inlined, as the compiler often optimizes memcpy into inline
// copy loops. Since this gets called by every field with string or bytes
@@ -621,8 +667,21 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
void WriteString(const string& str);
// Like WriteString() but writing directly to the target array.
static uint8* WriteStringToArray(const string& str, uint8* target);
+ // Write the varint-encoded size of str followed by str.
+ static uint8* WriteStringWithSizeToArray(const string& str, uint8* target);
+ // Instructs the CodedOutputStream to allow the underlying
+ // ZeroCopyOutputStream to hold pointers to the original structure instead of
+ // copying, if it supports it (i.e. output->AllowsAliasing() is true). If the
+ // underlying stream does not support aliasing, then enabling it has no
+ // affect. For now, this only affects the behavior of
+ // WriteRawMaybeAliased().
+ //
+ // NOTE: It is caller's responsibility to ensure that the chunk of memory
+ // remains live until all of the data has been consumed from the stream.
+ void EnableAliasing(bool enabled);
+
// Write a 32-bit little-endian integer.
void WriteLittleEndian32(uint32 value);
// Like WriteLittleEndian32() but writing directly to the target array.
@@ -667,6 +726,21 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
// If negative, 10 bytes. Otheriwse, same as VarintSize32().
static int VarintSize32SignExtended(int32 value);
+ // Compile-time equivalent of VarintSize32().
+ template <uint32 Value>
+ struct StaticVarintSize32 {
+ static const int value =
+ (Value < (1 << 7))
+ ? 1
+ : (Value < (1 << 14))
+ ? 2
+ : (Value < (1 << 21))
+ ? 3
+ : (Value < (1 << 28))
+ ? 4
+ : 5;
+ };
+
// Returns the total number of bytes written since this object was created.
inline int ByteCount() const;
@@ -682,6 +756,7 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
int buffer_size_;
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().
// Advance the buffer by a given number of bytes.
void Advance(int amount);
@@ -690,6 +765,10 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
// Advance(buffer_size_).
bool Refresh();
+ // Like WriteRaw() but may avoid copying if the underlying
+ // ZeroCopyOutputStream supports it.
+ void WriteAliasedRaw(const void* buffer, int size);
+
static uint8* WriteVarint32FallbackToArray(uint32 value, uint8* target);
// Always-inlined versions of WriteVarint* functions so that code can be
@@ -735,8 +814,7 @@ inline bool CodedInputStream::ReadVarint64(uint64* value) {
inline const uint8* CodedInputStream::ReadLittleEndian32FromArray(
const uint8* buffer,
uint32* value) {
-#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \
- defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN
+#if defined(PROTOBUF_LITTLE_ENDIAN)
memcpy(value, buffer, sizeof(*value));
return buffer + sizeof(*value);
#else
@@ -751,8 +829,7 @@ inline const uint8* CodedInputStream::ReadLittleEndian32FromArray(
inline const uint8* CodedInputStream::ReadLittleEndian64FromArray(
const uint8* buffer,
uint64* value) {
-#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \
- defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN
+#if defined(PROTOBUF_LITTLE_ENDIAN)
memcpy(value, buffer, sizeof(*value));
return buffer + sizeof(*value);
#else
@@ -771,9 +848,8 @@ inline const uint8* CodedInputStream::ReadLittleEndian64FromArray(
}
inline bool CodedInputStream::ReadLittleEndian32(uint32* value) {
-#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \
- defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN
- if (GOOGLE_PREDICT_TRUE(BufferSize() >= sizeof(*value))) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+ if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
memcpy(value, buffer_, sizeof(*value));
Advance(sizeof(*value));
return true;
@@ -786,9 +862,8 @@ inline bool CodedInputStream::ReadLittleEndian32(uint32* value) {
}
inline bool CodedInputStream::ReadLittleEndian64(uint64* value) {
-#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \
- defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN
- if (GOOGLE_PREDICT_TRUE(BufferSize() >= sizeof(*value))) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+ if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
memcpy(value, buffer_, sizeof(*value));
Advance(sizeof(*value));
return true;
@@ -811,6 +886,45 @@ inline uint32 CodedInputStream::ReadTag() {
}
}
+inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoff(
+ uint32 cutoff) {
+ // In performance-sensitive code we can expect cutoff to be a compile-time
+ // constant, and things like "cutoff >= kMax1ByteVarint" to be evaluated at
+ // compile time.
+ if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) {
+ // Hot case: buffer_ non_empty, buffer_[0] in [1, 128).
+ // TODO(gpike): Is it worth rearranging this? E.g., if the number of fields
+ // is large enough then is it better to check for the two-byte case first?
+ if (static_cast<int8>(buffer_[0]) > 0) {
+ const uint32 kMax1ByteVarint = 0x7f;
+ uint32 tag = last_tag_ = buffer_[0];
+ Advance(1);
+ return make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff);
+ }
+ // Other hot case: cutoff >= 0x80, buffer_ has at least two bytes available,
+ // and tag is two bytes. The latter is tested by bitwise-and-not of the
+ // first byte and the second byte.
+ if (cutoff >= 0x80 &&
+ GOOGLE_PREDICT_TRUE(buffer_ + 1 < buffer_end_) &&
+ GOOGLE_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) {
+ const uint32 kMax2ByteVarint = (0x7f << 7) + 0x7f;
+ uint32 tag = last_tag_ = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80);
+ Advance(2);
+ // It might make sense to test for tag == 0 now, but it is so rare that
+ // that we don't bother. A varint-encoded 0 should be one byte unless
+ // the encoder lost its mind. The second part of the return value of
+ // this function is allowed to be either true or false if the tag is 0,
+ // so we don't have to check for tag == 0. We may need to check whether
+ // it exceeds cutoff.
+ bool at_or_below_cutoff = cutoff >= kMax2ByteVarint || tag <= cutoff;
+ return make_pair(tag, at_or_below_cutoff);
+ }
+ }
+ // Slow path
+ last_tag_ = ReadTagFallback();
+ return make_pair(last_tag_, static_cast<uint32>(last_tag_ - 1) < cutoff);
+}
+
inline bool CodedInputStream::LastTagWas(uint32 expected) {
return last_tag_ == expected;
}
@@ -867,7 +981,9 @@ inline bool CodedInputStream::ExpectAtEnd() {
// If we are at a limit we know no more bytes can be read. Otherwise, it's
// hard to say without calling Refresh(), and we'd rather not do that.
- if (buffer_ == buffer_end_ && buffer_size_after_limit_ != 0) {
+ if (buffer_ == buffer_end_ &&
+ ((buffer_size_after_limit_ != 0) ||
+ (total_bytes_read_ == current_limit_))) {
last_tag_ = 0; // Pretend we called ReadTag()...
legitimate_message_end_ = true; // ... and it hit EOF.
return true;
@@ -876,6 +992,10 @@ inline bool CodedInputStream::ExpectAtEnd() {
}
}
+inline int CodedInputStream::CurrentPosition() const {
+ return total_bytes_read_ - (BufferSize() + buffer_size_after_limit_);
+}
+
inline uint8* CodedOutputStream::GetDirectBufferForNBytesAndAdvance(int size) {
if (buffer_size_ < size) {
return NULL;
@@ -915,8 +1035,7 @@ inline uint8* CodedOutputStream::WriteVarint32SignExtendedToArray(
inline uint8* CodedOutputStream::WriteLittleEndian32ToArray(uint32 value,
uint8* target) {
-#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \
- defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN
+#if defined(PROTOBUF_LITTLE_ENDIAN)
memcpy(target, &value, sizeof(value));
#else
target[0] = static_cast<uint8>(value);
@@ -929,8 +1048,7 @@ inline uint8* CodedOutputStream::WriteLittleEndian32ToArray(uint32 value,
inline uint8* CodedOutputStream::WriteLittleEndian64ToArray(uint64 value,
uint8* target) {
-#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \
- defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN
+#if defined(PROTOBUF_LITTLE_ENDIAN)
memcpy(target, &value, sizeof(value));
#else
uint32 part0 = static_cast<uint32>(value);
@@ -983,12 +1101,21 @@ inline int CodedOutputStream::VarintSize32SignExtended(int32 value) {
}
inline void CodedOutputStream::WriteString(const string& str) {
- WriteRaw(str.data(), str.size());
+ WriteRaw(str.data(), static_cast<int>(str.size()));
+}
+
+inline void CodedOutputStream::WriteRawMaybeAliased(
+ const void* data, int size) {
+ if (aliasing_enabled_) {
+ WriteAliasedRaw(data, size);
+ } else {
+ WriteRaw(data, size);
+ }
}
inline uint8* CodedOutputStream::WriteStringToArray(
const string& str, uint8* target) {
- return WriteRawToArray(str.data(), str.size(), target);
+ return WriteRawToArray(str.data(), static_cast<int>(str.size()), target);
}
inline int CodedOutputStream::ByteCount() const {
@@ -1017,7 +1144,7 @@ inline void CodedInputStream::DecrementRecursionDepth() {
if (recursion_depth_ > 0) --recursion_depth_;
}
-inline void CodedInputStream::SetExtensionRegistry(DescriptorPool* pool,
+inline void CodedInputStream::SetExtensionRegistry(const DescriptorPool* pool,
MessageFactory* factory) {
extension_pool_ = pool;
extension_factory_ = factory;
@@ -1031,7 +1158,7 @@ inline MessageFactory* CodedInputStream::GetExtensionFactory() {
return extension_factory_;
}
-inline uint32 CodedInputStream::BufferSize() const {
+inline int CodedInputStream::BufferSize() const {
return buffer_end_ - buffer_;
}
@@ -1044,12 +1171,12 @@ inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input)
last_tag_(0),
legitimate_message_end_(false),
aliasing_enabled_(false),
- current_limit_(INT_MAX),
+ current_limit_(kint32max),
buffer_size_after_limit_(0),
total_bytes_limit_(kDefaultTotalBytesLimit),
total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
recursion_depth_(0),
- recursion_limit_(kDefaultRecursionLimit),
+ recursion_limit_(default_recursion_limit_),
extension_pool_(NULL),
extension_factory_(NULL) {
// Eagerly Refresh() so buffer space is immediately available.
@@ -1070,21 +1197,24 @@ inline CodedInputStream::CodedInputStream(const uint8* buffer, int size)
total_bytes_limit_(kDefaultTotalBytesLimit),
total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
recursion_depth_(0),
- recursion_limit_(kDefaultRecursionLimit),
+ recursion_limit_(default_recursion_limit_),
extension_pool_(NULL),
extension_factory_(NULL) {
// Note that setting current_limit_ == size is important to prevent some
// code paths from trying to access input_ and segfaulting.
}
-inline CodedInputStream::~CodedInputStream() {
- if (input_ != NULL) {
- BackUpInputToCurrentPosition();
- }
+inline bool CodedInputStream::IsFlat() const {
+ return input_ == NULL;
}
} // namespace io
} // namespace protobuf
+
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+ #pragma runtime_checks("c", restore)
+#endif // _MSC_VER
+
} // namespace google
#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
diff --git a/src/google/protobuf/io/coded_stream_inl.h b/src/google/protobuf/io/coded_stream_inl.h
index e9799d4..88c14ca 100644
--- a/src/google/protobuf/io/coded_stream_inl.h
+++ b/src/google/protobuf/io/coded_stream_inl.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -37,8 +37,9 @@
#define GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <string>
-#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
@@ -50,8 +51,12 @@ inline bool CodedInputStream::InternalReadStringInline(string* buffer,
if (BufferSize() >= size) {
STLStringResizeUninitialized(buffer, size);
- memcpy(string_as_array(buffer), buffer_, size);
- Advance(size);
+ // When buffer is empty, string_as_array(buffer) will return NULL but memcpy
+ // requires non-NULL pointers even when size is 0. Hench this check.
+ if (size > 0) {
+ memcpy(mutable_string_data(buffer), buffer_, size);
+ Advance(size);
+ }
return true;
}
diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc
index 7d29833..f4cb5ea 100644
--- a/src/google/protobuf/io/coded_stream_unittest.cc
+++ b/src/google/protobuf/io/coded_stream_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -44,7 +44,6 @@
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
-#include <google/protobuf/stubs/strutil.h>
// This declares an unsigned long long integer literal in a portable way.
@@ -125,6 +124,13 @@ namespace {
class CodedStreamTest : public testing::Test {
protected:
+ // Helper method used by tests for bytes warning. See implementation comment
+ // for further information.
+ static void SetupTotalBytesLimitWarningTest(
+ int total_bytes_limit, int warning_threshold,
+ vector<string>* out_errors, vector<string>* out_warnings);
+
+ // Buffer used during most of the tests. This assumes tests run sequentially.
static const int kBufferSize = 1024 * 64;
static uint8 buffer_[kBufferSize];
};
@@ -208,6 +214,33 @@ TEST_2D(CodedStreamTest, ReadTag, kVarintCases, kBlockSizes) {
EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
}
+// This is the regression test that verifies that there is no issues
+// with the empty input buffers handling.
+TEST_F(CodedStreamTest, EmptyInputBeforeEos) {
+ class In : public ZeroCopyInputStream {
+ public:
+ In() : count_(0) {}
+ private:
+ virtual bool Next(const void** data, int* size) {
+ *data = NULL;
+ *size = 0;
+ return count_++ < 2;
+ }
+ virtual void BackUp(int count) {
+ GOOGLE_LOG(FATAL) << "Tests never call this.";
+ }
+ virtual bool Skip(int count) {
+ GOOGLE_LOG(FATAL) << "Tests never call this.";
+ return false;
+ }
+ virtual int64 ByteCount() const { return 0; }
+ int count_;
+ } in;
+ CodedInputStream input(&in);
+ input.ReadTag();
+ EXPECT_TRUE(input.ConsumedEntireMessage());
+}
+
TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) {
// Leave one byte at the beginning of the buffer so we can read it
// to force the first buffer to be loaded.
@@ -649,14 +682,197 @@ TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnHeap) {
EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
}
+TEST_1D(CodedStreamTest, ReadStringReservesMemoryOnTotalLimit, kBlockSizes) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.SetTotalBytesLimit(sizeof(kRawBytes), sizeof(kRawBytes));
+ EXPECT_EQ(sizeof(kRawBytes), coded_input.BytesUntilTotalBytesLimit());
+
+ string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ EXPECT_EQ(sizeof(kRawBytes) - strlen(kRawBytes),
+ coded_input.BytesUntilTotalBytesLimit());
+ EXPECT_EQ(kRawBytes, str);
+ // TODO(liujisi): Replace with a more meaningful test (see cl/60966023).
+ EXPECT_GE(str.capacity(), strlen(kRawBytes));
+ }
+
+ EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
+}
+
+TEST_1D(CodedStreamTest, ReadStringReservesMemoryOnPushedLimit, kBlockSizes) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.PushLimit(sizeof(buffer_));
+
+ string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ EXPECT_EQ(kRawBytes, str);
+ // TODO(liujisi): Replace with a more meaningful test (see cl/60966023).
+ EXPECT_GE(str.capacity(), strlen(kRawBytes));
+ }
+
+ EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationIfLimitsNotSet) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ EXPECT_EQ(kRawBytes, str);
+ // Note: this check depends on string class implementation. It
+ // expects that string will allocate more than strlen(kRawBytes)
+ // if the content of kRawBytes is appended to string in small
+ // chunks.
+ // TODO(liujisi): Replace with a more meaningful test (see cl/60966023).
+ EXPECT_GE(str.capacity(), strlen(kRawBytes));
+ }
+
+ EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsNegative) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.PushLimit(sizeof(buffer_));
+
+ string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, -1));
+ // Note: this check depends on string class implementation. It
+ // expects that string will always allocate the same amount of
+ // memory for an empty string.
+ EXPECT_EQ(string().capacity(), str.capacity());
+ }
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsLarge) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.PushLimit(sizeof(buffer_));
+
+ string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
+ EXPECT_GT(1 << 30, str.capacity());
+ }
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsOverTheLimit) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.PushLimit(16);
+
+ string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ // Note: this check depends on string class implementation. It
+ // expects that string will allocate less than strlen(kRawBytes)
+ // for an empty string.
+ EXPECT_GT(strlen(kRawBytes), str.capacity());
+ }
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsOverTheTotalBytesLimit) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.SetTotalBytesLimit(16, 16);
+
+ string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ // Note: this check depends on string class implementation. It
+ // expects that string will allocate less than strlen(kRawBytes)
+ // for an empty string.
+ EXPECT_GT(strlen(kRawBytes), str.capacity());
+ }
+}
+
+TEST_F(CodedStreamTest,
+ ReadStringNoReservationSizeIsOverTheClosestLimit_GlobalLimitIsCloser) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.PushLimit(sizeof(buffer_));
+ coded_input.SetTotalBytesLimit(16, 16);
+
+ string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ // Note: this check depends on string class implementation. It
+ // expects that string will allocate less than strlen(kRawBytes)
+ // for an empty string.
+ EXPECT_GT(strlen(kRawBytes), str.capacity());
+ }
+}
+
+TEST_F(CodedStreamTest,
+ ReadStringNoReservationSizeIsOverTheClosestLimit_LocalLimitIsCloser) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.PushLimit(16);
+ coded_input.SetTotalBytesLimit(sizeof(buffer_), sizeof(buffer_));
+ EXPECT_EQ(sizeof(buffer_), coded_input.BytesUntilTotalBytesLimit());
+
+ string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ // Note: this check depends on string class implementation. It
+ // expects that string will allocate less than strlen(kRawBytes)
+ // for an empty string.
+ EXPECT_GT(strlen(kRawBytes), str.capacity());
+ }
+}
+
// -------------------------------------------------------------------
// Skip
const char kSkipTestBytes[] =
"<Before skipping><To be skipped><After skipping>";
-const char kSkipOutputTestBytes[] =
- "-----------------<To be skipped>----------------";
TEST_1D(CodedStreamTest, SkipInput, kBlockSizes) {
memcpy(buffer_, kSkipTestBytes, sizeof(kSkipTestBytes));
@@ -947,9 +1163,11 @@ TEST_F(CodedStreamTest, TotalBytesLimit) {
ArrayInputStream input(buffer_, sizeof(buffer_));
CodedInputStream coded_input(&input);
coded_input.SetTotalBytesLimit(16, -1);
+ EXPECT_EQ(16, coded_input.BytesUntilTotalBytesLimit());
string str;
EXPECT_TRUE(coded_input.ReadString(&str, 16));
+ EXPECT_EQ(0, coded_input.BytesUntilTotalBytesLimit());
vector<string> errors;
@@ -964,7 +1182,9 @@ TEST_F(CodedStreamTest, TotalBytesLimit) {
"A protocol message was rejected because it was too big", errors[0]);
coded_input.SetTotalBytesLimit(32, -1);
+ EXPECT_EQ(16, coded_input.BytesUntilTotalBytesLimit());
EXPECT_TRUE(coded_input.ReadString(&str, 16));
+ EXPECT_EQ(0, coded_input.BytesUntilTotalBytesLimit());
}
TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) {
@@ -995,6 +1215,60 @@ TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) {
EXPECT_FALSE(coded_input.ConsumedEntireMessage());
}
+// This method is used by the tests below.
+// It constructs a CodedInputStream with the given limits and tries to read 2KiB
+// of data from it. Then it returns the logged errors and warnings in the given
+// vectors.
+void CodedStreamTest::SetupTotalBytesLimitWarningTest(
+ int total_bytes_limit, int warning_threshold,
+ vector<string>* out_errors, vector<string>* out_warnings) {
+ ArrayInputStream raw_input(buffer_, sizeof(buffer_), 128);
+
+ ScopedMemoryLog scoped_log;
+ {
+ CodedInputStream input(&raw_input);
+ input.SetTotalBytesLimit(total_bytes_limit, warning_threshold);
+ string str;
+ EXPECT_TRUE(input.ReadString(&str, 2048));
+ }
+
+ *out_errors = scoped_log.GetMessages(ERROR);
+ *out_warnings = scoped_log.GetMessages(WARNING);
+}
+
+TEST_F(CodedStreamTest, TotalBytesLimitWarning) {
+ vector<string> errors;
+ vector<string> warnings;
+ SetupTotalBytesLimitWarningTest(10240, 1024, &errors, &warnings);
+
+ EXPECT_EQ(0, errors.size());
+
+ ASSERT_EQ(2, warnings.size());
+ EXPECT_PRED_FORMAT2(testing::IsSubstring,
+ "Reading dangerously large protocol message. If the message turns out to "
+ "be larger than 10240 bytes, parsing will be halted for security reasons.",
+ warnings[0]);
+ EXPECT_PRED_FORMAT2(testing::IsSubstring,
+ "The total number of bytes read was 2048",
+ warnings[1]);
+}
+
+TEST_F(CodedStreamTest, TotalBytesLimitWarningDisabled) {
+ vector<string> errors;
+ vector<string> warnings;
+
+ // Test with -1
+ SetupTotalBytesLimitWarningTest(10240, -1, &errors, &warnings);
+ EXPECT_EQ(0, errors.size());
+ EXPECT_EQ(0, warnings.size());
+
+ // Test again with -2, expecting the same result
+ SetupTotalBytesLimitWarningTest(10240, -2, &errors, &warnings);
+ EXPECT_EQ(0, errors.size());
+ EXPECT_EQ(0, warnings.size());
+}
+
+
TEST_F(CodedStreamTest, RecursionLimit) {
ArrayInputStream input(buffer_, sizeof(buffer_));
CodedInputStream coded_input(&input);
@@ -1032,6 +1306,7 @@ TEST_F(CodedStreamTest, RecursionLimit) {
EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 7
}
+
class ReallyBigInputStream : public ZeroCopyInputStream {
public:
ReallyBigInputStream() : backup_amount_(0), buffer_count_(0) {}
diff --git a/src/google/protobuf/io/gzip_stream.cc b/src/google/protobuf/io/gzip_stream.cc
index 84d277f..ee28696 100644
--- a/src/google/protobuf/io/gzip_stream.cc
+++ b/src/google/protobuf/io/gzip_stream.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -73,6 +73,17 @@ GzipInputStream::~GzipInputStream() {
zerror_ = inflateEnd(&zcontext_);
}
+static inline int internalInflateInit2(
+ z_stream* zcontext, GzipInputStream::Format format) {
+ int windowBitsFormat = 0;
+ switch (format) {
+ case GzipInputStream::GZIP: windowBitsFormat = 16; break;
+ case GzipInputStream::AUTO: windowBitsFormat = 32; break;
+ case GzipInputStream::ZLIB: windowBitsFormat = 0; break;
+ }
+ return inflateInit2(zcontext, /* windowBits */15 | windowBitsFormat);
+}
+
int GzipInputStream::Inflate(int flush) {
if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) {
// previous inflate filled output buffer. don't change input params yet.
@@ -89,14 +100,7 @@ int GzipInputStream::Inflate(int flush) {
zcontext_.next_in = static_cast<Bytef*>(const_cast<void*>(in));
zcontext_.avail_in = in_size;
if (first) {
- int windowBitsFormat = 0;
- switch (format_) {
- case GZIP: windowBitsFormat = 16; break;
- case AUTO: windowBitsFormat = 32; break;
- case ZLIB: windowBitsFormat = 0; break;
- }
- int error = inflateInit2(&zcontext_,
- /* windowBits */15 | windowBitsFormat);
+ int error = internalInflateInit2(&zcontext_, format_);
if (error != Z_OK) {
return error;
}
@@ -127,9 +131,21 @@ bool GzipInputStream::Next(const void** data, int* size) {
return true;
}
if (zerror_ == Z_STREAM_END) {
- *data = NULL;
- *size = 0;
- return false;
+ if (zcontext_.next_out != NULL) {
+ // sub_stream_ may have concatenated streams to follow
+ zerror_ = inflateEnd(&zcontext_);
+ if (zerror_ != Z_OK) {
+ return false;
+ }
+ zerror_ = internalInflateInit2(&zcontext_, format_);
+ if (zerror_ != Z_OK) {
+ return false;
+ }
+ } else {
+ *data = NULL;
+ *size = 0;
+ return false;
+ }
}
zerror_ = Inflate(Z_NO_FLUSH);
if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) {
@@ -183,16 +199,6 @@ GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream,
Init(sub_stream, options);
}
-GzipOutputStream::GzipOutputStream(
- ZeroCopyOutputStream* sub_stream, Format format, int buffer_size) {
- Options options;
- options.format = format;
- if (buffer_size != -1) {
- options.buffer_size = buffer_size;
- }
- Init(sub_stream, options);
-}
-
void GzipOutputStream::Init(ZeroCopyOutputStream* sub_stream,
const Options& options) {
sub_stream_ = sub_stream;
@@ -251,8 +257,7 @@ int GzipOutputStream::Deflate(int flush) {
}
error = deflate(&zcontext_, flush);
} while (error == Z_OK && zcontext_.avail_out == 0);
- if (((flush == Z_FULL_FLUSH) || (flush == Z_FINISH))
- && (zcontext_.avail_out != sub_data_size_)) {
+ if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) {
// Notify lower layer of data.
sub_stream_->BackUp(zcontext_.avail_out);
// We don't own the buffer anymore.
@@ -294,10 +299,11 @@ int64 GzipOutputStream::ByteCount() const {
}
bool GzipOutputStream::Flush() {
- do {
- zerror_ = Deflate(Z_FULL_FLUSH);
- } while (zerror_ == Z_OK);
- return zerror_ == Z_OK;
+ zerror_ = Deflate(Z_FULL_FLUSH);
+ // Return true if the flush succeeded or if it was a no-op.
+ return (zerror_ == Z_OK) ||
+ (zerror_ == Z_BUF_ERROR && zcontext_.avail_in == 0 &&
+ zcontext_.avail_out != 0);
}
bool GzipOutputStream::Close() {
diff --git a/src/google/protobuf/io/gzip_stream.h b/src/google/protobuf/io/gzip_stream.h
index 65dbc5b..c7ccc26 100644
--- a/src/google/protobuf/io/gzip_stream.h
+++ b/src/google/protobuf/io/gzip_stream.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -45,6 +45,7 @@
#include <zlib.h>
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/zero_copy_stream.h>
namespace google {
@@ -144,12 +145,6 @@ class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream {
ZeroCopyOutputStream* sub_stream,
const Options& options);
- // DEPRECATED: Use one of the above constructors instead.
- GzipOutputStream(
- ZeroCopyOutputStream* sub_stream,
- Format format,
- int buffer_size = -1) GOOGLE_ATTRIBUTE_DEPRECATED;
-
virtual ~GzipOutputStream();
// Return last error message or NULL if no error.
@@ -165,6 +160,13 @@ class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream {
// necessary.
// Compression may be less efficient stopping and starting around flushes.
// Returns true if no error.
+ //
+ // Please ensure that block size is > 6. Here is an excerpt from the zlib
+ // doc that explains why:
+ //
+ // In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out
+ // is greater than six to avoid repeated flush markers due to
+ // avail_out == 0 on return.
bool Flush();
// Writes out all data and closes the gzip stream.
diff --git a/src/google/protobuf/io/gzip_stream_unittest.sh b/src/google/protobuf/io/gzip_stream_unittest.sh
index 6e8a094..16251a9 100755
--- a/src/google/protobuf/io/gzip_stream_unittest.sh
+++ b/src/google/protobuf/io/gzip_stream_unittest.sh
@@ -2,7 +2,7 @@
#
# Protocol Buffers - Google's data interchange format
# Copyright 2009 Google Inc. All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
diff --git a/src/google/protobuf/io/package_info.h b/src/google/protobuf/io/package_info.h
index 7a7a4e7..dc1fc91 100644
--- a/src/google/protobuf/io/package_info.h
+++ b/src/google/protobuf/io/package_info.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc
index c7d3074..c8df417 100644
--- a/src/google/protobuf/io/printer.cc
+++ b/src/google/protobuf/io/printer.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,7 +35,6 @@
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/strutil.h>
namespace google {
namespace protobuf {
@@ -51,8 +50,8 @@ Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter)
}
Printer::~Printer() {
- // Only BackUp() if we're sure we've successfully called Next() at least once.
- if (buffer_size_ > 0) {
+ // Only BackUp() if we have called Next() at least once and never failed.
+ if (buffer_size_ > 0 && !failed_) {
output_->BackUp(buffer_size_);
}
}
@@ -132,6 +131,17 @@ void Printer::Print(const char* text,
Print(vars, text);
}
+void Printer::Print(const char* text,
+ const char* variable1, const string& value1,
+ const char* variable2, const string& value2,
+ const char* variable3, const string& value3) {
+ map<string, string> vars;
+ vars[variable1] = value1;
+ vars[variable2] = value2;
+ vars[variable3] = value3;
+ Print(vars, text);
+}
+
void Printer::Indent() {
indent_ += " ";
}
@@ -158,7 +168,7 @@ void Printer::WriteRaw(const char* data, int size) {
if (failed_) return;
if (size == 0) return;
- if (at_start_of_line_) {
+ if (at_start_of_line_ && (size > 0) && (data[0] != '\n')) {
// Insert an indent.
at_start_of_line_ = false;
WriteRaw(indent_.data(), indent_.size());
diff --git a/src/google/protobuf/io/printer.h b/src/google/protobuf/io/printer.h
index de08538..f06cbf2 100644
--- a/src/google/protobuf/io/printer.h
+++ b/src/google/protobuf/io/printer.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -82,7 +82,11 @@ class LIBPROTOBUF_EXPORT Printer {
// Like the first Print(), except the substitutions are given as parameters.
void Print(const char* text, const char* variable1, const string& value1,
const char* variable2, const string& value2);
- // TODO(kenton): Overloaded versions with more variables? Two seems
+ // Like the first Print(), except the substitutions are given as parameters.
+ void Print(const char* text, const char* variable1, const string& value1,
+ const char* variable2, const string& value2,
+ const char* variable3, const string& value3);
+ // TODO(kenton): Overloaded versions with more variables? Three seems
// to be enough.
// Indent text by two spaces. After calling Indent(), two spaces will be
diff --git a/src/google/protobuf/io/printer_unittest.cc b/src/google/protobuf/io/printer_unittest.cc
index 580a53d..1331a8d 100644
--- a/src/google/protobuf/io/printer_unittest.cc
+++ b/src/google/protobuf/io/printer_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -220,7 +220,7 @@ TEST(Printer, Indenting) {
}
// Death tests do not work on Windows as of yet.
-#ifdef GTEST_HAS_DEATH_TEST
+#ifdef PROTOBUF_HAS_DEATH_TEST
TEST(Printer, Death) {
char buffer[8192];
@@ -231,9 +231,33 @@ TEST(Printer, Death) {
EXPECT_DEBUG_DEATH(printer.Print("$unclosed"), "Unclosed variable name");
EXPECT_DEBUG_DEATH(printer.Outdent(), "without matching Indent");
}
-#endif // GTEST_HAS_DEATH_TEST
+#endif // PROTOBUF_HAS_DEATH_TEST
-TEST(Printer, WriteFailure) {
+TEST(Printer, WriteFailurePartial) {
+ char buffer[17];
+
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ Printer printer(&output, '$');
+
+ // Print 16 bytes to almost fill the buffer (should not fail).
+ printer.Print("0123456789abcdef");
+ EXPECT_FALSE(printer.failed());
+
+ // Try to print 2 chars. Only one fits.
+ printer.Print("<>");
+ EXPECT_TRUE(printer.failed());
+
+ // Anything else should fail too.
+ printer.Print(" ");
+ EXPECT_TRUE(printer.failed());
+ printer.Print("blah");
+ EXPECT_TRUE(printer.failed());
+
+ // Buffer should contain the first 17 bytes written.
+ EXPECT_EQ("0123456789abcdef<", string(buffer, sizeof(buffer)));
+}
+
+TEST(Printer, WriteFailureExact) {
char buffer[16];
ArrayOutputStream output(buffer, sizeof(buffer));
diff --git a/src/google/protobuf/io/strtod.cc b/src/google/protobuf/io/strtod.cc
new file mode 100644
index 0000000..5697343
--- /dev/null
+++ b/src/google/protobuf/io/strtod.cc
@@ -0,0 +1,113 @@
+// 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/io/strtod.h>
+
+#include <cstdio>
+#include <cstring>
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// ----------------------------------------------------------------------
+// NoLocaleStrtod()
+// This code will make you cry.
+// ----------------------------------------------------------------------
+
+namespace {
+
+// Returns a string identical to *input except that the character pointed to
+// by radix_pos (which should be '.') is replaced with the locale-specific
+// radix character.
+string LocalizeRadix(const char* input, const char* radix_pos) {
+ // Determine the locale-specific radix character by calling sprintf() to
+ // print the number 1.5, then stripping off the digits. As far as I can
+ // tell, this is the only portable, thread-safe way to get the C library
+ // to divuldge the locale's radix character. No, localeconv() is NOT
+ // thread-safe.
+ char temp[16];
+ int size = sprintf(temp, "%.1f", 1.5);
+ GOOGLE_CHECK_EQ(temp[0], '1');
+ GOOGLE_CHECK_EQ(temp[size-1], '5');
+ GOOGLE_CHECK_LE(size, 6);
+
+ // Now replace the '.' in the input with it.
+ string result;
+ result.reserve(strlen(input) + size - 3);
+ result.append(input, radix_pos);
+ result.append(temp + 1, size - 2);
+ result.append(radix_pos + 1);
+ return result;
+}
+
+} // namespace
+
+double NoLocaleStrtod(const char* text, char** original_endptr) {
+ // We cannot simply set the locale to "C" temporarily with setlocale()
+ // as this is not thread-safe. Instead, we try to parse in the current
+ // locale first. If parsing stops at a '.' character, then this is a
+ // pretty good hint that we're actually in some other locale in which
+ // '.' is not the radix character.
+
+ char* temp_endptr;
+ double result = strtod(text, &temp_endptr);
+ if (original_endptr != NULL) *original_endptr = temp_endptr;
+ if (*temp_endptr != '.') return result;
+
+ // Parsing halted on a '.'. Perhaps we're in a different locale? Let's
+ // try to replace the '.' with a locale-specific radix character and
+ // try again.
+ string localized = LocalizeRadix(text, temp_endptr);
+ const char* localized_cstr = localized.c_str();
+ char* localized_endptr;
+ result = strtod(localized_cstr, &localized_endptr);
+ if ((localized_endptr - localized_cstr) >
+ (temp_endptr - text)) {
+ // This attempt got further, so replacing the decimal must have helped.
+ // Update original_endptr to point at the right location.
+ if (original_endptr != NULL) {
+ // size_diff is non-zero if the localized radix has multiple bytes.
+ int size_diff = localized.size() - strlen(text);
+ // const_cast is necessary to match the strtod() interface.
+ *original_endptr = const_cast<char*>(
+ text + (localized_endptr - localized_cstr - size_diff));
+ }
+ }
+
+ return result;
+}
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/io/strtod.h b/src/google/protobuf/io/strtod.h
new file mode 100644
index 0000000..c2efc8d
--- /dev/null
+++ b/src/google/protobuf/io/strtod.h
@@ -0,0 +1,50 @@
+// 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.
+
+// A locale-independent version of strtod(), used to parse floating
+// point default values in .proto files, where the decimal separator
+// is always a dot.
+
+#ifndef GOOGLE_PROTOBUF_IO_STRTOD_H__
+#define GOOGLE_PROTOBUF_IO_STRTOD_H__
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// A locale-independent version of the standard strtod(), which always
+// uses a dot as the decimal separator.
+double NoLocaleStrtod(const char* str, char** endptr);
+
+} // namespace io
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_IO_STRTOD_H__
diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc
index 38fa351..ef2de30 100644
--- a/src/google/protobuf/io/tokenizer.cc
+++ b/src/google/protobuf/io/tokenizer.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -89,8 +89,12 @@
// exactly pretty.
#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/io/strtod.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
@@ -118,6 +122,8 @@ namespace {
CHARACTER_CLASS(Whitespace, c == ' ' || c == '\n' || c == '\t' ||
c == '\r' || c == '\v' || c == '\f');
+CHARACTER_CLASS(WhitespaceNoNewline, c == ' ' || c == '\t' ||
+ c == '\r' || c == '\v' || c == '\f');
CHARACTER_CLASS(Unprintable, c < ' ' && c > '\0');
@@ -187,12 +193,16 @@ Tokenizer::Tokenizer(ZeroCopyInputStream* input,
read_error_(false),
line_(0),
column_(0),
- token_start_(-1),
+ record_target_(NULL),
+ record_start_(-1),
allow_f_after_float_(false),
- comment_style_(CPP_COMMENT_STYLE) {
+ comment_style_(CPP_COMMENT_STYLE),
+ require_space_after_number_(true),
+ allow_multiline_strings_(false) {
current_.line = 0;
current_.column = 0;
+ current_.end_column = 0;
current_.type = TYPE_START;
Refresh();
@@ -237,9 +247,9 @@ void Tokenizer::Refresh() {
}
// If we're in a token, append the rest of the buffer to it.
- if (token_start_ >= 0 && token_start_ < buffer_size_) {
- current_.text.append(buffer_ + token_start_, buffer_size_ - token_start_);
- token_start_ = 0;
+ if (record_target_ != NULL && record_start_ < buffer_size_) {
+ record_target_->append(buffer_ + record_start_, buffer_size_ - record_start_);
+ record_start_ = 0;
}
const void* data = NULL;
@@ -260,23 +270,34 @@ void Tokenizer::Refresh() {
current_char_ = buffer_[0];
}
+inline void Tokenizer::RecordTo(string* target) {
+ record_target_ = target;
+ record_start_ = buffer_pos_;
+}
+
+inline void Tokenizer::StopRecording() {
+ // Note: The if() is necessary because some STL implementations crash when
+ // you call string::append(NULL, 0), presumably because they are trying to
+ // be helpful by detecting the NULL pointer, even though there's nothing
+ // wrong with reading zero bytes from NULL.
+ if (buffer_pos_ != record_start_) {
+ record_target_->append(buffer_ + record_start_, buffer_pos_ - record_start_);
+ }
+ record_target_ = NULL;
+ record_start_ = -1;
+}
+
inline void Tokenizer::StartToken() {
- token_start_ = buffer_pos_;
current_.type = TYPE_START; // Just for the sake of initializing it.
current_.text.clear();
current_.line = line_;
current_.column = column_;
+ RecordTo(&current_.text);
}
inline void Tokenizer::EndToken() {
- // Note: The if() is necessary because some STL implementations crash when
- // you call string::append(NULL, 0), presumably because they are trying to
- // be helpful by detecting the NULL pointer, even though there's nothing
- // wrong with reading zero bytes from NULL.
- if (buffer_pos_ != token_start_) {
- current_.text.append(buffer_ + token_start_, buffer_pos_ - token_start_);
- }
- token_start_ = -1;
+ StopRecording();
+ current_.end_column = column_;
}
// -------------------------------------------------------------------
@@ -332,9 +353,16 @@ void Tokenizer::ConsumeString(char delimiter) {
while (true) {
switch (current_char_) {
case '\0':
- case '\n': {
- AddError("String literals cannot cross line boundaries.");
+ AddError("Unexpected end of string.");
return;
+
+ case '\n': {
+ if (!allow_multiline_strings_) {
+ AddError("String literals cannot cross line boundaries.");
+ return;
+ }
+ NextChar();
+ break;
}
case '\\': {
@@ -351,6 +379,27 @@ void Tokenizer::ConsumeString(char delimiter) {
AddError("Expected hex digits for escape sequence.");
}
// Possibly followed by another hex digit, but again we don't care.
+ } else if (TryConsume('u')) {
+ if (!TryConsumeOne<HexDigit>() ||
+ !TryConsumeOne<HexDigit>() ||
+ !TryConsumeOne<HexDigit>() ||
+ !TryConsumeOne<HexDigit>()) {
+ AddError("Expected four hex digits for \\u escape sequence.");
+ }
+ } else if (TryConsume('U')) {
+ // We expect 8 hex digits; but only the range up to 0x10ffff is
+ // legal.
+ if (!TryConsume('0') ||
+ !TryConsume('0') ||
+ !(TryConsume('0') || TryConsume('1')) ||
+ !TryConsumeOne<HexDigit>() ||
+ !TryConsumeOne<HexDigit>() ||
+ !TryConsumeOne<HexDigit>() ||
+ !TryConsumeOne<HexDigit>() ||
+ !TryConsumeOne<HexDigit>()) {
+ AddError("Expected eight hex digits up to 10ffff for \\U escape "
+ "sequence");
+ }
} else {
AddError("Invalid escape sequence in string literal.");
}
@@ -410,7 +459,7 @@ Tokenizer::TokenType Tokenizer::ConsumeNumber(bool started_with_zero,
}
}
- if (LookingAt<Letter>()) {
+ if (LookingAt<Letter>() && require_space_after_number_) {
AddError("Need space between number and identifier.");
} else if (current_char_ == '.') {
if (is_float) {
@@ -424,26 +473,51 @@ Tokenizer::TokenType Tokenizer::ConsumeNumber(bool started_with_zero,
return is_float ? TYPE_FLOAT : TYPE_INTEGER;
}
-void Tokenizer::ConsumeLineComment() {
+void Tokenizer::ConsumeLineComment(string* content) {
+ if (content != NULL) RecordTo(content);
+
while (current_char_ != '\0' && current_char_ != '\n') {
NextChar();
}
TryConsume('\n');
+
+ if (content != NULL) StopRecording();
}
-void Tokenizer::ConsumeBlockComment() {
+void Tokenizer::ConsumeBlockComment(string* content) {
int start_line = line_;
int start_column = column_ - 2;
+ if (content != NULL) RecordTo(content);
+
while (true) {
while (current_char_ != '\0' &&
current_char_ != '*' &&
- current_char_ != '/') {
+ current_char_ != '/' &&
+ current_char_ != '\n') {
NextChar();
}
- if (TryConsume('*') && TryConsume('/')) {
+ if (TryConsume('\n')) {
+ if (content != NULL) StopRecording();
+
+ // Consume leading whitespace and asterisk;
+ ConsumeZeroOrMore<WhitespaceNoNewline>();
+ if (TryConsume('*')) {
+ if (TryConsume('/')) {
+ // End of comment.
+ break;
+ }
+ }
+
+ if (content != NULL) RecordTo(content);
+ } else if (TryConsume('*') && TryConsume('/')) {
// End of comment.
+ if (content != NULL) {
+ StopRecording();
+ // Strip trailing "*/".
+ content->erase(content->size() - 2);
+ }
break;
} else if (TryConsume('/') && current_char_ == '*') {
// Note: We didn't consume the '*' because if there is a '/' after it
@@ -454,42 +528,59 @@ void Tokenizer::ConsumeBlockComment() {
AddError("End-of-file inside block comment.");
error_collector_->AddError(
start_line, start_column, " Comment started here.");
+ if (content != NULL) StopRecording();
break;
}
}
}
+Tokenizer::NextCommentStatus Tokenizer::TryConsumeCommentStart() {
+ if (comment_style_ == CPP_COMMENT_STYLE && TryConsume('/')) {
+ if (TryConsume('/')) {
+ return LINE_COMMENT;
+ } else if (TryConsume('*')) {
+ return BLOCK_COMMENT;
+ } else {
+ // Oops, it was just a slash. Return it.
+ current_.type = TYPE_SYMBOL;
+ current_.text = "/";
+ current_.line = line_;
+ current_.column = column_ - 1;
+ current_.end_column = column_;
+ return SLASH_NOT_COMMENT;
+ }
+ } else if (comment_style_ == SH_COMMENT_STYLE && TryConsume('#')) {
+ return LINE_COMMENT;
+ } else {
+ return NO_COMMENT;
+ }
+}
+
// -------------------------------------------------------------------
bool Tokenizer::Next() {
- TokenType last_token_type = current_.type;
-
- // Did we skip any characters after the last token?
- bool skipped_stuff = false;
+ previous_ = current_;
while (!read_error_) {
- if (TryConsumeOne<Whitespace>()) {
- ConsumeZeroOrMore<Whitespace>();
-
- } else if (comment_style_ == CPP_COMMENT_STYLE && TryConsume('/')) {
- // Starting a comment?
- if (TryConsume('/')) {
- ConsumeLineComment();
- } else if (TryConsume('*')) {
- ConsumeBlockComment();
- } else {
- // Oops, it was just a slash. Return it.
- current_.type = TYPE_SYMBOL;
- current_.text = "/";
- current_.line = line_;
- current_.column = column_ - 1;
+ ConsumeZeroOrMore<Whitespace>();
+
+ switch (TryConsumeCommentStart()) {
+ case LINE_COMMENT:
+ ConsumeLineComment(NULL);
+ continue;
+ case BLOCK_COMMENT:
+ ConsumeBlockComment(NULL);
+ continue;
+ case SLASH_NOT_COMMENT:
return true;
- }
+ case NO_COMMENT:
+ break;
+ }
- } else if (comment_style_ == SH_COMMENT_STYLE && TryConsume('#')) {
- ConsumeLineComment();
+ // Check for EOF before continuing.
+ if (read_error_) break;
- } else if (LookingAt<Unprintable>() || current_char_ == '\0') {
+ if (LookingAt<Unprintable>() || current_char_ == '\0') {
AddError("Invalid control characters encountered in text.");
NextChar();
// Skip more unprintable characters, too. But, remember that '\0' is
@@ -517,7 +608,9 @@ bool Tokenizer::Next() {
if (TryConsumeOne<Digit>()) {
// It's a floating-point number.
- if (last_token_type == TYPE_IDENTIFIER && !skipped_stuff) {
+ if (previous_.type == TYPE_IDENTIFIER &&
+ current_.line == previous_.line &&
+ current_.column == previous_.end_column) {
// We don't accept syntax like "blah.123".
error_collector_->AddError(line_, column_ - 2,
"Need space between identifier and decimal point.");
@@ -535,6 +628,12 @@ bool Tokenizer::Next() {
ConsumeString('\'');
current_.type = TYPE_STRING;
} else {
+ // Check if the high order bit is set.
+ if (current_char_ & 0x80) {
+ error_collector_->AddError(line_, column_,
+ StringPrintf("Interpreting non ascii codepoint %d.",
+ static_cast<unsigned char>(current_char_)));
+ }
NextChar();
current_.type = TYPE_SYMBOL;
}
@@ -542,8 +641,6 @@ bool Tokenizer::Next() {
EndToken();
return true;
}
-
- skipped_stuff = true;
}
// EOF
@@ -551,9 +648,199 @@ bool Tokenizer::Next() {
current_.text.clear();
current_.line = line_;
current_.column = column_;
+ current_.end_column = column_;
return false;
}
+namespace {
+
+// Helper class for collecting comments and putting them in the right places.
+//
+// This basically just buffers the most recent comment until it can be decided
+// exactly where that comment should be placed. When Flush() is called, the
+// current comment goes into either prev_trailing_comments or detached_comments.
+// When the CommentCollector is destroyed, the last buffered comment goes into
+// next_leading_comments.
+class CommentCollector {
+ public:
+ CommentCollector(string* prev_trailing_comments,
+ vector<string>* detached_comments,
+ string* next_leading_comments)
+ : prev_trailing_comments_(prev_trailing_comments),
+ detached_comments_(detached_comments),
+ next_leading_comments_(next_leading_comments),
+ has_comment_(false),
+ is_line_comment_(false),
+ can_attach_to_prev_(true) {
+ if (prev_trailing_comments != NULL) prev_trailing_comments->clear();
+ if (detached_comments != NULL) detached_comments->clear();
+ if (next_leading_comments != NULL) next_leading_comments->clear();
+ }
+
+ ~CommentCollector() {
+ // Whatever is in the buffer is a leading comment.
+ if (next_leading_comments_ != NULL && has_comment_) {
+ comment_buffer_.swap(*next_leading_comments_);
+ }
+ }
+
+ // About to read a line comment. Get the comment buffer pointer in order to
+ // read into it.
+ string* GetBufferForLineComment() {
+ // We want to combine with previous line comments, but not block comments.
+ if (has_comment_ && !is_line_comment_) {
+ Flush();
+ }
+ has_comment_ = true;
+ is_line_comment_ = true;
+ return &comment_buffer_;
+ }
+
+ // About to read a block comment. Get the comment buffer pointer in order to
+ // read into it.
+ string* GetBufferForBlockComment() {
+ if (has_comment_) {
+ Flush();
+ }
+ has_comment_ = true;
+ is_line_comment_ = false;
+ return &comment_buffer_;
+ }
+
+ void ClearBuffer() {
+ comment_buffer_.clear();
+ has_comment_ = false;
+ }
+
+ // Called once we know that the comment buffer is complete and is *not*
+ // connected to the next token.
+ void Flush() {
+ if (has_comment_) {
+ if (can_attach_to_prev_) {
+ if (prev_trailing_comments_ != NULL) {
+ prev_trailing_comments_->append(comment_buffer_);
+ }
+ can_attach_to_prev_ = false;
+ } else {
+ if (detached_comments_ != NULL) {
+ detached_comments_->push_back(comment_buffer_);
+ }
+ }
+ ClearBuffer();
+ }
+ }
+
+ void DetachFromPrev() {
+ can_attach_to_prev_ = false;
+ }
+
+ private:
+ string* prev_trailing_comments_;
+ vector<string>* detached_comments_;
+ string* next_leading_comments_;
+
+ string comment_buffer_;
+
+ // True if any comments were read into comment_buffer_. This can be true even
+ // if comment_buffer_ is empty, namely if the comment was "/**/".
+ bool has_comment_;
+
+ // Is the comment in the comment buffer a line comment?
+ bool is_line_comment_;
+
+ // Is it still possible that we could be reading a comment attached to the
+ // previous token?
+ bool can_attach_to_prev_;
+};
+
+} // namespace
+
+bool Tokenizer::NextWithComments(string* prev_trailing_comments,
+ vector<string>* detached_comments,
+ string* next_leading_comments) {
+ CommentCollector collector(prev_trailing_comments, detached_comments,
+ next_leading_comments);
+
+ if (current_.type == TYPE_START) {
+ collector.DetachFromPrev();
+ } else {
+ // A comment appearing on the same line must be attached to the previous
+ // declaration.
+ ConsumeZeroOrMore<WhitespaceNoNewline>();
+ switch (TryConsumeCommentStart()) {
+ case LINE_COMMENT:
+ ConsumeLineComment(collector.GetBufferForLineComment());
+
+ // Don't allow comments on subsequent lines to be attached to a trailing
+ // comment.
+ collector.Flush();
+ break;
+ case BLOCK_COMMENT:
+ ConsumeBlockComment(collector.GetBufferForBlockComment());
+
+ ConsumeZeroOrMore<WhitespaceNoNewline>();
+ if (!TryConsume('\n')) {
+ // Oops, the next token is on the same line. If we recorded a comment
+ // we really have no idea which token it should be attached to.
+ collector.ClearBuffer();
+ return Next();
+ }
+
+ // Don't allow comments on subsequent lines to be attached to a trailing
+ // comment.
+ collector.Flush();
+ break;
+ case SLASH_NOT_COMMENT:
+ return true;
+ case NO_COMMENT:
+ if (!TryConsume('\n')) {
+ // The next token is on the same line. There are no comments.
+ return Next();
+ }
+ break;
+ }
+ }
+
+ // OK, we are now on the line *after* the previous token.
+ while (true) {
+ ConsumeZeroOrMore<WhitespaceNoNewline>();
+
+ switch (TryConsumeCommentStart()) {
+ case LINE_COMMENT:
+ ConsumeLineComment(collector.GetBufferForLineComment());
+ break;
+ case BLOCK_COMMENT:
+ ConsumeBlockComment(collector.GetBufferForBlockComment());
+
+ // Consume the rest of the line so that we don't interpret it as a
+ // blank line the next time around the loop.
+ ConsumeZeroOrMore<WhitespaceNoNewline>();
+ TryConsume('\n');
+ break;
+ case SLASH_NOT_COMMENT:
+ return true;
+ case NO_COMMENT:
+ if (TryConsume('\n')) {
+ // Completely blank line.
+ collector.Flush();
+ collector.DetachFromPrev();
+ } else {
+ bool result = Next();
+ if (!result ||
+ current_.text == "}" ||
+ current_.text == "]" ||
+ current_.text == ")") {
+ // It looks like we're at the end of a scope. In this case it
+ // makes no sense to attach a comment to the following token.
+ collector.Flush();
+ }
+ return result;
+ }
+ break;
+ }
+ }
+}
+
// -------------------------------------------------------------------
// Token-parsing helpers. Remember that these don't need to report
// errors since any errors should already have been reported while
@@ -623,17 +910,138 @@ double Tokenizer::ParseFloat(const string& text) {
return result;
}
+// Helper to append a Unicode code point to a string as UTF8, without bringing
+// in any external dependencies.
+static void AppendUTF8(uint32 code_point, string* output) {
+ uint32 tmp = 0;
+ int len = 0;
+ if (code_point <= 0x7f) {
+ tmp = code_point;
+ len = 1;
+ } else if (code_point <= 0x07ff) {
+ tmp = 0x0000c080 |
+ ((code_point & 0x07c0) << 2) |
+ (code_point & 0x003f);
+ len = 2;
+ } else if (code_point <= 0xffff) {
+ tmp = 0x00e08080 |
+ ((code_point & 0xf000) << 4) |
+ ((code_point & 0x0fc0) << 2) |
+ (code_point & 0x003f);
+ len = 3;
+ } else if (code_point <= 0x1fffff) {
+ tmp = 0xf0808080 |
+ ((code_point & 0x1c0000) << 6) |
+ ((code_point & 0x03f000) << 4) |
+ ((code_point & 0x000fc0) << 2) |
+ (code_point & 0x003f);
+ len = 4;
+ } else {
+ // UTF-16 is only defined for code points up to 0x10FFFF, and UTF-8 is
+ // normally only defined up to there as well.
+ StringAppendF(output, "\\U%08x", code_point);
+ return;
+ }
+ tmp = ghtonl(tmp);
+ output->append(reinterpret_cast<const char*>(&tmp) + sizeof(tmp) - len, len);
+}
+
+// Try to read <len> hex digits from ptr, and stuff the numeric result into
+// *result. Returns true if that many digits were successfully consumed.
+static bool ReadHexDigits(const char* ptr, int len, uint32* result) {
+ *result = 0;
+ if (len == 0) return false;
+ for (const char* end = ptr + len; ptr < end; ++ptr) {
+ if (*ptr == '\0') return false;
+ *result = (*result << 4) + DigitValue(*ptr);
+ }
+ return true;
+}
+
+// Handling UTF-16 surrogate pairs. UTF-16 encodes code points in the range
+// 0x10000...0x10ffff as a pair of numbers, a head surrogate followed by a trail
+// surrogate. These numbers are in a reserved range of Unicode code points, so
+// if we encounter such a pair we know how to parse it and convert it into a
+// single code point.
+static const uint32 kMinHeadSurrogate = 0xd800;
+static const uint32 kMaxHeadSurrogate = 0xdc00;
+static const uint32 kMinTrailSurrogate = 0xdc00;
+static const uint32 kMaxTrailSurrogate = 0xe000;
+
+static inline bool IsHeadSurrogate(uint32 code_point) {
+ return (code_point >= kMinHeadSurrogate) && (code_point < kMaxHeadSurrogate);
+}
+
+static inline bool IsTrailSurrogate(uint32 code_point) {
+ return (code_point >= kMinTrailSurrogate) &&
+ (code_point < kMaxTrailSurrogate);
+}
+
+// Combine a head and trail surrogate into a single Unicode code point.
+static uint32 AssembleUTF16(uint32 head_surrogate, uint32 trail_surrogate) {
+ GOOGLE_DCHECK(IsHeadSurrogate(head_surrogate));
+ GOOGLE_DCHECK(IsTrailSurrogate(trail_surrogate));
+ return 0x10000 + (((head_surrogate - kMinHeadSurrogate) << 10) |
+ (trail_surrogate - kMinTrailSurrogate));
+}
+
+// Convert the escape sequence parameter to a number of expected hex digits.
+static inline int UnicodeLength(char key) {
+ if (key == 'u') return 4;
+ if (key == 'U') return 8;
+ return 0;
+}
+
+// Given a pointer to the 'u' or 'U' starting a Unicode escape sequence, attempt
+// to parse that sequence. On success, returns a pointer to the first char
+// beyond that sequence, and fills in *code_point. On failure, returns ptr
+// itself.
+static const char* FetchUnicodePoint(const char* ptr, uint32* code_point) {
+ const char* p = ptr;
+ // Fetch the code point.
+ const int len = UnicodeLength(*p++);
+ if (!ReadHexDigits(p, len, code_point))
+ return ptr;
+ p += len;
+
+ // Check if the code point we read is a "head surrogate." If so, then we
+ // expect it to be immediately followed by another code point which is a valid
+ // "trail surrogate," and together they form a UTF-16 pair which decodes into
+ // a single Unicode point. Trail surrogates may only use \u, not \U.
+ if (IsHeadSurrogate(*code_point) && *p == '\\' && *(p + 1) == 'u') {
+ uint32 trail_surrogate;
+ if (ReadHexDigits(p + 2, 4, &trail_surrogate) &&
+ IsTrailSurrogate(trail_surrogate)) {
+ *code_point = AssembleUTF16(*code_point, trail_surrogate);
+ p += 6;
+ }
+ // If this failed, then we just emit the head surrogate as a code point.
+ // It's bogus, but so is the string.
+ }
+
+ return p;
+}
+
+// The text string must begin and end with single or double quote
+// characters.
void Tokenizer::ParseStringAppend(const string& text, string* output) {
- // Reminder: text[0] is always the quote character. (If text is
- // empty, it's invalid, so we'll just return.)
- if (text.empty()) {
+ // Reminder: text[0] is always a quote character. (If text is
+ // empty, it's invalid, so we'll just return).
+ const size_t text_size = text.size();
+ if (text_size == 0) {
GOOGLE_LOG(DFATAL)
<< " Tokenizer::ParseStringAppend() passed text that could not"
" have been tokenized as a string: " << CEscape(text);
return;
}
- output->reserve(output->size() + text.size());
+ // Reserve room for new string. The branch is necessary because if
+ // there is already space available the reserve() call might
+ // downsize the output.
+ const size_t new_len = text_size + output->size();
+ if (new_len > output->capacity()) {
+ output->reserve(new_len);
+ }
// Loop through the string copying characters to "output" and
// interpreting escape sequences. Note that any invalid escape
@@ -671,19 +1079,47 @@ void Tokenizer::ParseStringAppend(const string& text, string* output) {
}
output->push_back(static_cast<char>(code));
+ } else if (*ptr == 'u' || *ptr == 'U') {
+ uint32 unicode;
+ const char* end = FetchUnicodePoint(ptr, &unicode);
+ if (end == ptr) {
+ // Failure: Just dump out what we saw, don't try to parse it.
+ output->push_back(*ptr);
+ } else {
+ AppendUTF8(unicode, output);
+ ptr = end - 1; // Because we're about to ++ptr.
+ }
} else {
// Some other escape code.
output->push_back(TranslateEscape(*ptr));
}
- } else if (*ptr == text[0]) {
- // Ignore quote matching the starting quote.
+ } else if (*ptr == text[0] && ptr[1] == '\0') {
+ // Ignore final quote matching the starting quote.
} else {
output->push_back(*ptr);
}
}
+}
- return;
+template<typename CharacterClass>
+static bool AllInClass(const string& s) {
+ for (int i = 0; i < s.size(); ++i) {
+ if (!CharacterClass::InClass(s[i]))
+ return false;
+ }
+ return true;
+}
+
+bool Tokenizer::IsIdentifier(const string& text) {
+ // Mirrors IDENTIFIER definition in Tokenizer::Next() above.
+ if (text.size() == 0)
+ return false;
+ if (!Letter::InClass(text.at(0)))
+ return false;
+ if (!AllInClass<Alphanumeric>(text.substr(1)))
+ return false;
+ return true;
}
} // namespace io
diff --git a/src/google/protobuf/io/tokenizer.h b/src/google/protobuf/io/tokenizer.h
index d115161..8c6220a 100644
--- a/src/google/protobuf/io/tokenizer.h
+++ b/src/google/protobuf/io/tokenizer.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -38,6 +38,7 @@
#define GOOGLE_PROTOBUF_IO_TOKENIZER_H__
#include <string>
+#include <vector>
#include <google/protobuf/stubs/common.h>
namespace google {
@@ -66,7 +67,8 @@ class LIBPROTOBUF_EXPORT ErrorCollector {
// 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 */, int /* column */,
+ const string& /* message */) { }
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector);
@@ -122,16 +124,68 @@ class LIBPROTOBUF_EXPORT Tokenizer {
// the token within the input stream. They are zero-based.
int line;
int column;
+ int end_column;
};
// Get the current token. This is updated when Next() is called. Before
// the first call to Next(), current() has type TYPE_START and no contents.
const Token& current();
+ // Return the previous token -- i.e. what current() returned before the
+ // previous call to Next().
+ const Token& previous();
+
// Advance to the next token. Returns false if the end of the input is
// reached.
bool Next();
+ // Like Next(), but also collects comments which appear between the previous
+ // and next tokens.
+ //
+ // Comments which appear to be attached to the previous token are stored
+ // in *prev_tailing_comments. Comments which appear to be attached to the
+ // next token are stored in *next_leading_comments. Comments appearing in
+ // between which do not appear to be attached to either will be added to
+ // detached_comments. Any of these parameters can be NULL to simply discard
+ // the comments.
+ //
+ // 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 returned; 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. This is not attached to qux or corge
+ // // because there are blank lines separating it from both.
+ //
+ // optional string corge = 5;
+ // /* Block comment attached
+ // * to corge. Leading asterisks
+ // * will be removed. */
+ // /* Block comment attached to
+ // * grault. */
+ // optional int32 grault = 6;
+ bool NextWithComments(string* prev_trailing_comments,
+ vector<string>* detached_comments,
+ string* next_leading_comments);
+
// Parse helpers ---------------------------------------------------
// Parses a TYPE_FLOAT token. This never fails, so long as the text actually
@@ -175,11 +229,27 @@ class LIBPROTOBUF_EXPORT Tokenizer {
// Sets the comment style.
void set_comment_style(CommentStyle style) { comment_style_ = style; }
+ // Whether to require whitespace between a number and a field name.
+ // Default is true. Do not use this; for Google-internal cleanup only.
+ void set_require_space_after_number(bool require) {
+ require_space_after_number_ = require;
+ }
+
+ // Whether to allow string literals to span multiple lines. Default is false.
+ // Do not use this; for Google-internal cleanup only.
+ void set_allow_multiline_strings(bool allow) {
+ allow_multiline_strings_ = allow;
+ }
+
+ // External helper: validate an identifier.
+ static bool IsIdentifier(const string& text);
+
// -----------------------------------------------------------------
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer);
Token current_; // Returned by current().
+ Token previous_; // Returned by previous().
ZeroCopyInputStream* input_;
ErrorCollector* error_collector_;
@@ -194,15 +264,18 @@ class LIBPROTOBUF_EXPORT Tokenizer {
int line_;
int column_;
- // Position in buffer_ where StartToken() was called. If the token
- // started in the previous buffer, this is zero, and current_.text already
- // contains the part of the token from the previous buffer. If not
- // currently parsing a token, this is -1.
- int token_start_;
+ // String to which text should be appended as we advance through it.
+ // Call RecordTo(&str) to start recording and StopRecording() to stop.
+ // E.g. StartToken() calls RecordTo(&current_.text). record_start_ is the
+ // position within the current buffer where recording started.
+ string* record_target_;
+ int record_start_;
// Options.
bool allow_f_after_float_;
CommentStyle comment_style_;
+ bool require_space_after_number_;
+ bool allow_multiline_strings_;
// 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.
@@ -217,6 +290,9 @@ class LIBPROTOBUF_EXPORT Tokenizer {
// Read a new buffer from the input.
void Refresh();
+ inline void RecordTo(string* target);
+ inline void StopRecording();
+
// Called when the current character is the first character of a new
// token (not including whitespace or comments).
inline void StartToken();
@@ -249,9 +325,28 @@ class LIBPROTOBUF_EXPORT Tokenizer {
TokenType ConsumeNumber(bool started_with_zero, bool started_with_dot);
// Consume the rest of a line.
- void ConsumeLineComment();
+ void ConsumeLineComment(string* content);
// Consume until "*/".
- void ConsumeBlockComment();
+ void ConsumeBlockComment(string* content);
+
+ enum NextCommentStatus {
+ // Started a line comment.
+ LINE_COMMENT,
+
+ // Started a block comment.
+ BLOCK_COMMENT,
+
+ // Consumed a slash, then realized it wasn't a comment. current_ has
+ // been filled in with a slash token. The caller should return it.
+ SLASH_NOT_COMMENT,
+
+ // We do not appear to be starting a comment here.
+ NO_COMMENT
+ };
+
+ // If we're at the start of a new comment, consume it and return what kind
+ // of comment it is.
+ NextCommentStatus TryConsumeCommentStart();
// -----------------------------------------------------------------
// These helper methods make the parsing code more readable. The
@@ -291,6 +386,10 @@ inline const Tokenizer::Token& Tokenizer::current() {
return current_;
}
+inline const Tokenizer::Token& Tokenizer::previous() {
+ return previous_;
+}
+
inline void Tokenizer::ParseString(const string& text, string* output) {
output->clear();
ParseStringAppend(text, output);
diff --git a/src/google/protobuf/io/tokenizer_unittest.cc b/src/google/protobuf/io/tokenizer_unittest.cc
index 358ec56..de096fb 100644
--- a/src/google/protobuf/io/tokenizer_unittest.cc
+++ b/src/google/protobuf/io/tokenizer_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,9 +32,10 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
-#include <vector>
-#include <math.h>
#include <limits.h>
+#include <math.h>
+
+#include <vector>
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
@@ -257,6 +258,7 @@ TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) {
EXPECT_EQ("", tokenizer.current().text);
EXPECT_EQ(0, tokenizer.current().line);
EXPECT_EQ(0, tokenizer.current().column);
+ EXPECT_EQ(0, tokenizer.current().end_column);
// Parse the token.
ASSERT_TRUE(tokenizer.Next());
@@ -268,6 +270,8 @@ TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) {
// Check that it is located at the beginning of the input
EXPECT_EQ(0, tokenizer.current().line);
EXPECT_EQ(0, tokenizer.current().column);
+ EXPECT_EQ(kSimpleTokenCases_case.input.size(),
+ tokenizer.current().end_column);
// There should be no more input.
EXPECT_FALSE(tokenizer.Next());
@@ -277,6 +281,8 @@ TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) {
EXPECT_EQ("", tokenizer.current().text);
EXPECT_EQ(0, tokenizer.current().line);
EXPECT_EQ(kSimpleTokenCases_case.input.size(), tokenizer.current().column);
+ EXPECT_EQ(kSimpleTokenCases_case.input.size(),
+ tokenizer.current().end_column);
// There should be no errors.
EXPECT_TRUE(error_collector.text_.empty());
@@ -339,76 +345,77 @@ MultiTokenCase kMultiTokenCases[] = {
// Test all token types at the same time.
{ "foo 1 1.2 + 'bar'", {
- { Tokenizer::TYPE_IDENTIFIER, "foo" , 0, 0 },
- { Tokenizer::TYPE_INTEGER , "1" , 0, 4 },
- { Tokenizer::TYPE_FLOAT , "1.2" , 0, 6 },
- { Tokenizer::TYPE_SYMBOL , "+" , 0, 10 },
- { Tokenizer::TYPE_STRING , "'bar'", 0, 12 },
- { Tokenizer::TYPE_END , "" , 0, 17 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo" , 0, 0, 3 },
+ { Tokenizer::TYPE_INTEGER , "1" , 0, 4, 5 },
+ { Tokenizer::TYPE_FLOAT , "1.2" , 0, 6, 9 },
+ { Tokenizer::TYPE_SYMBOL , "+" , 0, 10, 11 },
+ { Tokenizer::TYPE_STRING , "'bar'", 0, 12, 17 },
+ { Tokenizer::TYPE_END , "" , 0, 17, 17 },
}},
// Test that consecutive symbols are parsed as separate tokens.
{ "!@+%", {
- { Tokenizer::TYPE_SYMBOL , "!" , 0, 0 },
- { Tokenizer::TYPE_SYMBOL , "@" , 0, 1 },
- { Tokenizer::TYPE_SYMBOL , "+" , 0, 2 },
- { Tokenizer::TYPE_SYMBOL , "%" , 0, 3 },
- { Tokenizer::TYPE_END , "" , 0, 4 },
+ { Tokenizer::TYPE_SYMBOL , "!" , 0, 0, 1 },
+ { Tokenizer::TYPE_SYMBOL , "@" , 0, 1, 2 },
+ { Tokenizer::TYPE_SYMBOL , "+" , 0, 2, 3 },
+ { Tokenizer::TYPE_SYMBOL , "%" , 0, 3, 4 },
+ { Tokenizer::TYPE_END , "" , 0, 4, 4 },
}},
// Test that newlines affect line numbers correctly.
{ "foo bar\nrab oof", {
- { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 },
- { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 4 },
- { Tokenizer::TYPE_IDENTIFIER, "rab", 1, 0 },
- { Tokenizer::TYPE_IDENTIFIER, "oof", 1, 4 },
- { Tokenizer::TYPE_END , "" , 1, 7 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 4, 7 },
+ { Tokenizer::TYPE_IDENTIFIER, "rab", 1, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "oof", 1, 4, 7 },
+ { Tokenizer::TYPE_END , "" , 1, 7, 7 },
}},
// Test that tabs affect column numbers correctly.
{ "foo\tbar \tbaz", {
- { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 },
- { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 8 },
- { Tokenizer::TYPE_IDENTIFIER, "baz", 0, 16 },
- { Tokenizer::TYPE_END , "" , 0, 19 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 8, 11 },
+ { Tokenizer::TYPE_IDENTIFIER, "baz", 0, 16, 19 },
+ { Tokenizer::TYPE_END , "" , 0, 19, 19 },
+ }},
+
+ // Test that tabs in string literals affect column numbers correctly.
+ { "\"foo\tbar\" baz", {
+ { Tokenizer::TYPE_STRING , "\"foo\tbar\"", 0, 0, 12 },
+ { Tokenizer::TYPE_IDENTIFIER, "baz" , 0, 13, 16 },
+ { Tokenizer::TYPE_END , "" , 0, 16, 16 },
}},
// Test that line comments are ignored.
{ "foo // This is a comment\n"
"bar // This is another comment", {
- { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 },
- { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 0 },
- { Tokenizer::TYPE_END , "" , 1, 30 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 0, 3 },
+ { Tokenizer::TYPE_END , "" , 1, 30, 30 },
}},
// Test that block comments are ignored.
{ "foo /* This is a block comment */ bar", {
- { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 },
- { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 34 },
- { Tokenizer::TYPE_END , "" , 0, 37 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 34, 37 },
+ { Tokenizer::TYPE_END , "" , 0, 37, 37 },
}},
// Test that sh-style comments are not ignored by default.
{ "foo # bar\n"
"baz", {
- { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 },
- { Tokenizer::TYPE_SYMBOL , "#" , 0, 4 },
- { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6 },
- { Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0 },
- { Tokenizer::TYPE_END , "" , 1, 3 },
- }},
-
- // Bytes with the high-order bit set should not be seen as control characters.
- { "\300", {
- { Tokenizer::TYPE_SYMBOL, "\300", 0, 0 },
- { Tokenizer::TYPE_END , "" , 0, 1 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_SYMBOL , "#" , 0, 4, 5 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6, 9 },
+ { Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0, 3 },
+ { Tokenizer::TYPE_END , "" , 1, 3, 3 },
}},
// Test all whitespace chars
{ "foo\n\t\r\v\fbar", {
- { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 },
- { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11 },
- { Tokenizer::TYPE_END , "" , 1, 14 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11, 14 },
+ { Tokenizer::TYPE_END , "" , 1, 14, 14 },
}},
};
@@ -425,6 +432,7 @@ TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) {
EXPECT_EQ("", tokenizer.current().text);
EXPECT_EQ(0, tokenizer.current().line);
EXPECT_EQ(0, tokenizer.current().column);
+ EXPECT_EQ(0, tokenizer.current().end_column);
// Loop through all expected tokens.
int i = 0;
@@ -434,6 +442,8 @@ TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) {
SCOPED_TRACE(testing::Message() << "Token #" << i << ": " << token.text);
+ Tokenizer::Token previous = tokenizer.current();
+
// Next() should only return false when it hits the end token.
if (token.type != Tokenizer::TYPE_END) {
ASSERT_TRUE(tokenizer.Next());
@@ -441,11 +451,19 @@ TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) {
ASSERT_FALSE(tokenizer.Next());
}
+ // Check that the previous token is set correctly.
+ EXPECT_EQ(previous.type, tokenizer.previous().type);
+ EXPECT_EQ(previous.text, tokenizer.previous().text);
+ EXPECT_EQ(previous.line, tokenizer.previous().line);
+ EXPECT_EQ(previous.column, tokenizer.previous().column);
+ EXPECT_EQ(previous.end_column, tokenizer.previous().end_column);
+
// Check that the token matches the expected one.
EXPECT_EQ(token.type, tokenizer.current().type);
EXPECT_EQ(token.text, tokenizer.current().text);
EXPECT_EQ(token.line, tokenizer.current().line);
EXPECT_EQ(token.column, tokenizer.current().column);
+ EXPECT_EQ(token.end_column, tokenizer.current().end_column);
} while (token.type != Tokenizer::TYPE_END);
@@ -491,6 +509,217 @@ TEST_1D(TokenizerTest, ShCommentStyle, kBlockSizes) {
// -------------------------------------------------------------------
+// In each case, the input is expected to have two tokens named "prev" and
+// "next" with comments in between.
+struct DocCommentCase {
+ string input;
+
+ const char* prev_trailing_comments;
+ const char* detached_comments[10];
+ const char* next_leading_comments;
+};
+
+inline ostream& operator<<(ostream& out,
+ const DocCommentCase& test_case) {
+ return out << CEscape(test_case.input);
+}
+
+DocCommentCase kDocCommentCases[] = {
+ {
+ "prev next",
+
+ "",
+ {},
+ ""
+ },
+
+ {
+ "prev /* ignored */ next",
+
+ "",
+ {},
+ ""
+ },
+
+ {
+ "prev // trailing comment\n"
+ "next",
+
+ " trailing comment\n",
+ {},
+ ""
+ },
+
+ {
+ "prev\n"
+ "// leading comment\n"
+ "// line 2\n"
+ "next",
+
+ "",
+ {},
+ " leading comment\n"
+ " line 2\n"
+ },
+
+ {
+ "prev\n"
+ "// trailing comment\n"
+ "// line 2\n"
+ "\n"
+ "next",
+
+ " trailing comment\n"
+ " line 2\n",
+ {},
+ ""
+ },
+
+ {
+ "prev // trailing comment\n"
+ "// leading comment\n"
+ "// line 2\n"
+ "next",
+
+ " trailing comment\n",
+ {},
+ " leading comment\n"
+ " line 2\n"
+ },
+
+ {
+ "prev /* trailing block comment */\n"
+ "/* leading block comment\n"
+ " * line 2\n"
+ " * line 3 */"
+ "next",
+
+ " trailing block comment ",
+ {},
+ " leading block comment\n"
+ " line 2\n"
+ " line 3 "
+ },
+
+ {
+ "prev\n"
+ "/* trailing block comment\n"
+ " * line 2\n"
+ " * line 3\n"
+ " */\n"
+ "/* leading block comment\n"
+ " * line 2\n"
+ " * line 3 */"
+ "next",
+
+ " trailing block comment\n"
+ " line 2\n"
+ " line 3\n",
+ {},
+ " leading block comment\n"
+ " line 2\n"
+ " line 3 "
+ },
+
+ {
+ "prev\n"
+ "// trailing comment\n"
+ "\n"
+ "// detached comment\n"
+ "// line 2\n"
+ "\n"
+ "// second detached comment\n"
+ "/* third detached comment\n"
+ " * line 2 */\n"
+ "// leading comment\n"
+ "next",
+
+ " trailing comment\n",
+ {
+ " detached comment\n"
+ " line 2\n",
+ " second detached comment\n",
+ " third detached comment\n"
+ " line 2 "
+ },
+ " leading comment\n"
+ },
+
+ {
+ "prev /**/\n"
+ "\n"
+ "// detached comment\n"
+ "\n"
+ "// leading comment\n"
+ "next",
+
+ "",
+ {
+ " detached comment\n"
+ },
+ " leading comment\n"
+ },
+
+ {
+ "prev /**/\n"
+ "// leading comment\n"
+ "next",
+
+ "",
+ {},
+ " leading comment\n"
+ },
+ };
+
+TEST_2D(TokenizerTest, DocComments, kDocCommentCases, kBlockSizes) {
+ // Set up the tokenizer.
+ TestInputStream input(kDocCommentCases_case.input.data(),
+ kDocCommentCases_case.input.size(),
+ kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+
+ // Set up a second tokenizer where we'll pass all NULLs to NextWithComments().
+ TestInputStream input2(kDocCommentCases_case.input.data(),
+ kDocCommentCases_case.input.size(),
+ kBlockSizes_case);
+ Tokenizer tokenizer2(&input2, &error_collector);
+
+ tokenizer.Next();
+ tokenizer2.Next();
+
+ EXPECT_EQ("prev", tokenizer.current().text);
+ EXPECT_EQ("prev", tokenizer2.current().text);
+
+ string prev_trailing_comments;
+ vector<string> detached_comments;
+ string next_leading_comments;
+ tokenizer.NextWithComments(&prev_trailing_comments, &detached_comments,
+ &next_leading_comments);
+ tokenizer2.NextWithComments(NULL, NULL, NULL);
+ EXPECT_EQ("next", tokenizer.current().text);
+ EXPECT_EQ("next", tokenizer2.current().text);
+
+ EXPECT_EQ(kDocCommentCases_case.prev_trailing_comments,
+ prev_trailing_comments);
+
+ for (int i = 0; i < detached_comments.size(); i++) {
+ ASSERT_LT(i, GOOGLE_ARRAYSIZE(kDocCommentCases));
+ ASSERT_TRUE(kDocCommentCases_case.detached_comments[i] != NULL);
+ EXPECT_EQ(kDocCommentCases_case.detached_comments[i],
+ detached_comments[i]);
+ }
+
+ // Verify that we matched all the detached comments.
+ EXPECT_EQ(NULL,
+ kDocCommentCases_case.detached_comments[detached_comments.size()]);
+
+ EXPECT_EQ(kDocCommentCases_case.next_leading_comments,
+ next_leading_comments);
+}
+
+// -------------------------------------------------------------------
+
// Test parse helpers. It's not really worth setting up a full data-driven
// test here.
TEST_F(TokenizerTest, ParseInteger) {
@@ -506,7 +735,7 @@ TEST_F(TokenizerTest, ParseInteger) {
EXPECT_EQ(0, ParseInteger("0x"));
uint64 i;
-#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet
+#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");
@@ -518,7 +747,7 @@ TEST_F(TokenizerTest, ParseInteger) {
"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 // GTEST_HAS_DEATH_TEST
+#endif // PROTOBUF_HAS_DEATH_TEST
// Test overflows.
EXPECT_TRUE (Tokenizer::ParseInteger("0", 0, &i));
@@ -561,7 +790,7 @@ TEST_F(TokenizerTest, ParseFloat) {
EXPECT_EQ( 0.0, Tokenizer::ParseFloat("1e-9999999999999999999999999999"));
EXPECT_EQ(HUGE_VAL, Tokenizer::ParseFloat("1e+9999999999999999999999999999"));
-#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet
+#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::ParseFloat("zxy"),
"passed text that could not have been tokenized as a float");
@@ -569,7 +798,7 @@ TEST_F(TokenizerTest, ParseFloat) {
"passed text that could not have been tokenized as a float");
EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("-1.0"),
"passed text that could not have been tokenized as a float");
-#endif // GTEST_HAS_DEATH_TEST
+#endif // PROTOBUF_HAS_DEATH_TEST
}
TEST_F(TokenizerTest, ParseString) {
@@ -591,11 +820,27 @@ TEST_F(TokenizerTest, ParseString) {
Tokenizer::ParseString("'\\", &output);
EXPECT_EQ("\\", output);
+ // Experiment with Unicode escapes. Here are one-, two- and three-byte Unicode
+ // characters.
+ Tokenizer::ParseString("'\\u0024\\u00a2\\u20ac\\U00024b62XX'", &output);
+ EXPECT_EQ("$¢€𤭢XX", output);
+ // Same thing encoded using UTF16.
+ Tokenizer::ParseString("'\\u0024\\u00a2\\u20ac\\ud852\\udf62XX'", &output);
+ EXPECT_EQ("$¢€𤭢XX", output);
+ // Here's some broken UTF16; there's a head surrogate with no tail surrogate.
+ // We just output this as if it were UTF8; it's not a defined code point, but
+ // it has a defined encoding.
+ Tokenizer::ParseString("'\\ud852XX'", &output);
+ EXPECT_EQ("\xed\xa1\x92XX", output);
+ // Malformed escape: Demons may fly out of the nose.
+ Tokenizer::ParseString("\\u0", &output);
+ EXPECT_EQ("u0", output);
+
// Test invalid strings that will never be tokenized as strings.
-#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet
+#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet
EXPECT_DEBUG_DEATH(Tokenizer::ParseString("", &output),
"passed text that could not have been tokenized as a string");
-#endif // GTEST_HAS_DEATH_TEST
+#endif // PROTOBUF_HAS_DEATH_TEST
}
TEST_F(TokenizerTest, ParseStringAppend) {
@@ -632,9 +877,15 @@ ErrorCase kErrorCases[] = {
{ "'\\x' foo", true,
"0:3: Expected hex digits for escape sequence.\n" },
{ "'foo", false,
- "0:4: String literals cannot cross line boundaries.\n" },
+ "0:4: Unexpected end of string.\n" },
{ "'bar\nfoo", true,
"0:4: String literals cannot cross line boundaries.\n" },
+ { "'\\u01' foo", true,
+ "0:5: Expected four hex digits for \\u escape sequence.\n" },
+ { "'\\u01' foo", true,
+ "0:5: Expected four hex digits for \\u escape sequence.\n" },
+ { "'\\uXYZ' foo", true,
+ "0:3: Expected four hex digits for \\u escape sequence.\n" },
// Integer errors.
{ "123foo", true,
@@ -694,6 +945,10 @@ ErrorCase kErrorCases[] = {
"0:0: Invalid control characters encountered in text.\n" },
{ string("\0\0foo", 5), true,
"0:0: Invalid control characters encountered in text.\n" },
+
+ // Check error from high order bits set
+ { "\300foo", true,
+ "0:0: Interpreting non ascii codepoint 192.\n" },
};
TEST_2D(TokenizerTest, Errors, kErrorCases, kBlockSizes) {
@@ -711,7 +966,7 @@ TEST_2D(TokenizerTest, Errors, kErrorCases, kBlockSizes) {
}
// Check that the errors match what was expected.
- EXPECT_EQ(error_collector.text_, kErrorCases_case.errors);
+ EXPECT_EQ(kErrorCases_case.errors, error_collector.text_);
// If the error was recoverable, make sure we saw "foo" after it.
if (kErrorCases_case.recoverable) {
@@ -737,6 +992,7 @@ TEST_1D(TokenizerTest, BackUpOnDestruction, kBlockSizes) {
EXPECT_EQ(strlen("foo"), input.ByteCount());
}
+
} // namespace
} // namespace io
} // namespace protobuf
diff --git a/src/google/protobuf/io/zero_copy_stream.cc b/src/google/protobuf/io/zero_copy_stream.cc
index dad6ff1..f77c768 100644
--- a/src/google/protobuf/io/zero_copy_stream.cc
+++ b/src/google/protobuf/io/zero_copy_stream.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -34,6 +34,7 @@
#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
@@ -43,6 +44,14 @@ ZeroCopyInputStream::~ZeroCopyInputStream() {}
ZeroCopyOutputStream::~ZeroCopyOutputStream() {}
+bool ZeroCopyOutputStream::WriteAliasedRaw(const void* /* data */,
+ int /* size */) {
+ GOOGLE_LOG(FATAL) << "This ZeroCopyOutputStream doesn't support aliasing. "
+ "Reaching here usually means a ZeroCopyOutputStream "
+ "implementation bug.";
+ return false;
+}
+
} // namespace io
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/io/zero_copy_stream.h b/src/google/protobuf/io/zero_copy_stream.h
index db5326f..52650fc 100644
--- a/src/google/protobuf/io/zero_copy_stream.h
+++ b/src/google/protobuf/io/zero_copy_stream.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -226,6 +226,16 @@ class LIBPROTOBUF_EXPORT ZeroCopyOutputStream {
// Returns the total number of bytes written since this object was created.
virtual int64 ByteCount() const = 0;
+ // Write a given chunk of data to the output. Some output streams may
+ // implement this in a way that avoids copying. Check AllowsAliasing() before
+ // calling WriteAliasedRaw(). It will GOOGLE_CHECK fail if WriteAliasedRaw() is
+ // called on a stream that does not allow aliasing.
+ //
+ // NOTE: It is caller's responsibility to ensure that the chunk of memory
+ // remains live until all of the data has been consumed from the stream.
+ virtual bool WriteAliasedRaw(const void* data, int size);
+ virtual bool AllowsAliasing() const { return false; }
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream);
diff --git a/src/google/protobuf/io/zero_copy_stream_impl.cc b/src/google/protobuf/io/zero_copy_stream_impl.cc
index 1384c74..f7901b2 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl.cc
+++ b/src/google/protobuf/io/zero_copy_stream_impl.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -46,7 +46,8 @@
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/stl_util.h>
+
namespace google {
namespace protobuf {
@@ -412,7 +413,9 @@ int64 ConcatenatingInputStream::ByteCount() const {
LimitingInputStream::LimitingInputStream(ZeroCopyInputStream* input,
int64 limit)
- : input_(input), limit_(limit) {}
+ : input_(input), limit_(limit) {
+ prior_bytes_read_ = input_->ByteCount();
+}
LimitingInputStream::~LimitingInputStream() {
// If we overshot the limit, back up.
@@ -456,9 +459,9 @@ bool LimitingInputStream::Skip(int count) {
int64 LimitingInputStream::ByteCount() const {
if (limit_ < 0) {
- return input_->ByteCount() + limit_;
+ return input_->ByteCount() + limit_ - prior_bytes_read_;
} else {
- return input_->ByteCount();
+ return input_->ByteCount() - prior_bytes_read_;
}
}
diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h
index 9fedb00..0746fa6 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl.h
+++ b/src/google/protobuf/io/zero_copy_stream_impl.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -344,6 +344,7 @@ class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream {
private:
ZeroCopyInputStream* input_;
int64 limit_; // Decreases as we go, becomes negative if we overshoot.
+ int64 prior_bytes_read_; // Bytes read on underlying stream at construction
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream);
};
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 e801251..58aff0e 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
+++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,9 +32,13 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
-#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+
+#include <algorithm>
+#include <limits>
+
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
@@ -159,15 +163,23 @@ bool StringOutputStream::Next(void** data, int* size) {
// without a memory allocation this way.
STLStringResizeUninitialized(target_, target_->capacity());
} else {
- // Size has reached capacity, so double the size. Also make sure
- // that the new size is at least kMinimumSize.
+ // Size has reached capacity, try to double the size.
+ if (old_size > std::numeric_limits<int>::max() / 2) {
+ // Can not double the size otherwise it is going to cause integer
+ // overflow in the expression below: old_size * 2 ";
+ GOOGLE_LOG(ERROR) << "Cannot allocate buffer larger than kint32max for "
+ << "StringOutputStream.";
+ return false;
+ }
+ // Double the size, also make sure that the new size is at least
+ // kMinimumSize.
STLStringResizeUninitialized(
target_,
max(old_size * 2,
kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness.
}
- *data = string_as_array(target_) + old_size;
+ *data = mutable_string_data(target_) + old_size;
*size = target_->size() - old_size;
return true;
}
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 153f543..e18da72 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h
+++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -48,6 +48,7 @@
#include <iosfwd>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
@@ -333,6 +334,19 @@ class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStrea
// ===================================================================
+// Return a pointer to mutable characters underlying the given string. The
+// return value is valid until the next time the string is resized. We
+// trust the caller to treat the return value as an array of length s->size().
+inline char* mutable_string_data(string* s) {
+#ifdef LANG_CXX11
+ // This should be simpler & faster than string_as_array() because the latter
+ // is guaranteed to return NULL when *s is empty, so it has to check for that.
+ return &(*s)[0];
+#else
+ return string_as_array(s);
+#endif
+}
+
} // namespace io
} // namespace protobuf
diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc
index 8229ee6..bf978cc 100644
--- a/src/google/protobuf/io/zero_copy_stream_unittest.cc
+++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -61,6 +61,7 @@
#include <sstream>
#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/coded_stream.h>
#if HAVE_ZLIB
#include <google/protobuf/io/gzip_stream.h>
@@ -285,6 +286,57 @@ TEST_F(IoTest, ArrayIo) {
}
}
+TEST_F(IoTest, TwoSessionWrite) {
+ // Test that two concatenated write sessions read correctly
+
+ static const char* strA = "0123456789";
+ static const char* strB = "WhirledPeas";
+ const int kBufferSize = 2*1024;
+ uint8* buffer = new uint8[kBufferSize];
+ char* temp_buffer = new char[40];
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ ArrayOutputStream* output =
+ new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]);
+ CodedOutputStream* coded_output = new CodedOutputStream(output);
+ coded_output->WriteVarint32(strlen(strA));
+ coded_output->WriteRaw(strA, strlen(strA));
+ delete coded_output; // flush
+ int64 pos = output->ByteCount();
+ delete output;
+ output = new ArrayOutputStream(
+ buffer + pos, kBufferSize - pos, kBlockSizes[i]);
+ coded_output = new CodedOutputStream(output);
+ coded_output->WriteVarint32(strlen(strB));
+ coded_output->WriteRaw(strB, strlen(strB));
+ delete coded_output; // flush
+ int64 size = pos + output->ByteCount();
+ delete output;
+
+ ArrayInputStream* input =
+ new ArrayInputStream(buffer, size, kBlockSizes[j]);
+ CodedInputStream* coded_input = new CodedInputStream(input);
+ uint32 insize;
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strA), insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strA, insize));
+
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strB), insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strB, insize));
+
+ delete coded_input;
+ delete input;
+ }
+ }
+
+ delete [] temp_buffer;
+ delete [] buffer;
+}
+
#if HAVE_ZLIB
TEST_F(IoTest, GzipIo) {
const int kBufferSize = 2*1024;
@@ -296,9 +348,49 @@ TEST_F(IoTest, GzipIo) {
int size;
{
ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
- GzipOutputStream gzout(
- &output, GzipOutputStream::GZIP, gzip_buffer_size);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ gzout.Close();
+ size = output.ByteCount();
+ }
+ {
+ ArrayInputStream input(buffer, size, kBlockSizes[j]);
+ GzipInputStream gzin(
+ &input, GzipInputStream::GZIP, gzip_buffer_size);
+ ReadStuff(&gzin);
+ }
+ }
+ }
+ }
+ delete [] buffer;
+}
+
+TEST_F(IoTest, GzipIoWithFlush) {
+ const int kBufferSize = 2*1024;
+ uint8* buffer = new uint8[kBufferSize];
+ // We start with i = 4 as we want a block size > 6. With block size <= 6
+ // Flush() fills up the entire 2K buffer with flush markers and the test
+ // fails. See documentation for Flush() for more detail.
+ for (int i = 4; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ for (int z = 0; z < kBlockSizeCount; z++) {
+ int gzip_buffer_size = kBlockSizes[z];
+ int size;
+ {
+ ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+ GzipOutputStream gzout(&output, options);
WriteStuff(&gzout);
+ EXPECT_TRUE(gzout.Flush());
gzout.Close();
size = output.ByteCount();
}
@@ -314,6 +406,64 @@ TEST_F(IoTest, GzipIo) {
delete [] buffer;
}
+TEST_F(IoTest, GzipIoContiguousFlushes) {
+ const int kBufferSize = 2*1024;
+ uint8* buffer = new uint8[kBufferSize];
+
+ int block_size = kBlockSizes[4];
+ int gzip_buffer_size = block_size;
+ int size;
+
+ ArrayOutputStream output(buffer, kBufferSize, block_size);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ EXPECT_TRUE(gzout.Flush());
+ EXPECT_TRUE(gzout.Flush());
+ gzout.Close();
+ size = output.ByteCount();
+
+ ArrayInputStream input(buffer, size, block_size);
+ GzipInputStream gzin(
+ &input, GzipInputStream::GZIP, gzip_buffer_size);
+ ReadStuff(&gzin);
+
+ delete [] buffer;
+}
+
+TEST_F(IoTest, GzipIoReadAfterFlush) {
+ const int kBufferSize = 2*1024;
+ uint8* buffer = new uint8[kBufferSize];
+
+ int block_size = kBlockSizes[4];
+ int gzip_buffer_size = block_size;
+ int size;
+ ArrayOutputStream output(buffer, kBufferSize, block_size);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ EXPECT_TRUE(gzout.Flush());
+ size = output.ByteCount();
+
+ ArrayInputStream input(buffer, size, block_size);
+ GzipInputStream gzin(
+ &input, GzipInputStream::GZIP, gzip_buffer_size);
+ ReadStuff(&gzin);
+
+ gzout.Close();
+
+ delete [] buffer;
+}
+
TEST_F(IoTest, ZlibIo) {
const int kBufferSize = 2*1024;
uint8* buffer = new uint8[kBufferSize];
@@ -324,8 +474,12 @@ TEST_F(IoTest, ZlibIo) {
int size;
{
ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
- GzipOutputStream gzout(
- &output, GzipOutputStream::ZLIB, gzip_buffer_size);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::ZLIB;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+ GzipOutputStream gzout(&output, options);
WriteStuff(&gzout);
gzout.Close();
size = output.ByteCount();
@@ -348,7 +502,9 @@ TEST_F(IoTest, ZlibIoInputAutodetect) {
int size;
{
ArrayOutputStream output(buffer, kBufferSize);
- GzipOutputStream gzout(&output, GzipOutputStream::ZLIB);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::ZLIB;
+ GzipOutputStream gzout(&output, options);
WriteStuff(&gzout);
gzout.Close();
size = output.ByteCount();
@@ -360,7 +516,9 @@ TEST_F(IoTest, ZlibIoInputAutodetect) {
}
{
ArrayOutputStream output(buffer, kBufferSize);
- GzipOutputStream gzout(&output, GzipOutputStream::GZIP);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ GzipOutputStream gzout(&output, options);
WriteStuff(&gzout);
gzout.Close();
size = output.ByteCount();
@@ -402,9 +560,10 @@ TEST_F(IoTest, CompressionOptions) {
// Some ad-hoc testing of compression options.
string golden;
- File::ReadFileToStringOrDie(
- TestSourceDir() + "/google/protobuf/testdata/golden_message",
- &golden);
+ GOOGLE_CHECK_OK(File::GetContents(
+ TestSourceDir() +
+ "/google/protobuf/testdata/golden_message",
+ &golden, true));
GzipOutputStream::Options options;
string gzip_compressed = Compress(golden, options);
@@ -432,6 +591,71 @@ TEST_F(IoTest, CompressionOptions) {
EXPECT_TRUE(Uncompress(gzip_compressed) == golden);
EXPECT_TRUE(Uncompress(zlib_compressed) == golden);
}
+
+TEST_F(IoTest, TwoSessionWriteGzip) {
+ // Test that two concatenated gzip streams can be read correctly
+
+ static const char* strA = "0123456789";
+ static const char* strB = "QuickBrownFox";
+ const int kBufferSize = 2*1024;
+ uint8* buffer = new uint8[kBufferSize];
+ char* temp_buffer = new char[40];
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ ArrayOutputStream* output =
+ new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]);
+ GzipOutputStream* gzout = new GzipOutputStream(output);
+ CodedOutputStream* coded_output = new CodedOutputStream(gzout);
+ int32 outlen = strlen(strA) + 1;
+ coded_output->WriteVarint32(outlen);
+ coded_output->WriteRaw(strA, outlen);
+ delete coded_output; // flush
+ delete gzout; // flush
+ int64 pos = output->ByteCount();
+ delete output;
+ output = new ArrayOutputStream(
+ buffer + pos, kBufferSize - pos, kBlockSizes[i]);
+ gzout = new GzipOutputStream(output);
+ coded_output = new CodedOutputStream(gzout);
+ outlen = strlen(strB) + 1;
+ coded_output->WriteVarint32(outlen);
+ coded_output->WriteRaw(strB, outlen);
+ delete coded_output; // flush
+ delete gzout; // flush
+ int64 size = pos + output->ByteCount();
+ delete output;
+
+ ArrayInputStream* input =
+ new ArrayInputStream(buffer, size, kBlockSizes[j]);
+ GzipInputStream* gzin = new GzipInputStream(input);
+ CodedInputStream* coded_input = new CodedInputStream(gzin);
+ uint32 insize;
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strA) + 1, insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strA, insize))
+ << "strA=" << strA << " in=" << temp_buffer;
+
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strB) + 1, insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strB, insize))
+ << " out_block_size=" << kBlockSizes[i]
+ << " in_block_size=" << kBlockSizes[j]
+ << " pos=" << pos
+ << " size=" << size
+ << " strB=" << strB << " in=" << temp_buffer;
+
+ delete coded_input;
+ delete gzin;
+ delete input;
+ }
+ }
+
+ delete [] temp_buffer;
+ delete [] buffer;
+}
#endif
// There is no string input, only string output. Also, it doesn't support
@@ -700,6 +924,26 @@ TEST_F(IoTest, LimitingInputStream) {
ReadStuff(&input);
}
+// Checks that ByteCount works correctly for LimitingInputStreams where the
+// underlying stream has already been read.
+TEST_F(IoTest, LimitingInputStreamByteCount) {
+ const int kHalfBufferSize = 128;
+ const int kBufferSize = kHalfBufferSize * 2;
+ uint8 buffer[kBufferSize];
+
+ // Set up input. Only allow half to be read at once.
+ ArrayInputStream array_input(buffer, kBufferSize, kHalfBufferSize);
+ const void* data;
+ int size;
+ EXPECT_TRUE(array_input.Next(&data, &size));
+ EXPECT_EQ(kHalfBufferSize, array_input.ByteCount());
+ // kHalfBufferSize - 1 to test limiting logic as well.
+ LimitingInputStream input(&array_input, kHalfBufferSize - 1);
+ EXPECT_EQ(0, input.ByteCount());
+ EXPECT_TRUE(input.Next(&data, &size));
+ EXPECT_EQ(kHalfBufferSize - 1 , input.ByteCount());
+}
+
// Check that a zero-size array doesn't confuse the code.
TEST(ZeroSizeArray, Input) {
ArrayInputStream input(NULL, 0);
diff --git a/src/google/protobuf/lite_unittest.cc b/src/google/protobuf/lite_unittest.cc
index ffeec3c..a370526 100644
--- a/src/google/protobuf/lite_unittest.cc
+++ b/src/google/protobuf/lite_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -33,13 +33,59 @@
#include <string>
#include <iostream>
-#include <google/protobuf/test_util_lite.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/test_util_lite.h>
+#include <google/protobuf/unittest_lite.pb.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/wire_format_lite_inl.h>
using namespace std;
+namespace {
+// Helper methods to test parsing merge behavior.
+void ExpectMessageMerged(const google::protobuf::unittest::TestAllTypesLite& message) {
+ GOOGLE_CHECK(message.optional_int32() == 3);
+ GOOGLE_CHECK(message.optional_int64() == 2);
+ GOOGLE_CHECK(message.optional_string() == "hello");
+}
+
+void AssignParsingMergeMessages(
+ google::protobuf::unittest::TestAllTypesLite* msg1,
+ google::protobuf::unittest::TestAllTypesLite* msg2,
+ google::protobuf::unittest::TestAllTypesLite* msg3) {
+ msg1->set_optional_int32(1);
+ msg2->set_optional_int64(2);
+ msg3->set_optional_int32(3);
+ msg3->set_optional_string("hello");
+}
+
+void SetAllTypesInEmptyMessageUnknownFields(
+ google::protobuf::unittest::TestEmptyMessageLite* empty_message) {
+ protobuf_unittest::TestAllTypesLite message;
+ google::protobuf::TestUtilLite::ExpectClear(message);
+ google::protobuf::TestUtilLite::SetAllFields(&message);
+ string data = message.SerializeAsString();
+ empty_message->ParseFromString(data);
+}
+
+void SetSomeTypesInEmptyMessageUnknownFields(
+ google::protobuf::unittest::TestEmptyMessageLite* empty_message) {
+ protobuf_unittest::TestAllTypesLite message;
+ google::protobuf::TestUtilLite::ExpectClear(message);
+ message.set_optional_int32(101);
+ message.set_optional_int64(102);
+ message.set_optional_uint32(103);
+ message.set_optional_uint64(104);
+ string data = message.SerializeAsString();
+ empty_message->ParseFromString(data);
+}
+
+} // namespace
+
int main(int argc, char* argv[]) {
- string data, packed_data;
+ string data, data2, packed_data;
{
protobuf_unittest::TestAllTypesLite message, message2, message3;
@@ -63,7 +109,6 @@ int main(int argc, char* argv[]) {
google::protobuf::TestUtilLite::SetAllExtensions(&message);
message2.CopyFrom(message);
string extensions_data = message.SerializeAsString();
- GOOGLE_CHECK(extensions_data == data);
message3.ParseFromString(extensions_data);
google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message);
google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2);
@@ -107,6 +152,199 @@ int main(int argc, char* argv[]) {
google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
}
+ {
+ // Test that if an optional or required message/group field appears multiple
+ // times in the input, they need to be merged.
+ google::protobuf::unittest::TestParsingMergeLite::RepeatedFieldsGenerator generator;
+ google::protobuf::unittest::TestAllTypesLite* msg1;
+ google::protobuf::unittest::TestAllTypesLite* msg2;
+ google::protobuf::unittest::TestAllTypesLite* msg3;
+
+#define ASSIGN_REPEATED_FIELD(FIELD) \
+ msg1 = generator.add_##FIELD(); \
+ msg2 = generator.add_##FIELD(); \
+ msg3 = generator.add_##FIELD(); \
+ AssignParsingMergeMessages(msg1, msg2, msg3)
+
+ ASSIGN_REPEATED_FIELD(field1);
+ ASSIGN_REPEATED_FIELD(field2);
+ ASSIGN_REPEATED_FIELD(field3);
+ ASSIGN_REPEATED_FIELD(ext1);
+ ASSIGN_REPEATED_FIELD(ext2);
+
+#undef ASSIGN_REPEATED_FIELD
+#define ASSIGN_REPEATED_GROUP(FIELD) \
+ msg1 = generator.add_##FIELD()->mutable_field1(); \
+ msg2 = generator.add_##FIELD()->mutable_field1(); \
+ msg3 = generator.add_##FIELD()->mutable_field1(); \
+ AssignParsingMergeMessages(msg1, msg2, msg3)
+
+ ASSIGN_REPEATED_GROUP(group1);
+ ASSIGN_REPEATED_GROUP(group2);
+
+#undef ASSIGN_REPEATED_GROUP
+
+ string buffer;
+ generator.SerializeToString(&buffer);
+ google::protobuf::unittest::TestParsingMergeLite parsing_merge;
+ parsing_merge.ParseFromString(buffer);
+
+ // Required and optional fields should be merged.
+ ExpectMessageMerged(parsing_merge.required_all_types());
+ ExpectMessageMerged(parsing_merge.optional_all_types());
+ ExpectMessageMerged(
+ parsing_merge.optionalgroup().optional_group_all_types());
+ ExpectMessageMerged(parsing_merge.GetExtension(
+ google::protobuf::unittest::TestParsingMergeLite::optional_ext));
+
+ // Repeated fields should not be merged.
+ GOOGLE_CHECK(parsing_merge.repeated_all_types_size() == 3);
+ GOOGLE_CHECK(parsing_merge.repeatedgroup_size() == 3);
+ GOOGLE_CHECK(parsing_merge.ExtensionSize(
+ google::protobuf::unittest::TestParsingMergeLite::repeated_ext) == 3);
+ }
+
+ // Test unknown fields support for lite messages.
+ {
+ protobuf_unittest::TestAllTypesLite message, message2;
+ protobuf_unittest::TestEmptyMessageLite empty_message;
+ google::protobuf::TestUtilLite::ExpectClear(message);
+ google::protobuf::TestUtilLite::SetAllFields(&message);
+ data = message.SerializeAsString();
+ empty_message.ParseFromString(data);
+ data.clear();
+ data = empty_message.SerializeAsString();
+ message2.ParseFromString(data);
+ data = message2.SerializeAsString();
+ google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2);
+ message.Clear();
+ google::protobuf::TestUtilLite::ExpectClear(message);
+ }
+
+ {
+ protobuf_unittest::TestAllExtensionsLite message, message2;
+ protobuf_unittest::TestEmptyMessageLite empty_message;
+ google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
+ google::protobuf::TestUtilLite::SetAllExtensions(&message);
+ data = message.SerializeAsString();
+ empty_message.ParseFromString(data);
+ data.clear();
+ data = empty_message.SerializeAsString();
+ message2.ParseFromString(data);
+ data = message2.SerializeAsString();
+ google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2);
+ message.Clear();
+ google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
+ }
+
+ {
+ protobuf_unittest::TestPackedTypesLite message, message2;
+ protobuf_unittest::TestEmptyMessageLite empty_message;
+ google::protobuf::TestUtilLite::ExpectPackedClear(message);
+ google::protobuf::TestUtilLite::SetPackedFields(&message);
+ data = message.SerializeAsString();
+ empty_message.ParseFromString(data);
+ data.clear();
+ data = empty_message.SerializeAsString();
+ message2.ParseFromString(data);
+ data = message2.SerializeAsString();
+ google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2);
+ message.Clear();
+ google::protobuf::TestUtilLite::ExpectPackedClear(message);
+ }
+
+ {
+ protobuf_unittest::TestPackedExtensionsLite message, message2;
+ protobuf_unittest::TestEmptyMessageLite empty_message;
+ google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
+ google::protobuf::TestUtilLite::SetPackedExtensions(&message);
+ data = message.SerializeAsString();
+ empty_message.ParseFromString(data);
+ data.clear();
+ data = empty_message.SerializeAsString();
+ message2.ParseFromString(data);
+ data = message2.SerializeAsString();
+ google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2);
+ message.Clear();
+ google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
+ }
+
+ {
+ // Test Unknown fields swap
+ protobuf_unittest::TestEmptyMessageLite empty_message, empty_message2;
+ SetAllTypesInEmptyMessageUnknownFields(&empty_message);
+ SetSomeTypesInEmptyMessageUnknownFields(&empty_message2);
+ data = empty_message.SerializeAsString();
+ data2 = empty_message2.SerializeAsString();
+ empty_message.Swap(&empty_message2);
+ GOOGLE_CHECK_EQ(data, empty_message2.SerializeAsString());
+ GOOGLE_CHECK_EQ(data2, empty_message.SerializeAsString());
+ }
+
+ {
+ // Test unknown fields swap with self
+ protobuf_unittest::TestEmptyMessageLite empty_message;
+ SetAllTypesInEmptyMessageUnknownFields(&empty_message);
+ data = empty_message.SerializeAsString();
+ empty_message.Swap(&empty_message);
+ GOOGLE_CHECK_EQ(data, empty_message.SerializeAsString());
+ }
+
+ {
+ // Test MergeFrom with unknown fields
+ protobuf_unittest::TestAllTypesLite message, message2;
+ protobuf_unittest::TestEmptyMessageLite empty_message, empty_message2;
+ message.set_optional_int32(101);
+ message.add_repeated_int32(201);
+ message.set_optional_nested_enum(google::protobuf::unittest::TestAllTypesLite::BAZ);
+ message2.set_optional_int64(102);
+ message2.add_repeated_int64(202);
+ message2.set_optional_foreign_enum(google::protobuf::unittest::FOREIGN_LITE_BAZ);
+
+ data = message.SerializeAsString();
+ empty_message.ParseFromString(data);
+ data = message2.SerializeAsString();
+ empty_message2.ParseFromString(data);
+ message.MergeFrom(message2);
+ empty_message.MergeFrom(empty_message2);
+
+ data = empty_message.SerializeAsString();
+ message2.ParseFromString(data);
+ // We do not compare the serialized output of a normal message and a lite
+ // message because the order of fields do not match. We convert lite message
+ // back into normal message, then compare.
+ GOOGLE_CHECK_EQ(message.SerializeAsString(), message2.SerializeAsString());
+ }
+
+ {
+ // Test unknown enum value
+ protobuf_unittest::TestAllTypesLite message;
+ string buffer;
+ {
+ google::protobuf::io::StringOutputStream output_stream(&buffer);
+ google::protobuf::io::CodedOutputStream coded_output(&output_stream);
+ google::protobuf::internal::WireFormatLite::WriteTag(
+ protobuf_unittest::TestAllTypesLite::kOptionalNestedEnumFieldNumber,
+ google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT, &coded_output);
+ coded_output.WriteVarint32(10);
+ google::protobuf::internal::WireFormatLite::WriteTag(
+ protobuf_unittest::TestAllTypesLite::kRepeatedNestedEnumFieldNumber,
+ google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT, &coded_output);
+ coded_output.WriteVarint32(20);
+ }
+ message.ParseFromString(buffer);
+ data = message.SerializeAsString();
+ GOOGLE_CHECK_EQ(data, buffer);
+ }
+
+ {
+ // Test Clear with unknown fields
+ protobuf_unittest::TestEmptyMessageLite empty_message;
+ SetAllTypesInEmptyMessageUnknownFields(&empty_message);
+ empty_message.Clear();
+ GOOGLE_CHECK_EQ(0, empty_message.unknown_fields().size());
+ }
+
cout << "PASS" << endl;
return 0;
}
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index 0409a94..1324ed9 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,7 +32,7 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
-#include <istream>
+#include <iostream>
#include <stack>
#include <google/protobuf/stubs/hash.h>
@@ -44,11 +44,12 @@
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/stubs/map-util.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
@@ -74,7 +75,7 @@ void Message::CheckTypeAndMergeFrom(const MessageLite& other) {
void Message::CopyFrom(const Message& from) {
const Descriptor* descriptor = GetDescriptor();
GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
- << ": Tried to copy from a message with a different type."
+ << ": Tried to copy from a message with a different type. "
"to: " << descriptor->full_name() << ", "
"from:" << from.GetDescriptor()->full_name();
ReflectionOps::Copy(from, this);
@@ -99,7 +100,7 @@ void Message::FindInitializationErrors(vector<string>* errors) const {
string Message::InitializationErrorString() const {
vector<string> errors;
FindInitializationErrors(&errors);
- return JoinStrings(errors, ", ");
+ return Join(errors, ", ");
}
void Message::CheckInitialized() const {
@@ -148,7 +149,7 @@ int Message::ByteSize() const {
return size;
}
-void Message::SetCachedSize(int size) const {
+void Message::SetCachedSize(int /* size */) const {
GOOGLE_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name()
<< "\" implements neither SetCachedSize() nor ByteSize(). "
"Must implement one or the other.";
@@ -182,9 +183,46 @@ bool Message::SerializePartialToOstream(ostream* output) const {
}
+// =============================================================================
+// Reflection and associated Template Specializations
+
Reflection::~Reflection() {}
-// ===================================================================
+#define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE) \
+template<> \
+const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>( \
+ const Message& message, const FieldDescriptor* field) const { \
+ return *static_cast<RepeatedField<TYPE>* >( \
+ MutableRawRepeatedField(const_cast<Message*>(&message), \
+ field, CPPTYPE, CTYPE, NULL)); \
+} \
+ \
+template<> \
+RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>( \
+ Message* message, const FieldDescriptor* field) const { \
+ return static_cast<RepeatedField<TYPE>* >( \
+ MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL)); \
+}
+
+HANDLE_TYPE(int32, FieldDescriptor::CPPTYPE_INT32, -1);
+HANDLE_TYPE(int64, FieldDescriptor::CPPTYPE_INT64, -1);
+HANDLE_TYPE(uint32, FieldDescriptor::CPPTYPE_UINT32, -1);
+HANDLE_TYPE(uint64, FieldDescriptor::CPPTYPE_UINT64, -1);
+HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1);
+HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1);
+HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1);
+
+
+#undef HANDLE_TYPE
+
+void* Reflection::MutableRawRepeatedString(
+ Message* message, const FieldDescriptor* field, bool is_string) const {
+ return MutableRawRepeatedField(message, field,
+ FieldDescriptor::CPPTYPE_STRING, FieldOptions::STRING, NULL);
+}
+
+
+// =============================================================================
// MessageFactory
MessageFactory::~MessageFactory() {}
@@ -258,6 +296,7 @@ void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor,
}
}
+
const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) {
{
ReaderMutexLock lock(&mutex_);
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index c0062f9..87a89ef 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -79,18 +79,19 @@
// // Same as the last block, but do it dynamically via the Message
// // reflection interface.
// Message* foo = new Foo;
-// Descriptor* descriptor = foo->GetDescriptor();
+// const Descriptor* descriptor = foo->GetDescriptor();
//
// // Get the descriptors for the fields we're interested in and verify
// // their types.
-// FieldDescriptor* text_field = descriptor->FindFieldByName("text");
+// const FieldDescriptor* text_field = descriptor->FindFieldByName("text");
// assert(text_field != NULL);
// assert(text_field->type() == FieldDescriptor::TYPE_STRING);
-// assert(text_field->label() == FieldDescriptor::TYPE_OPTIONAL);
-// FieldDescriptor* numbers_field = descriptor->FindFieldByName("numbers");
+// assert(text_field->label() == FieldDescriptor::LABEL_OPTIONAL);
+// const FieldDescriptor* numbers_field = descriptor->
+// FindFieldByName("numbers");
// assert(numbers_field != NULL);
// assert(numbers_field->type() == FieldDescriptor::TYPE_INT32);
-// assert(numbers_field->label() == FieldDescriptor::TYPE_REPEATED);
+// assert(numbers_field->label() == FieldDescriptor::LABEL_REPEATED);
//
// // Parse the message.
// foo->ParseFromString(data);
@@ -109,38 +110,17 @@
#ifndef GOOGLE_PROTOBUF_MESSAGE_H__
#define GOOGLE_PROTOBUF_MESSAGE_H__
-#include <vector>
-#include <string>
-
-#ifdef __DECCXX
-// HP C++'s iosfwd doesn't work.
-#include <iostream>
-#else
#include <iosfwd>
-#endif
+#include <string>
+#include <vector>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
-#if defined(_WIN32) && defined(GetMessage)
-// windows.h defines GetMessage() as a macro. Let's re-define it as an inline
-// function. This is necessary because Reflection has a method called
-// GetMessage() which we don't want overridden. The inline function should be
-// equivalent for C++ users.
-inline BOOL GetMessage_Win32(
- LPMSG lpMsg, HWND hWnd,
- UINT wMsgFilterMin, UINT wMsgFilterMax) {
- return GetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
-}
-#undef GetMessage
-inline BOOL GetMessage(
- LPMSG lpMsg, HWND hWnd,
- UINT wMsgFilterMin, UINT wMsgFilterMax) {
- return GetMessage_Win32(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
-}
-#endif
+#define GOOGLE_PROTOBUF_HAS_ONEOF
namespace google {
namespace protobuf {
@@ -151,17 +131,20 @@ class Reflection;
class MessageFactory;
// Defined in other files.
-class Descriptor; // descriptor.h
-class FieldDescriptor; // descriptor.h
-class EnumDescriptor; // descriptor.h
-class EnumValueDescriptor; // descriptor.h
+class UnknownFieldSet; // unknown_field_set.h
namespace io {
class ZeroCopyInputStream; // zero_copy_stream.h
class ZeroCopyOutputStream; // zero_copy_stream.h
class CodedInputStream; // coded_stream.h
class CodedOutputStream; // coded_stream.h
}
-class UnknownFieldSet; // unknown_field_set.h
+
+
+template<typename T>
+class RepeatedField; // repeated_field.h
+
+template<typename T>
+class RepeatedPtrField; // repeated_field.h
// A container to hold message metadata.
struct Metadata {
@@ -169,12 +152,6 @@ struct Metadata {
const Reflection* reflection;
};
-// Returns the EnumDescriptor for enum type E, which must be a
-// proto-declared enum type. Code generated by the protocol compiler
-// will include specializations of this template for each enum type declared.
-template <typename E>
-const EnumDescriptor* GetEnumDescriptor();
-
// Abstract interface for protocol messages.
//
// See also MessageLite, which contains most every-day operations. Message
@@ -203,9 +180,10 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite {
virtual void CopyFrom(const Message& from);
// Merge the fields from the given message into this message. Singular
- // fields will be overwritten, except for embedded messages which will
- // be merged. Repeated fields will be concatenated. The given message
- // must be of the same type as this message (i.e. the exact same class).
+ // fields will be overwritten, if specified in from, except for embedded
+ // messages which will be merged. Repeated fields will be concatenated.
+ // The given message must be of the same type as this message (i.e. the
+ // exact same class).
virtual void MergeFrom(const Message& from);
// Verifies that IsInitialized() returns true. GOOGLE_CHECK-fails otherwise, with
@@ -216,7 +194,7 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite {
// This is much, much slower than IsInitialized() as it is implemented
// purely via reflection. Generally, you should not call this unless you
// have already determined that an error exists by calling IsInitialized().
- void FindInitializationErrors(vector<string>* errors) const;
+ void FindInitializationErrors(std::vector<string>* errors) const;
// Like FindInitializationErrors, but joins all the strings, delimited by
// commas, and returns them.
@@ -378,7 +356,6 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite {
// write fields from a Reflection without paying attention to the type.
class LIBPROTOBUF_EXPORT Reflection {
public:
- // TODO(kenton): Remove parameter.
inline Reflection() {}
virtual ~Reflection();
@@ -408,7 +385,27 @@ class LIBPROTOBUF_EXPORT Reflection {
virtual void ClearField(Message* message,
const FieldDescriptor* field) const = 0;
- // Remove the last element of a repeated field.
+ // Check if the oneof is set. Returns ture if any field in oneof
+ // is set, false otherwise.
+ // TODO(jieluo) - make it pure virtual after updating all
+ // the subclasses.
+ virtual bool HasOneof(const Message& message,
+ const OneofDescriptor* oneof_descriptor) const {
+ return false;
+ }
+
+ virtual void ClearOneof(Message* message,
+ const OneofDescriptor* oneof_descriptor) const {}
+
+ // Returns the field descriptor if the oneof is set. NULL otherwise.
+ // TODO(jieluo) - make it pure virtual.
+ virtual const FieldDescriptor* GetOneofFieldDescriptor(
+ const Message& message,
+ const OneofDescriptor* oneof_descriptor) const {
+ return NULL;
+ }
+
+ // Removes the last element of a repeated field.
// We don't provide a way to remove any element other than the last
// because it invites inefficient use, such as O(n^2) filtering loops
// that should have been O(n). If you want to remove an element other
@@ -417,15 +414,25 @@ class LIBPROTOBUF_EXPORT Reflection {
// call RemoveLast().
virtual void RemoveLast(Message* message,
const FieldDescriptor* field) const = 0;
+ // Removes the last element of a repeated message field, and returns the
+ // pointer to the caller. Caller takes ownership of the returned pointer.
+ virtual Message* ReleaseLast(Message* message,
+ const FieldDescriptor* field) const = 0;
// Swap the complete contents of two messages.
virtual void Swap(Message* message1, Message* message2) const = 0;
+ // Swap fields listed in fields vector of two messages.
+ virtual void SwapFields(Message* message1,
+ Message* message2,
+ const std::vector<const FieldDescriptor*>& fields)
+ const = 0;
+
// Swap two elements of a repeated field.
virtual void SwapElements(Message* message,
- const FieldDescriptor* field,
- int index1,
- int index2) const = 0;
+ const FieldDescriptor* field,
+ int index1,
+ int index2) const = 0;
// List all fields of the message which are currently set. This includes
// extensions. Singular fields will only be listed if HasField(field) would
@@ -433,7 +440,7 @@ class LIBPROTOBUF_EXPORT Reflection {
// would return non-zero. Fields (both normal fields and extension fields)
// will be listed ordered by field number.
virtual void ListFields(const Message& message,
- vector<const FieldDescriptor*>* output) const = 0;
+ std::vector<const FieldDescriptor*>* output) const = 0;
// Singular field getters ------------------------------------------
// These get the value of a non-repeated field. They return the default
@@ -518,6 +525,23 @@ class LIBPROTOBUF_EXPORT Reflection {
virtual Message* MutableMessage(Message* message,
const FieldDescriptor* field,
MessageFactory* factory = NULL) const = 0;
+ // Replaces the message specified by 'field' with the already-allocated object
+ // sub_message, passing ownership to the message. If the field contained a
+ // message, that message is deleted. If sub_message is NULL, the field is
+ // cleared.
+ virtual void SetAllocatedMessage(Message* message,
+ Message* sub_message,
+ const FieldDescriptor* field) const = 0;
+ // Releases the message specified by 'field' and returns the pointer,
+ // ReleaseMessage() will return the message the message object if it exists.
+ // Otherwise, it may or may not return NULL. In any case, if the return value
+ // is non-NULL, the caller takes ownership of the pointer.
+ // If the field existed (HasField() is true), then the returned pointer will
+ // be the same as the pointer returned by MutableMessage().
+ // This function has the same effect as ClearField().
+ virtual Message* ReleaseMessage(Message* message,
+ const FieldDescriptor* field,
+ MessageFactory* factory = NULL) const = 0;
// Repeated field getters ------------------------------------------
@@ -625,7 +649,39 @@ class LIBPROTOBUF_EXPORT Reflection {
MessageFactory* factory = NULL) const = 0;
- // Extensions ------------------------------------------------------
+ // Repeated field accessors -------------------------------------------------
+ // The methods above, e.g. GetRepeatedInt32(msg, fd, index), provide singular
+ // access to the data in a RepeatedField. The methods below provide aggregate
+ // access by exposing the RepeatedField object itself with the Message.
+ // Applying these templates to inappropriate types will lead to an undefined
+ // reference at link time (e.g. GetRepeatedField<***double>), or possibly a
+ // template matching error at compile time (e.g. GetRepeatedPtrField<File>).
+ //
+ // Usage example: my_doubs = refl->GetRepeatedField<double>(msg, fd);
+
+ // for T = Cord and all protobuf scalar types except enums.
+ template<typename T>
+ const RepeatedField<T>& GetRepeatedField(
+ const Message&, const FieldDescriptor*) const;
+
+ // for T = Cord and all protobuf scalar types except enums.
+ template<typename T>
+ RepeatedField<T>* MutableRepeatedField(
+ Message*, const FieldDescriptor*) const;
+
+ // for T = string, google::protobuf::internal::StringPieceField
+ // google::protobuf::Message & descendants.
+ template<typename T>
+ const RepeatedPtrField<T>& GetRepeatedPtrField(
+ const Message&, const FieldDescriptor*) const;
+
+ // for T = string, google::protobuf::internal::StringPieceField
+ // google::protobuf::Message & descendants.
+ template<typename T>
+ RepeatedPtrField<T>* MutableRepeatedPtrField(
+ Message*, const FieldDescriptor*) const;
+
+ // Extensions ----------------------------------------------------------------
// Try to find an extension of this message type by fully-qualified field
// name. Returns NULL if no extension is known for this name or number.
@@ -637,7 +693,26 @@ class LIBPROTOBUF_EXPORT Reflection {
virtual const FieldDescriptor* FindKnownExtensionByNumber(
int number) const = 0;
+ // ---------------------------------------------------------------------------
+
+ protected:
+ // Obtain a pointer to a Repeated Field Structure and do some type checking:
+ // on field->cpp_type(),
+ // on field->field_option().ctype() (if ctype >= 0)
+ // of field->message_type() (if message_type != NULL).
+ // We use 1 routine rather than 4 (const vs mutable) x (scalar vs pointer).
+ virtual void* MutableRawRepeatedField(
+ Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
+ int ctype, const Descriptor* message_type) const = 0;
+
private:
+ // Special version for specialized implementations of string. We can't call
+ // MutableRawRepeatedField directly here because we don't have access to
+ // FieldOptions::* which are defined in descriptor.pb.h. Including that
+ // file here is not possible because it would cause a circular include cycle.
+ void* MutableRawRepeatedString(
+ Message* message, const FieldDescriptor* field, bool is_string) const;
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection);
};
@@ -654,7 +729,7 @@ class LIBPROTOBUF_EXPORT MessageFactory {
// Calling this method twice with the same Descriptor returns the same
// object. The returned object remains property of the factory. Also, any
// objects created by calling the prototype's New() method share some data
- // with the prototype, so these must be destoyed before the MessageFactory
+ // with the prototype, so these must be destroyed before the MessageFactory
// is destroyed.
//
// The given descriptor must outlive the returned message, and hence must
@@ -700,10 +775,91 @@ class LIBPROTOBUF_EXPORT MessageFactory {
static void InternalRegisterGeneratedMessage(const Descriptor* descriptor,
const Message* prototype);
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory);
};
+#define DECLARE_GET_REPEATED_FIELD(TYPE) \
+template<> \
+LIBPROTOBUF_EXPORT \
+const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>( \
+ const Message& message, const FieldDescriptor* field) const; \
+ \
+template<> \
+RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>( \
+ Message* message, const FieldDescriptor* field) const;
+
+DECLARE_GET_REPEATED_FIELD(int32)
+DECLARE_GET_REPEATED_FIELD(int64)
+DECLARE_GET_REPEATED_FIELD(uint32)
+DECLARE_GET_REPEATED_FIELD(uint64)
+DECLARE_GET_REPEATED_FIELD(float)
+DECLARE_GET_REPEATED_FIELD(double)
+DECLARE_GET_REPEATED_FIELD(bool)
+
+#undef DECLARE_GET_REPEATED_FIELD
+
+// =============================================================================
+// Implementation details for {Get,Mutable}RawRepeatedPtrField. We provide
+// specializations for <string>, <StringPieceField> and <Message> and handle
+// everything else with the default template which will match any type having
+// a method with signature "static const google::protobuf::Descriptor* descriptor()".
+// Such a type presumably is a descendant of google::protobuf::Message.
+
+template<>
+inline const RepeatedPtrField<string>& Reflection::GetRepeatedPtrField<string>(
+ const Message& message, const FieldDescriptor* field) const {
+ return *static_cast<RepeatedPtrField<string>* >(
+ MutableRawRepeatedString(const_cast<Message*>(&message), field, true));
+}
+
+template<>
+inline RepeatedPtrField<string>* Reflection::MutableRepeatedPtrField<string>(
+ Message* message, const FieldDescriptor* field) const {
+ return static_cast<RepeatedPtrField<string>* >(
+ MutableRawRepeatedString(message, field, true));
+}
+
+
+// -----
+
+template<>
+inline const RepeatedPtrField<Message>& Reflection::GetRepeatedPtrField(
+ const Message& message, const FieldDescriptor* field) const {
+ return *static_cast<RepeatedPtrField<Message>* >(
+ MutableRawRepeatedField(const_cast<Message*>(&message), field,
+ FieldDescriptor::CPPTYPE_MESSAGE, -1,
+ NULL));
+}
+
+template<>
+inline RepeatedPtrField<Message>* Reflection::MutableRepeatedPtrField(
+ Message* message, const FieldDescriptor* field) const {
+ return static_cast<RepeatedPtrField<Message>* >(
+ MutableRawRepeatedField(message, field,
+ FieldDescriptor::CPPTYPE_MESSAGE, -1,
+ NULL));
+}
+
+template<typename PB>
+inline const RepeatedPtrField<PB>& Reflection::GetRepeatedPtrField(
+ const Message& message, const FieldDescriptor* field) const {
+ return *static_cast<RepeatedPtrField<PB>* >(
+ MutableRawRepeatedField(const_cast<Message*>(&message), field,
+ FieldDescriptor::CPPTYPE_MESSAGE, -1,
+ PB::default_instance().GetDescriptor()));
+}
+
+template<typename PB>
+inline RepeatedPtrField<PB>* Reflection::MutableRepeatedPtrField(
+ Message* message, const FieldDescriptor* field) const {
+ return static_cast<RepeatedPtrField<PB>* >(
+ MutableRawRepeatedField(message, field,
+ FieldDescriptor::CPPTYPE_MESSAGE, -1,
+ PB::default_instance().GetDescriptor()));
+}
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc
index 7c8f37d..14cdc91 100644
--- a/src/google/protobuf/message_lite.cc
+++ b/src/google/protobuf/message_lite.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -37,8 +37,8 @@
#include <string>
#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/stubs/stl_util-inl.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
@@ -278,7 +278,8 @@ bool MessageLite::AppendPartialToString(string* output) const {
int old_size = output->size();
int byte_size = ByteSize();
STLStringResizeUninitialized(output, old_size + byte_size);
- uint8* start = reinterpret_cast<uint8*>(string_as_array(output) + old_size);
+ uint8* start =
+ 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);
diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h
index ebf4ba3..027cabf 100644
--- a/src/google/protobuf/message_lite.h
+++ b/src/google/protobuf/message_lite.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -40,11 +40,17 @@
#define GOOGLE_PROTOBUF_MESSAGE_LITE_H__
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/io/coded_stream.h>
namespace google {
namespace protobuf {
+namespace io {
+ class CodedInputStream;
+ class CodedOutputStream;
+ class ZeroCopyInputStream;
+ class ZeroCopyOutputStream;
+}
+
// Interface to light weight protocol messages.
//
// This interface is implemented by all protocol message objects. Non-lite
@@ -103,7 +109,8 @@ class LIBPROTOBUF_EXPORT MessageLite {
// Parsing ---------------------------------------------------------
// Methods for parsing in protocol buffer format. Most of these are
- // just simple wrappers around MergeFromCodedStream().
+ // just simple wrappers around MergeFromCodedStream(). Clear() will be called
+ // before merging the input.
// Fill the message with a protocol buffer parsed from the given input
// stream. Returns false on a read error or if the input is in the
@@ -158,6 +165,7 @@ class LIBPROTOBUF_EXPORT MessageLite {
// followed by IsInitialized().
virtual bool MergePartialFromCodedStream(io::CodedInputStream* input) = 0;
+
// Serialization ---------------------------------------------------
// Methods for serializing in protocol buffer format. Most of these
// are just simple wrappers around ByteSize() and SerializeWithCachedSizes().
diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc
index 33b9e77..a5f339f 100644
--- a/src/google/protobuf/message_unittest.cc
+++ b/src/google/protobuf/message_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -45,7 +45,6 @@
#include <sstream>
#include <fstream>
-#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/descriptor.h>
@@ -53,6 +52,7 @@
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/test_util.h>
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -205,7 +205,7 @@ TEST(MessageTest, InitializationErrorString) {
EXPECT_EQ("a, b, c", message.InitializationErrorString());
}
-#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet.
+#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet.
TEST(MessageTest, SerializeFailsIfNotInitialized) {
unittest::TestRequired message;
@@ -222,7 +222,25 @@ TEST(MessageTest, CheckInitialized) {
"fields: a, b, c");
}
-#endif // GTEST_HAS_DEATH_TEST
+TEST(MessageTest, CheckOverflow) {
+ unittest::TestAllTypes message;
+ // Create a message with size just over 2GB. This triggers integer overflow
+ // when computing message size.
+ const string data(1024, 'x');
+ Cord one_megabyte;
+ for (int i = 0; i < 1024; i++) {
+ one_megabyte.Append(data);
+ }
+
+ for (int i = 0; i < 2 * 1024 + 1; ++i) {
+ message.add_repeated_cord()->CopyFrom(one_megabyte);
+ }
+
+ Cord serialized;
+ EXPECT_FALSE(message.AppendToCord(&serialized));
+}
+
+#endif // PROTOBUF_HAS_DEATH_TEST
TEST(MessageTest, BypassInitializationCheckOnSerialize) {
unittest::TestRequired message;
@@ -257,6 +275,133 @@ TEST(MessageTest, ParseFailsOnInvalidMessageEnd) {
EXPECT_FALSE(message.ParseFromArray("\014", 1));
}
+namespace {
+
+void ExpectMessageMerged(const unittest::TestAllTypes& message) {
+ EXPECT_EQ(3, message.optional_int32());
+ EXPECT_EQ(2, message.optional_int64());
+ EXPECT_EQ("hello", message.optional_string());
+}
+
+void AssignParsingMergeMessages(
+ unittest::TestAllTypes* msg1,
+ unittest::TestAllTypes* msg2,
+ unittest::TestAllTypes* msg3) {
+ msg1->set_optional_int32(1);
+ msg2->set_optional_int64(2);
+ msg3->set_optional_int32(3);
+ msg3->set_optional_string("hello");
+}
+
+} // namespace
+
+// Test that if an optional or required message/group field appears multiple
+// times in the input, they need to be merged.
+TEST(MessageTest, ParsingMerge) {
+ unittest::TestParsingMerge::RepeatedFieldsGenerator generator;
+ unittest::TestAllTypes* msg1;
+ unittest::TestAllTypes* msg2;
+ unittest::TestAllTypes* msg3;
+
+#define ASSIGN_REPEATED_FIELD(FIELD) \
+ msg1 = generator.add_##FIELD(); \
+ msg2 = generator.add_##FIELD(); \
+ msg3 = generator.add_##FIELD(); \
+ AssignParsingMergeMessages(msg1, msg2, msg3)
+
+ ASSIGN_REPEATED_FIELD(field1);
+ ASSIGN_REPEATED_FIELD(field2);
+ ASSIGN_REPEATED_FIELD(field3);
+ ASSIGN_REPEATED_FIELD(ext1);
+ ASSIGN_REPEATED_FIELD(ext2);
+
+#undef ASSIGN_REPEATED_FIELD
+#define ASSIGN_REPEATED_GROUP(FIELD) \
+ msg1 = generator.add_##FIELD()->mutable_field1(); \
+ msg2 = generator.add_##FIELD()->mutable_field1(); \
+ msg3 = generator.add_##FIELD()->mutable_field1(); \
+ AssignParsingMergeMessages(msg1, msg2, msg3)
+
+ ASSIGN_REPEATED_GROUP(group1);
+ ASSIGN_REPEATED_GROUP(group2);
+
+#undef ASSIGN_REPEATED_GROUP
+
+ string buffer;
+ generator.SerializeToString(&buffer);
+ unittest::TestParsingMerge parsing_merge;
+ parsing_merge.ParseFromString(buffer);
+
+ // Required and optional fields should be merged.
+ ExpectMessageMerged(parsing_merge.required_all_types());
+ ExpectMessageMerged(parsing_merge.optional_all_types());
+ ExpectMessageMerged(
+ parsing_merge.optionalgroup().optional_group_all_types());
+ ExpectMessageMerged(
+ parsing_merge.GetExtension(unittest::TestParsingMerge::optional_ext));
+
+ // Repeated fields should not be merged.
+ EXPECT_EQ(3, parsing_merge.repeated_all_types_size());
+ EXPECT_EQ(3, parsing_merge.repeatedgroup_size());
+ EXPECT_EQ(3, parsing_merge.ExtensionSize(
+ unittest::TestParsingMerge::repeated_ext));
+}
+
+TEST(MessageTest, MergeFrom) {
+ unittest::TestAllTypes source;
+ unittest::TestAllTypes dest;
+
+ // Optional fields
+ source.set_optional_int32(1); // only source
+ source.set_optional_int64(2); // both source and dest
+ dest.set_optional_int64(3);
+ dest.set_optional_uint32(4); // only dest
+
+ // Optional fields with defaults
+ source.set_default_int32(13); // only source
+ source.set_default_int64(14); // both source and dest
+ dest.set_default_int64(15);
+ dest.set_default_uint32(16); // only dest
+
+ // Repeated fields
+ source.add_repeated_int32(5); // only source
+ source.add_repeated_int32(6);
+ source.add_repeated_int64(7); // both source and dest
+ source.add_repeated_int64(8);
+ dest.add_repeated_int64(9);
+ dest.add_repeated_int64(10);
+ dest.add_repeated_uint32(11); // only dest
+ dest.add_repeated_uint32(12);
+
+ dest.MergeFrom(source);
+
+ // Optional fields: source overwrites dest if source is specified
+ EXPECT_EQ(1, dest.optional_int32()); // only source: use source
+ EXPECT_EQ(2, dest.optional_int64()); // source and dest: use source
+ EXPECT_EQ(4, dest.optional_uint32()); // only dest: use dest
+ EXPECT_EQ(0, dest.optional_uint64()); // neither: use default
+
+ // Optional fields with defaults
+ EXPECT_EQ(13, dest.default_int32()); // only source: use source
+ EXPECT_EQ(14, dest.default_int64()); // source and dest: use source
+ EXPECT_EQ(16, dest.default_uint32()); // only dest: use dest
+ EXPECT_EQ(44, dest.default_uint64()); // neither: use default
+
+ // Repeated fields: concatenate source onto the end of dest
+ ASSERT_EQ(2, dest.repeated_int32_size());
+ EXPECT_EQ(5, dest.repeated_int32(0));
+ EXPECT_EQ(6, dest.repeated_int32(1));
+ ASSERT_EQ(4, dest.repeated_int64_size());
+ EXPECT_EQ(9, dest.repeated_int64(0));
+ EXPECT_EQ(10, dest.repeated_int64(1));
+ EXPECT_EQ(7, dest.repeated_int64(2));
+ EXPECT_EQ(8, dest.repeated_int64(3));
+ ASSERT_EQ(2, dest.repeated_uint32_size());
+ EXPECT_EQ(11, dest.repeated_uint32(0));
+ EXPECT_EQ(12, dest.repeated_uint32(1));
+ ASSERT_EQ(0, dest.repeated_uint64_size());
+}
+
TEST(MessageFactoryTest, GeneratedFactoryLookup) {
EXPECT_EQ(
MessageFactory::generated_factory()->GetPrototype(
@@ -277,5 +422,6 @@ TEST(MessageFactoryTest, GeneratedFactoryUnknownType) {
MessageFactory::generated_factory()->GetPrototype(descriptor) == NULL);
}
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/package_info.h b/src/google/protobuf/package_info.h
index 60cd399..935e963 100644
--- a/src/google/protobuf/package_info.h
+++ b/src/google/protobuf/package_info.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc
index 897c0d7..4629dec 100644
--- a/src/google/protobuf/reflection_ops.cc
+++ b/src/google/protobuf/reflection_ops.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,8 +32,12 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#include <string>
+#include <vector>
+
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/stubs/strutil.h>
@@ -52,7 +56,9 @@ void ReflectionOps::Merge(const Message& from, Message* to) {
const Descriptor* descriptor = from.GetDescriptor();
GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor)
- << "Tried to merge messages of different types.";
+ << "Tried to merge messages of different types "
+ << "(merge " << descriptor->full_name()
+ << " to " << to->GetDescriptor()->full_name() << ")";
const Reflection* from_reflection = from.GetReflection();
const Reflection* to_reflection = to->GetReflection();
@@ -151,11 +157,12 @@ bool ReflectionOps::IsInitialized(const Message& message) {
for (int i = 0; i < fields.size(); i++) {
const FieldDescriptor* field = fields[i];
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+
if (field->is_repeated()) {
int size = reflection->FieldSize(message, field);
- for (int i = 0; i < size; i++) {
- if (!reflection->GetRepeatedMessage(message, field, i)
+ for (int j = 0; j < size; j++) {
+ if (!reflection->GetRepeatedMessage(message, field, j)
.IsInitialized()) {
return false;
}
@@ -183,8 +190,8 @@ void ReflectionOps::DiscardUnknownFields(Message* message) {
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
if (field->is_repeated()) {
int size = reflection->FieldSize(*message, field);
- for (int i = 0; i < size; i++) {
- reflection->MutableRepeatedMessage(message, field, i)
+ for (int j = 0; j < size; j++) {
+ reflection->MutableRepeatedMessage(message, field, j)
->DiscardUnknownFields();
}
} else {
@@ -240,11 +247,11 @@ void ReflectionOps::FindInitializationErrors(
if (field->is_repeated()) {
int size = reflection->FieldSize(message, field);
- for (int i = 0; i < size; i++) {
+ for (int j = 0; j < size; j++) {
const Message& sub_message =
- reflection->GetRepeatedMessage(message, field, i);
+ reflection->GetRepeatedMessage(message, field, j);
FindInitializationErrors(sub_message,
- SubMessagePrefix(prefix, field, i),
+ SubMessagePrefix(prefix, field, j),
errors);
}
} else {
diff --git a/src/google/protobuf/reflection_ops.h b/src/google/protobuf/reflection_ops.h
index 355a0a5..4775911 100644
--- a/src/google/protobuf/reflection_ops.h
+++ b/src/google/protobuf/reflection_ops.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -38,6 +38,7 @@
#ifndef GOOGLE_PROTOBUF_REFLECTION_OPS_H__
#define GOOGLE_PROTOBUF_REFLECTION_OPS_H__
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message.h>
namespace google {
diff --git a/src/google/protobuf/reflection_ops_unittest.cc b/src/google/protobuf/reflection_ops_unittest.cc
index 1cd56f1..32740ea 100644
--- a/src/google/protobuf/reflection_ops_unittest.cc
+++ b/src/google/protobuf/reflection_ops_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -78,6 +78,18 @@ TEST(ReflectionOpsTest, CopyExtensions) {
TestUtil::ExpectAllExtensionsSet(message2);
}
+TEST(ReflectionOpsTest, CopyOneof) {
+ unittest::TestOneof2 message, message2;
+ TestUtil::SetOneof1(&message);
+ ReflectionOps::Copy(message, &message2);
+ TestUtil::ExpectOneofSet1(message2);
+
+ TestUtil::SetOneof2(&message);
+ TestUtil::ExpectOneofSet2(message);
+ ReflectionOps::Copy(message, &message2);
+ TestUtil::ExpectOneofSet2(message2);
+}
+
TEST(ReflectionOpsTest, Merge) {
// Note: Copy is implemented in terms of Merge() so technically the Copy
// test already tested most of this.
@@ -152,7 +164,25 @@ TEST(ReflectionOpsTest, MergeUnknown) {
EXPECT_EQ(2, message1.unknown_fields().field(1).varint());
}
-#ifdef GTEST_HAS_DEATH_TEST
+TEST(ReflectionOpsTest, MergeOneof) {
+ unittest::TestOneof2 message1, message2;
+ TestUtil::SetOneof1(&message1);
+
+ // Merge to empty message
+ ReflectionOps::Merge(message1, &message2);
+ TestUtil::ExpectOneofSet1(message2);
+
+ // Merge with the same oneof fields
+ ReflectionOps::Merge(message1, &message2);
+ TestUtil::ExpectOneofSet1(message2);
+
+ // Merge with different oneof fields
+ TestUtil::SetOneof2(&message1);
+ ReflectionOps::Merge(message1, &message2);
+ TestUtil::ExpectOneofSet2(message2);
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
TEST(ReflectionOpsTest, MergeFromSelf) {
// Note: Copy is implemented in terms of Merge() so technically the Copy
@@ -165,7 +195,7 @@ TEST(ReflectionOpsTest, MergeFromSelf) {
"&from");
}
-#endif // GTEST_HAS_DEATH_TEST
+#endif // PROTOBUF_HAS_DEATH_TEST
TEST(ReflectionOpsTest, Clear) {
unittest::TestAllTypes message;
@@ -220,6 +250,23 @@ TEST(ReflectionOpsTest, ClearUnknown) {
EXPECT_EQ(0, message.unknown_fields().field_count());
}
+TEST(ReflectionOpsTest, ClearOneof) {
+ unittest::TestOneof2 message;
+
+ TestUtil::ExpectOneofClear(message);
+ TestUtil::SetOneof1(&message);
+ TestUtil::ExpectOneofSet1(message);
+ ReflectionOps::Clear(&message);
+ TestUtil::ExpectOneofClear(message);
+
+ TestUtil::SetOneof1(&message);
+ TestUtil::ExpectOneofSet1(message);
+ TestUtil::SetOneof2(&message);
+ TestUtil::ExpectOneofSet2(message);
+ ReflectionOps::Clear(&message);
+ TestUtil::ExpectOneofClear(message);
+}
+
TEST(ReflectionOpsTest, DiscardUnknownFields) {
unittest::TestAllTypes message;
TestUtil::SetAllFields(&message);
@@ -354,10 +401,26 @@ TEST(ReflectionOpsTest, ExtensionIsInitialized) {
EXPECT_TRUE(ReflectionOps::IsInitialized(message));
}
+TEST(ReflectionOpsTest, OneofIsInitialized) {
+ unittest::TestRequiredOneof message;
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+
+ message.mutable_foo_message();
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+
+ message.set_foo_int(1);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+
+ message.mutable_foo_message();
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+ message.mutable_foo_message()->set_required_double(0.1);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+}
+
static string FindInitializationErrors(const Message& message) {
vector<string> errors;
ReflectionOps::FindInitializationErrors(message, "", &errors);
- return JoinStrings(errors, ",");
+ return Join(errors, ",");
}
TEST(ReflectionOpsTest, FindInitializationErrors) {
@@ -399,6 +462,13 @@ TEST(ReflectionOpsTest, FindExtensionInitializationErrors) {
FindInitializationErrors(message));
}
+TEST(ReflectionOpsTest, FindOneofInitializationErrors) {
+ unittest::TestRequiredOneof message;
+ message.mutable_foo_message();
+ EXPECT_EQ("foo_message.required_double",
+ FindInitializationErrors(message));
+}
+
} // namespace
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/repeated_field.cc b/src/google/protobuf/repeated_field.cc
index f7beb11..b400732 100644
--- a/src/google/protobuf/repeated_field.cc
+++ b/src/google/protobuf/repeated_field.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,53 +32,45 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#include <algorithm>
+
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
+
namespace internal {
void RepeatedPtrFieldBase::Reserve(int new_size) {
if (total_size_ >= new_size) return;
void** old_elements = elements_;
- total_size_ = max(total_size_ * 2, new_size);
+ total_size_ = max(kMinRepeatedFieldAllocationSize,
+ max(total_size_ * 2, new_size));
elements_ = new void*[total_size_];
- memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0]));
- if (old_elements != initial_space_) {
+ if (old_elements != NULL) {
+ memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0]));
delete [] old_elements;
}
}
void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) {
+ if (this == other) return;
void** swap_elements = elements_;
int swap_current_size = current_size_;
int swap_allocated_size = allocated_size_;
int swap_total_size = total_size_;
- // We may not be using initial_space_ but it's not worth checking. Just
- // copy it anyway.
- void* swap_initial_space[kInitialSize];
- memcpy(swap_initial_space, initial_space_, sizeof(initial_space_));
elements_ = other->elements_;
current_size_ = other->current_size_;
allocated_size_ = other->allocated_size_;
total_size_ = other->total_size_;
- memcpy(initial_space_, other->initial_space_, sizeof(initial_space_));
other->elements_ = swap_elements;
other->current_size_ = swap_current_size;
other->allocated_size_ = swap_allocated_size;
other->total_size_ = swap_total_size;
- memcpy(other->initial_space_, swap_initial_space, sizeof(swap_initial_space));
-
- if (elements_ == other->initial_space_) {
- elements_ = initial_space_;
- }
- if (other->elements_ == initial_space_) {
- other->elements_ = other->initial_space_;
- }
}
string* StringTypeHandlerBase::New() {
@@ -88,8 +80,8 @@ void StringTypeHandlerBase::Delete(string* value) {
delete value;
}
+} // namespace internal
-} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index defdefe..5005183 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -46,24 +46,55 @@
#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
#define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
+#ifdef _MSC_VER
+// This is required for min/max on VS2013 only.
+#include <algorithm>
+#endif
+
#include <string>
#include <iterator>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/type_traits.h>
+#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message_lite.h>
namespace google {
+namespace upb {
+namespace google_opensource {
+class GMR_Handlers;
+} // namespace google_opensource
+} // namespace upb
+
namespace protobuf {
class Message;
namespace internal {
-// We need this (from generated_message_reflection.cc).
-LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str);
+static const int kMinRepeatedFieldAllocationSize = 4;
+
+// A utility function for logging that doesn't need any template types.
+void LogIndexOutOfBounds(int index, int size);
+template <typename Iter>
+inline int CalculateReserve(Iter begin, Iter end, std::forward_iterator_tag) {
+ return std::distance(begin, end);
+}
+
+template <typename Iter>
+inline int CalculateReserve(Iter begin, Iter end, std::input_iterator_tag) {
+ return -1;
+}
+
+template <typename Iter>
+inline int CalculateReserve(Iter begin, Iter end) {
+ typedef typename std::iterator_traits<Iter>::iterator_category Category;
+ return CalculateReserve(begin, end, Category());
+}
} // namespace internal
+
// RepeatedField is used to represent repeated fields of a primitive type (in
// other words, everything except strings and nested Messages). Most users will
// not ever use a RepeatedField directly; they will use the get-by-index,
@@ -72,8 +103,14 @@ template <typename Element>
class RepeatedField {
public:
RepeatedField();
+ RepeatedField(const RepeatedField& other);
+ template <typename Iter>
+ RepeatedField(Iter begin, const Iter& end);
~RepeatedField();
+ RepeatedField& operator=(const RepeatedField& other);
+
+ bool empty() const;
int size() const;
const Element& Get(int index) const;
@@ -82,14 +119,17 @@ class RepeatedField {
void Add(const Element& value);
Element* Add();
// Remove the last element in the array.
- // We don't provide a way to remove any element other than the last
- // because it invites inefficient use, such as O(n^2) filtering loops
- // that should have been O(n). If you want to remove an element other
- // than the last, the best way to do it is to re-arrange the elements
- // so that the one you want removed is at the end, then call RemoveLast().
void RemoveLast();
+
+ // Extract elements with indices in "[start .. start+num-1]".
+ // Copy them into "elements[0 .. num-1]" if "elements" is not NULL.
+ // Caution: implementation also moves elements with indices [start+num ..].
+ // Calling this routine inside a loop can cause quadratic behavior.
+ void ExtractSubrange(int start, int num, Element* elements);
+
void Clear();
void MergeFrom(const RepeatedField& other);
+ void CopyFrom(const RepeatedField& other);
// Reserve space to expand the field to at least the given size. If the
// array is grown, it will always be at least doubled in size.
@@ -102,6 +142,11 @@ class RepeatedField {
Element* AddAlreadyReserved();
int Capacity() const;
+ // Like STL resize. Uses value to fill appended elements.
+ // Like Truncate() if new_size <= size(), otherwise this is
+ // O(new_size - size()).
+ void Resize(int new_size, const Element& value);
+
// Gets the underlying array. This pointer is possibly invalidated by
// any add or remove operation.
Element* mutable_data();
@@ -116,27 +161,46 @@ class RepeatedField {
// STL-like iterator support
typedef Element* iterator;
typedef const Element* const_iterator;
+ typedef Element value_type;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef int size_type;
+ typedef ptrdiff_t difference_type;
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
+ // Reverse iterator support
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ reverse_iterator rbegin() {
+ return reverse_iterator(end());
+ }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ reverse_iterator rend() {
+ return reverse_iterator(begin());
+ }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+
// Returns the number of bytes used by the repeated field, excluding
// sizeof(*this)
int SpaceUsedExcludingSelf() const;
private:
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedField);
-
- static const int kInitialSize = 4;
+ static const int kInitialSize = 0;
Element* elements_;
int current_size_;
int total_size_;
- Element initial_space_[kInitialSize];
-
// Move the contents of |from| into |to|, possibly clobbering |from| in the
// process. For primitive types this is just a memcpy(), but it could be
// specialized for non-primitive types to, say, swap each element instead.
@@ -148,7 +212,21 @@ class RepeatedField {
namespace internal {
template <typename It> class RepeatedPtrIterator;
-template <typename It> class RepeatedPtrOverPtrsIterator;
+template <typename It, typename VoidPtr> class RepeatedPtrOverPtrsIterator;
+} // namespace internal
+
+namespace internal {
+
+// This is a helper template to copy an array of elements effeciently when they
+// have a trivial copy constructor, and correctly otherwise. This really
+// shouldn't be necessary, but our compiler doesn't optimize std::copy very
+// effectively.
+template <typename Element,
+ bool HasTrivialCopy = has_trivial_copy<Element>::value>
+struct ElementCopier {
+ void operator()(Element to[], const Element from[], int array_size);
+};
+
} // namespace internal
namespace internal {
@@ -183,12 +261,17 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
// use of AddFromCleared(), which is not part of the public interface.
friend class ExtensionSet;
+ // To parse directly into a proto2 generated class, the upb class GMR_Handlers
+ // needs to be able to modify a RepeatedPtrFieldBase directly.
+ friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers;
+
RepeatedPtrFieldBase();
// Must be called from destructor.
template <typename TypeHandler>
void Destroy();
+ bool empty() const;
int size() const;
template <typename TypeHandler>
@@ -203,6 +286,16 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
void Clear();
template <typename TypeHandler>
void MergeFrom(const RepeatedPtrFieldBase& other);
+ template <typename TypeHandler>
+ void CopyFrom(const RepeatedPtrFieldBase& other);
+
+ void CloseGap(int start, int num) {
+ // Close up a gap of "num" elements starting at offset "start".
+ for (int i = start + num; i < allocated_size_; ++i)
+ elements_[i - num] = elements_[i];
+ current_size_ -= num;
+ allocated_size_ -= num;
+ }
void Reserve(int new_size);
@@ -243,17 +336,13 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
typename TypeHandler::Type* ReleaseCleared();
private:
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
-
- static const int kInitialSize = 4;
+ static const int kInitialSize = 0;
void** elements_;
int current_size_;
int allocated_size_;
int total_size_;
- void* initial_space_[kInitialSize];
-
template <typename TypeHandler>
static inline typename TypeHandler::Type* cast(void* element) {
return reinterpret_cast<typename TypeHandler::Type*>(element);
@@ -262,6 +351,8 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
static inline const typename TypeHandler::Type* cast(const void* element) {
return reinterpret_cast<const typename TypeHandler::Type*>(element);
}
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
};
template <typename GenericType>
@@ -275,6 +366,7 @@ class GenericTypeHandler {
to->MergeFrom(from);
}
static int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); }
+ static const Type& default_instance() { return Type::default_instance(); }
};
template <>
@@ -283,6 +375,25 @@ inline void GenericTypeHandler<MessageLite>::Merge(
to->CheckTypeAndMergeFrom(from);
}
+template <>
+inline const MessageLite& GenericTypeHandler<MessageLite>::default_instance() {
+ // Yes, the behavior of the code is undefined, but this function is only
+ // called when we're already deep into the world of undefined, because the
+ // caller called Get(index) out of bounds.
+ MessageLite* null = NULL;
+ return *null;
+}
+
+template <>
+inline const Message& GenericTypeHandler<Message>::default_instance() {
+ // Yes, the behavior of the code is undefined, but this function is only
+ // called when we're already deep into the world of undefined, because the
+ // caller called Get(index) out of bounds.
+ Message* null = NULL;
+ return *null;
+}
+
+
// HACK: If a class is declared as DLL-exported in MSVC, it insists on
// generating copies of all its methods -- even inline ones -- to include
// in the DLL. But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
@@ -298,6 +409,9 @@ class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
static void Delete(string* value);
static void Clear(string* value) { value->clear(); }
static void Merge(const string& from, string* to) { *to = from; }
+ static const Type& default_instance() {
+ return ::google::protobuf::internal::GetEmptyString();
+ }
};
class StringTypeHandler : public StringTypeHandlerBase {
@@ -316,17 +430,32 @@ template <typename Element>
class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
public:
RepeatedPtrField();
-
+ RepeatedPtrField(const RepeatedPtrField& other);
+ template <typename Iter>
+ RepeatedPtrField(Iter begin, const Iter& end);
~RepeatedPtrField();
+ RepeatedPtrField& operator=(const RepeatedPtrField& other);
+
+ bool empty() const;
int size() const;
const Element& Get(int index) const;
Element* Mutable(int index);
Element* Add();
- void RemoveLast(); // Remove the last element in the array.
+
+ // Remove the last element in the array.
+ // Ownership of the element is retained by the array.
+ void RemoveLast();
+
+ // Delete elements with indices in the range [start .. start+num-1].
+ // Caution: implementation moves all elements with indices [start+num .. ].
+ // Calling this routine inside a loop can cause quadratic behavior.
+ void DeleteSubrange(int start, int num);
+
void Clear();
void MergeFrom(const RepeatedPtrField& other);
+ void CopyFrom(const RepeatedPtrField& other);
// Reserve space to expand the field to at least the given size. This only
// resizes the pointer array; it doesn't allocate any objects. If the
@@ -349,47 +478,79 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
// STL-like iterator support
typedef internal::RepeatedPtrIterator<Element> iterator;
typedef internal::RepeatedPtrIterator<const Element> const_iterator;
+ typedef Element value_type;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef int size_type;
+ typedef ptrdiff_t difference_type;
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
+ // Reverse iterator support
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ reverse_iterator rbegin() {
+ return reverse_iterator(end());
+ }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ reverse_iterator rend() {
+ return reverse_iterator(begin());
+ }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+
// Custom STL-like iterator that iterates over and returns the underlying
// pointers to Element rather than Element itself.
- typedef internal::RepeatedPtrOverPtrsIterator<Element> pointer_iterator;
+ typedef internal::RepeatedPtrOverPtrsIterator<Element, void*>
+ pointer_iterator;
+ typedef internal::RepeatedPtrOverPtrsIterator<const Element, const void*>
+ const_pointer_iterator;
pointer_iterator pointer_begin();
+ const_pointer_iterator pointer_begin() const;
pointer_iterator pointer_end();
+ const_pointer_iterator pointer_end() const;
// Returns (an estimate of) the number of bytes used by the repeated field,
// excluding sizeof(*this).
int SpaceUsedExcludingSelf() const;
- // The spaced used just by the pointer array, not counting the objects pointed
- // at. Returns zero if the array is inlined (i.e. initial_space_ is being
- // used).
- int SpaceUsedByArray() const;
-
// Advanced memory management --------------------------------------
- // When hardcore memory management becomes necessary -- as it often
+ // When hardcore memory management becomes necessary -- as it sometimes
// does here at Google -- the following methods may be useful.
// Add an already-allocated object, passing ownership to the
// RepeatedPtrField.
void AddAllocated(Element* value);
- // Remove the last element and return it, passing ownership to the
- // caller.
+ // Remove the last element and return it, passing ownership to the caller.
// Requires: size() > 0
Element* ReleaseLast();
+ // Extract elements with indices in the range "[start .. start+num-1]".
+ // The caller assumes ownership of the extracted elements and is responsible
+ // for deleting them when they are no longer needed.
+ // If "elements" is non-NULL, then pointers to the extracted elements
+ // are stored in "elements[0 .. num-1]" for the convenience of the caller.
+ // If "elements" is NULL, then the caller must use some other mechanism
+ // to perform any further operations (like deletion) on these elements.
+ // Caution: implementation also moves elements with indices [start+num ..].
+ // Calling this routine inside a loop can cause quadratic behavior.
+ void ExtractSubrange(int start, int num, Element** elements);
+
// When elements are removed by calls to RemoveLast() or Clear(), they
// are not actually freed. Instead, they are cleared and kept so that
// they can be reused later. This can save lots of CPU time when
// repeatedly reusing a protocol message for similar purposes.
//
- // Really, extremely hardcore programs may actually want to manipulate
- // these objects to better-optimize memory management. These methods
- // allow that.
+ // Hardcore programs may choose to manipulate these cleared objects
+ // to better optimize memory management using the following routines.
// Get the number of cleared objects that are currently being kept
// around for reuse.
@@ -410,28 +571,63 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
// methods on RepeatedPtrFieldBase.
class TypeHandler;
-
- private:
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrField);
};
// implementation ====================================================
template <typename Element>
inline RepeatedField<Element>::RepeatedField()
- : elements_(initial_space_),
+ : elements_(NULL),
current_size_(0),
total_size_(kInitialSize) {
}
template <typename Element>
-RepeatedField<Element>::~RepeatedField() {
- if (elements_ != initial_space_) {
- delete [] elements_;
+inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
+ : elements_(NULL),
+ current_size_(0),
+ total_size_(kInitialSize) {
+ CopyFrom(other);
+}
+
+template <typename Element>
+template <typename Iter>
+inline RepeatedField<Element>::RepeatedField(Iter begin, const Iter& end)
+ : elements_(NULL),
+ current_size_(0),
+ total_size_(kInitialSize) {
+ int reserve = internal::CalculateReserve(begin, end);
+ if (reserve != -1) {
+ Reserve(reserve);
+ for (; begin != end; ++begin) {
+ AddAlreadyReserved(*begin);
+ }
+ } else {
+ for (; begin != end; ++begin) {
+ Add(*begin);
+ }
}
}
template <typename Element>
+RepeatedField<Element>::~RepeatedField() {
+ delete [] elements_;
+}
+
+template <typename Element>
+inline RepeatedField<Element>&
+RepeatedField<Element>::operator=(const RepeatedField& other) {
+ if (this != &other)
+ CopyFrom(other);
+ return *this;
+}
+
+template <typename Element>
+inline bool RepeatedField<Element>::empty() const {
+ return current_size_ == 0;
+}
+
+template <typename Element>
inline int RepeatedField<Element>::size() const {
return current_size_;
}
@@ -453,20 +649,33 @@ inline Element* RepeatedField<Element>::AddAlreadyReserved() {
return &elements_[current_size_++];
}
+template<typename Element>
+inline void RepeatedField<Element>::Resize(int new_size, const Element& value) {
+ GOOGLE_DCHECK_GE(new_size, 0);
+ if (new_size > size()) {
+ Reserve(new_size);
+ std::fill(&elements_[current_size_], &elements_[new_size], value);
+ }
+ current_size_ = new_size;
+}
+
template <typename Element>
inline const Element& RepeatedField<Element>::Get(int index) const {
+ GOOGLE_DCHECK_GE(index, 0);
GOOGLE_DCHECK_LT(index, size());
return elements_[index];
}
template <typename Element>
inline Element* RepeatedField<Element>::Mutable(int index) {
+ GOOGLE_DCHECK_GE(index, 0);
GOOGLE_DCHECK_LT(index, size());
return elements_ + index;
}
template <typename Element>
inline void RepeatedField<Element>::Set(int index, const Element& value) {
+ GOOGLE_DCHECK_GE(index, 0);
GOOGLE_DCHECK_LT(index, size());
elements_[index] = value;
}
@@ -490,15 +699,46 @@ inline void RepeatedField<Element>::RemoveLast() {
}
template <typename Element>
+void RepeatedField<Element>::ExtractSubrange(
+ int start, int num, Element* elements) {
+ GOOGLE_DCHECK_GE(start, 0);
+ GOOGLE_DCHECK_GE(num, 0);
+ GOOGLE_DCHECK_LE(start + num, this->size());
+
+ // Save the values of the removed elements if requested.
+ if (elements != NULL) {
+ for (int i = 0; i < num; ++i)
+ elements[i] = this->Get(i + start);
+ }
+
+ // Slide remaining elements down to fill the gap.
+ if (num > 0) {
+ for (int i = start + num; i < this->size(); ++i)
+ this->Set(i - num, this->Get(i));
+ this->Truncate(this->size() - num);
+ }
+}
+
+template <typename Element>
inline void RepeatedField<Element>::Clear() {
current_size_ = 0;
}
template <typename Element>
inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
- Reserve(current_size_ + other.current_size_);
- CopyArray(elements_ + current_size_, other.elements_, other.current_size_);
- current_size_ += other.current_size_;
+ GOOGLE_CHECK_NE(&other, this);
+ if (other.current_size_ != 0) {
+ Reserve(current_size_ + other.current_size_);
+ CopyArray(elements_ + current_size_, other.elements_, other.current_size_);
+ current_size_ += other.current_size_;
+ }
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
+ if (&other == this) return;
+ Clear();
+ MergeFrom(other);
}
template <typename Element>
@@ -514,35 +754,24 @@ inline const Element* RepeatedField<Element>::data() const {
template <typename Element>
void RepeatedField<Element>::Swap(RepeatedField* other) {
+ if (this == other) return;
Element* swap_elements = elements_;
int swap_current_size = current_size_;
int swap_total_size = total_size_;
- // We may not be using initial_space_ but it's not worth checking. Just
- // copy it anyway.
- Element swap_initial_space[kInitialSize];
- MoveArray(swap_initial_space, initial_space_, kInitialSize);
elements_ = other->elements_;
current_size_ = other->current_size_;
total_size_ = other->total_size_;
- MoveArray(initial_space_, other->initial_space_, kInitialSize);
other->elements_ = swap_elements;
other->current_size_ = swap_current_size;
other->total_size_ = swap_total_size;
- MoveArray(other->initial_space_, swap_initial_space, kInitialSize);
-
- if (elements_ == other->initial_space_) {
- elements_ = initial_space_;
- }
- if (other->elements_ == initial_space_) {
- other->elements_ = other->initial_space_;
- }
}
template <typename Element>
void RepeatedField<Element>::SwapElements(int index1, int index2) {
- std::swap(elements_[index1], elements_[index2]);
+ using std::swap; // enable ADL with fallback
+ swap(elements_[index1], elements_[index2]);
}
template <typename Element>
@@ -568,20 +797,21 @@ RepeatedField<Element>::end() const {
template <typename Element>
inline int RepeatedField<Element>::SpaceUsedExcludingSelf() const {
- return (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
+ return (elements_ != NULL) ? total_size_ * sizeof(elements_[0]) : 0;
}
-// Avoid inlining of Reserve(): new, memcpy, and delete[] lead to a significant
+// Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant
// amount of code bloat.
template <typename Element>
void RepeatedField<Element>::Reserve(int new_size) {
if (total_size_ >= new_size) return;
Element* old_elements = elements_;
- total_size_ = max(total_size_ * 2, new_size);
+ total_size_ = max(google::protobuf::internal::kMinRepeatedFieldAllocationSize,
+ max(total_size_ * 2, new_size));
elements_ = new Element[total_size_];
- MoveArray(elements_, old_elements, current_size_);
- if (old_elements != initial_space_) {
+ if (old_elements != NULL) {
+ MoveArray(elements_, old_elements, current_size_);
delete [] old_elements;
}
}
@@ -594,23 +824,40 @@ inline void RepeatedField<Element>::Truncate(int new_size) {
template <typename Element>
inline void RepeatedField<Element>::MoveArray(
- Element to[], Element from[], int size) {
- memcpy(to, from, size * sizeof(Element));
+ Element to[], Element from[], int array_size) {
+ CopyArray(to, from, array_size);
}
template <typename Element>
inline void RepeatedField<Element>::CopyArray(
- Element to[], const Element from[], int size) {
- memcpy(to, from, size * sizeof(Element));
+ Element to[], const Element from[], int array_size) {
+ internal::ElementCopier<Element>()(to, from, array_size);
}
+namespace internal {
+
+template <typename Element, bool HasTrivialCopy>
+void ElementCopier<Element, HasTrivialCopy>::operator()(
+ Element to[], const Element from[], int array_size) {
+ std::copy(from, from + array_size, to);
+}
+
+template <typename Element>
+struct ElementCopier<Element, true> {
+ void operator()(Element to[], const Element from[], int array_size) {
+ memcpy(to, from, array_size * sizeof(Element));
+ }
+};
+
+} // namespace internal
+
// -------------------------------------------------------------------
namespace internal {
inline RepeatedPtrFieldBase::RepeatedPtrFieldBase()
- : elements_(initial_space_),
+ : elements_(NULL),
current_size_(0),
allocated_size_(0),
total_size_(kInitialSize) {
@@ -621,26 +868,30 @@ void RepeatedPtrFieldBase::Destroy() {
for (int i = 0; i < allocated_size_; i++) {
TypeHandler::Delete(cast<TypeHandler>(elements_[i]));
}
- if (elements_ != initial_space_) {
- delete [] elements_;
- }
+ delete [] elements_;
+}
+
+inline bool RepeatedPtrFieldBase::empty() const {
+ return current_size_ == 0;
}
inline int RepeatedPtrFieldBase::size() const {
return current_size_;
}
-
template <typename TypeHandler>
inline const typename TypeHandler::Type&
RepeatedPtrFieldBase::Get(int index) const {
+ GOOGLE_DCHECK_GE(index, 0);
GOOGLE_DCHECK_LT(index, size());
return *cast<TypeHandler>(elements_[index]);
}
+
template <typename TypeHandler>
inline typename TypeHandler::Type*
RepeatedPtrFieldBase::Mutable(int index) {
+ GOOGLE_DCHECK_GE(index, 0);
GOOGLE_DCHECK_LT(index, size());
return cast<TypeHandler>(elements_[index]);
}
@@ -651,8 +902,8 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add() {
return cast<TypeHandler>(elements_[current_size_++]);
}
if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
- ++allocated_size_;
typename TypeHandler::Type* result = TypeHandler::New();
+ ++allocated_size_;
elements_[current_size_++] = result;
return result;
}
@@ -673,12 +924,20 @@ void RepeatedPtrFieldBase::Clear() {
template <typename TypeHandler>
inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
+ GOOGLE_CHECK_NE(&other, this);
Reserve(current_size_ + other.current_size_);
for (int i = 0; i < other.current_size_; i++) {
- TypeHandler::Merge(other.Get<TypeHandler>(i), Add<TypeHandler>());
+ TypeHandler::Merge(other.template Get<TypeHandler>(i), Add<TypeHandler>());
}
}
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) {
+ if (&other == this) return;
+ RepeatedPtrFieldBase::Clear<TypeHandler>();
+ RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
+}
+
inline int RepeatedPtrFieldBase::Capacity() const {
return total_size_;
}
@@ -707,13 +966,14 @@ RepeatedPtrFieldBase::data() const {
}
inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) {
- std::swap(elements_[index1], elements_[index2]);
+ using std::swap; // enable ADL with fallback
+ swap(elements_[index1], elements_[index2]);
}
template <typename TypeHandler>
inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const {
int allocated_bytes =
- (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
+ (elements_ != NULL) ? total_size_ * sizeof(elements_[0]) : 0;
for (int i = 0; i < allocated_size_; ++i) {
allocated_bytes += TypeHandler::SpaceUsed(*cast<TypeHandler>(elements_[i]));
}
@@ -770,7 +1030,6 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() {
return result;
}
-
inline int RepeatedPtrFieldBase::ClearedCount() const {
return allocated_size_ - current_size_;
}
@@ -794,22 +1053,57 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() {
template <typename Element>
class RepeatedPtrField<Element>::TypeHandler
- : public internal::GenericTypeHandler<Element> {};
+ : public internal::GenericTypeHandler<Element> {
+};
template <>
class RepeatedPtrField<string>::TypeHandler
- : public internal::StringTypeHandler {};
+ : public internal::StringTypeHandler {
+};
template <typename Element>
inline RepeatedPtrField<Element>::RepeatedPtrField() {}
template <typename Element>
+inline RepeatedPtrField<Element>::RepeatedPtrField(
+ const RepeatedPtrField& other)
+ : RepeatedPtrFieldBase() {
+ CopyFrom(other);
+}
+
+template <typename Element>
+template <typename Iter>
+inline RepeatedPtrField<Element>::RepeatedPtrField(
+ Iter begin, const Iter& end) {
+ int reserve = internal::CalculateReserve(begin, end);
+ if (reserve != -1) {
+ Reserve(reserve);
+ }
+ for (; begin != end; ++begin) {
+ *Add() = *begin;
+ }
+}
+
+template <typename Element>
RepeatedPtrField<Element>::~RepeatedPtrField() {
Destroy<TypeHandler>();
}
template <typename Element>
+inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
+ const RepeatedPtrField& other) {
+ if (this != &other)
+ CopyFrom(other);
+ return *this;
+}
+
+template <typename Element>
+inline bool RepeatedPtrField<Element>::empty() const {
+ return RepeatedPtrFieldBase::empty();
+}
+
+template <typename Element>
inline int RepeatedPtrField<Element>::size() const {
return RepeatedPtrFieldBase::size();
}
@@ -819,6 +1113,7 @@ inline const Element& RepeatedPtrField<Element>::Get(int index) const {
return RepeatedPtrFieldBase::Get<TypeHandler>(index);
}
+
template <typename Element>
inline Element* RepeatedPtrField<Element>::Mutable(int index) {
return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
@@ -835,6 +1130,33 @@ inline void RepeatedPtrField<Element>::RemoveLast() {
}
template <typename Element>
+inline void RepeatedPtrField<Element>::DeleteSubrange(int start, int num) {
+ GOOGLE_DCHECK_GE(start, 0);
+ GOOGLE_DCHECK_GE(num, 0);
+ GOOGLE_DCHECK_LE(start + num, size());
+ for (int i = 0; i < num; ++i)
+ delete RepeatedPtrFieldBase::Mutable<TypeHandler>(start + i);
+ ExtractSubrange(start, num, NULL);
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::ExtractSubrange(
+ int start, int num, Element** elements) {
+ GOOGLE_DCHECK_GE(start, 0);
+ GOOGLE_DCHECK_GE(num, 0);
+ GOOGLE_DCHECK_LE(start + num, size());
+
+ if (num > 0) {
+ // Save the values of the removed elements if requested.
+ if (elements != NULL) {
+ for (int i = 0; i < num; ++i)
+ elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
+ }
+ CloseGap(start, num);
+ }
+}
+
+template <typename Element>
inline void RepeatedPtrField<Element>::Clear() {
RepeatedPtrFieldBase::Clear<TypeHandler>();
}
@@ -846,6 +1168,12 @@ inline void RepeatedPtrField<Element>::MergeFrom(
}
template <typename Element>
+inline void RepeatedPtrField<Element>::CopyFrom(
+ const RepeatedPtrField& other) {
+ RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other);
+}
+
+template <typename Element>
inline Element** RepeatedPtrField<Element>::mutable_data() {
return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
}
@@ -914,7 +1242,7 @@ namespace internal {
// refer to this class directly; use RepeatedPtrField<T>::iterator instead.
//
// The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is
-// very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors-inl.h,
+// very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors.h,
// but adds random-access operators and is modified to wrap a void** base
// iterator (since RepeatedPtrField stores its array as a void* array and
// casting void** to T** would violate C++ aliasing rules).
@@ -930,6 +1258,10 @@ class RepeatedPtrIterator
typedef std::iterator<
std::random_access_iterator_tag, Element> superclass;
+ // Shadow the value_type in std::iterator<> because const_iterator::value_type
+ // needs to be T, not const T.
+ typedef typename remove_const<Element>::type value_type;
+
// Let the compiler know that these are type names, so we don't have to
// write "typename" in front of them everywhere.
typedef typename superclass::reference reference;
@@ -944,7 +1276,7 @@ class RepeatedPtrIterator
template<typename OtherElement>
RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
: it_(other.it_) {
- // Force a compiler error if the other type is not convertable to ours.
+ // Force a compiler error if the other type is not convertible to ours.
if (false) {
implicit_cast<Element*, OtherElement*>(0);
}
@@ -1010,14 +1342,21 @@ class RepeatedPtrIterator
// rather than the objects themselves as RepeatedPtrIterator does.
// Consider using this when working with stl algorithms that change
// the array.
-template<typename Element>
+// The VoidPtr template parameter holds the type-agnostic pointer value
+// referenced by the iterator. It should either be "void *" for a mutable
+// iterator, or "const void *" for a constant iterator.
+template<typename Element, typename VoidPtr>
class RepeatedPtrOverPtrsIterator
: public std::iterator<std::random_access_iterator_tag, Element*> {
public:
- typedef RepeatedPtrOverPtrsIterator<Element> iterator;
+ typedef RepeatedPtrOverPtrsIterator<Element, VoidPtr> iterator;
typedef std::iterator<
std::random_access_iterator_tag, Element*> superclass;
+ // Shadow the value_type in std::iterator<> because const_iterator::value_type
+ // needs to be T, not const T.
+ typedef typename remove_const<Element*>::type value_type;
+
// Let the compiler know that these are type names, so we don't have to
// write "typename" in front of them everywhere.
typedef typename superclass::reference reference;
@@ -1025,7 +1364,7 @@ class RepeatedPtrOverPtrsIterator
typedef typename superclass::difference_type difference_type;
RepeatedPtrOverPtrsIterator() : it_(NULL) {}
- explicit RepeatedPtrOverPtrsIterator(void** it) : it_(it) {}
+ explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}
// dereferenceable
reference operator*() const { return *reinterpret_cast<Element**>(it_); }
@@ -1080,10 +1419,9 @@ class RepeatedPtrOverPtrsIterator
friend class RepeatedPtrIterator;
// The internal iterator.
- void** it_;
+ VoidPtr* it_;
};
-
} // namespace internal
template <typename Element>
@@ -1113,10 +1451,21 @@ RepeatedPtrField<Element>::pointer_begin() {
return pointer_iterator(raw_mutable_data());
}
template <typename Element>
+inline typename RepeatedPtrField<Element>::const_pointer_iterator
+RepeatedPtrField<Element>::pointer_begin() const {
+ return const_pointer_iterator(const_cast<const void**>(raw_mutable_data()));
+}
+template <typename Element>
inline typename RepeatedPtrField<Element>::pointer_iterator
RepeatedPtrField<Element>::pointer_end() {
return pointer_iterator(raw_mutable_data() + size());
}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_pointer_iterator
+RepeatedPtrField<Element>::pointer_end() const {
+ return const_pointer_iterator(
+ const_cast<const void**>(raw_mutable_data() + size()));
+}
// Iterators and helper functions that follow the spirit of the STL
@@ -1126,7 +1475,7 @@ RepeatedPtrField<Element>::pointer_end() {
// std::copy(some_sequence.begin(), some_sequence.end(),
// google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
//
-// Ported by johannes from util/gtl/proto-array-iterators-inl.h
+// Ported by johannes from util/gtl/proto-array-iterators.h
namespace internal {
// A back inserter for RepeatedField objects.
@@ -1147,12 +1496,12 @@ template<typename T> class RepeatedFieldBackInsertIterator
RepeatedFieldBackInsertIterator<T>& operator++() {
return *this;
}
- RepeatedFieldBackInsertIterator<T>& operator++(int ignores_parameter) {
+ RepeatedFieldBackInsertIterator<T>& operator++(int /* unused */) {
return *this;
}
private:
- RepeatedField<T>* const field_;
+ RepeatedField<T>* field_;
};
// A back inserter for RepeatedPtrField objects.
@@ -1178,12 +1527,12 @@ template<typename T> class RepeatedPtrFieldBackInsertIterator
RepeatedPtrFieldBackInsertIterator<T>& operator++() {
return *this;
}
- RepeatedPtrFieldBackInsertIterator<T>& operator++(int ignores_parameter) {
+ RepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) {
return *this;
}
private:
- RepeatedPtrField<T>* const field_;
+ RepeatedPtrField<T>* field_;
};
// A back inserter for RepeatedPtrFields that inserts by transfering ownership
@@ -1207,26 +1556,32 @@ template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
return *this;
}
AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
- int ignores_parameter) {
+ int /* unused */) {
return *this;
}
private:
- RepeatedPtrField<T>* const field_;
+ RepeatedPtrField<T>* field_;
};
} // namespace internal
// Provides a back insert iterator for RepeatedField instances,
-// similar to std::back_inserter(). Note the identically named
-// function for RepeatedPtrField instances.
+// similar to std::back_inserter().
template<typename T> internal::RepeatedFieldBackInsertIterator<T>
RepeatedFieldBackInserter(RepeatedField<T>* const mutable_field) {
return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
}
// Provides a back insert iterator for RepeatedPtrField instances,
-// similar to std::back_inserter(). Note the identically named
-// function for RepeatedField instances.
+// similar to std::back_inserter().
+template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
+RepeatedPtrFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
+ return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
+}
+
+// Special back insert iterator for RepeatedPtrField instances, just in
+// case someone wants to write generic template code that can access both
+// RepeatedFields and RepeatedPtrFields using a common name.
template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
RepeatedFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
diff --git a/src/google/protobuf/repeated_field_reflection_unittest.cc b/src/google/protobuf/repeated_field_reflection_unittest.cc
new file mode 100644
index 0000000..62833aa
--- /dev/null
+++ b/src/google/protobuf/repeated_field_reflection_unittest.cc
@@ -0,0 +1,195 @@
+// 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: tgs@google.com (Tom Szymanski)
+//
+// Test reflection methods for aggregate access to Repeated[Ptr]Fields.
+// This test proto2 methods on a proto2 layout.
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/test_util.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+using unittest::ForeignMessage;
+using unittest::TestAllTypes;
+using unittest::TestAllExtensions;
+
+namespace {
+
+static int Func(int i, int j) {
+ return i * j;
+}
+
+static string StrFunc(int i, int j) {
+ string str;
+ SStringPrintf(&str, "%d", Func(i, 4));
+ return str;
+}
+
+
+TEST(RepeatedFieldReflectionTest, RegularFields) {
+ TestAllTypes message;
+ const Reflection* refl = message.GetReflection();
+ const Descriptor* desc = message.GetDescriptor();
+
+ for (int i = 0; i < 10; ++i) {
+ message.add_repeated_int32(Func(i, 1));
+ message.add_repeated_double(Func(i, 2));
+ message.add_repeated_string(StrFunc(i, 5));
+ message.add_repeated_foreign_message()->set_c(Func(i, 6));
+ }
+
+ // Get FieldDescriptors for all the fields of interest.
+ const FieldDescriptor* fd_repeated_int32 =
+ desc->FindFieldByName("repeated_int32");
+ const FieldDescriptor* fd_repeated_double =
+ desc->FindFieldByName("repeated_double");
+ const FieldDescriptor* fd_repeated_string =
+ desc->FindFieldByName("repeated_string");
+ const FieldDescriptor* fd_repeated_foreign_message =
+ desc->FindFieldByName("repeated_foreign_message");
+
+ // Get RepeatedField objects for all fields of interest.
+ const RepeatedField<int32>& rf_int32 =
+ refl->GetRepeatedField<int32>(message, fd_repeated_int32);
+ const RepeatedField<double>& rf_double =
+ refl->GetRepeatedField<double>(message, fd_repeated_double);
+
+ // Get mutable RepeatedField objects for all fields of interest.
+ RepeatedField<int32>* mrf_int32 =
+ refl->MutableRepeatedField<int32>(&message, fd_repeated_int32);
+ RepeatedField<double>* mrf_double =
+ refl->MutableRepeatedField<double>(&message, fd_repeated_double);
+
+ // Get RepeatedPtrField objects for all fields of interest.
+ const RepeatedPtrField<string>& rpf_string =
+ refl->GetRepeatedPtrField<string>(message, fd_repeated_string);
+ const RepeatedPtrField<ForeignMessage>& rpf_foreign_message =
+ refl->GetRepeatedPtrField<ForeignMessage>(
+ message, fd_repeated_foreign_message);
+ const RepeatedPtrField<Message>& rpf_message =
+ refl->GetRepeatedPtrField<Message>(
+ message, fd_repeated_foreign_message);
+
+ // Get mutable RepeatedPtrField objects for all fields of interest.
+ RepeatedPtrField<string>* mrpf_string =
+ refl->MutableRepeatedPtrField<string>(&message, fd_repeated_string);
+ RepeatedPtrField<ForeignMessage>* mrpf_foreign_message =
+ refl->MutableRepeatedPtrField<ForeignMessage>(
+ &message, fd_repeated_foreign_message);
+ RepeatedPtrField<Message>* mrpf_message =
+ refl->MutableRepeatedPtrField<Message>(
+ &message, fd_repeated_foreign_message);
+
+ // Make sure we can do get and sets through the Repeated[Ptr]Field objects.
+ for (int i = 0; i < 10; ++i) {
+ // Check gets through const objects.
+ EXPECT_EQ(rf_int32.Get(i), Func(i, 1));
+ EXPECT_EQ(rf_double.Get(i), Func(i, 2));
+ EXPECT_EQ(rpf_string.Get(i), StrFunc(i, 5));
+ EXPECT_EQ(rpf_foreign_message.Get(i).c(), Func(i, 6));
+ EXPECT_EQ(down_cast<const ForeignMessage*>(&rpf_message.Get(i))->c(),
+ Func(i, 6));
+
+ // Check gets through mutable objects.
+ EXPECT_EQ(mrf_int32->Get(i), Func(i, 1));
+ EXPECT_EQ(mrf_double->Get(i), Func(i, 2));
+ EXPECT_EQ(mrpf_string->Get(i), StrFunc(i, 5));
+ EXPECT_EQ(mrpf_foreign_message->Get(i).c(), Func(i, 6));
+ EXPECT_EQ(down_cast<const ForeignMessage*>(&mrpf_message->Get(i))->c(),
+ Func(i, 6));
+
+ // Check sets through mutable objects.
+ mrf_int32->Set(i, Func(i, -1));
+ mrf_double->Set(i, Func(i, -2));
+ mrpf_string->Mutable(i)->assign(StrFunc(i, -5));
+ mrpf_foreign_message->Mutable(i)->set_c(Func(i, -6));
+ EXPECT_EQ(message.repeated_int32(i), Func(i, -1));
+ EXPECT_EQ(message.repeated_double(i), Func(i, -2));
+ EXPECT_EQ(message.repeated_string(i), StrFunc(i, -5));
+ EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, -6));
+ down_cast<ForeignMessage*>(mrpf_message->Mutable(i))->set_c(Func(i, 7));
+ EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, 7));
+ }
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+ // Make sure types are checked correctly at runtime.
+ const FieldDescriptor* fd_optional_int32 =
+ desc->FindFieldByName("optional_int32");
+ EXPECT_DEATH(refl->GetRepeatedField<int32>(
+ message, fd_optional_int32), "requires a repeated field");
+ EXPECT_DEATH(refl->GetRepeatedField<double>(
+ message, fd_repeated_int32), "not the right type");
+ EXPECT_DEATH(refl->GetRepeatedPtrField<TestAllTypes>(
+ message, fd_repeated_foreign_message), "wrong submessage type");
+#endif // PROTOBUF_HAS_DEATH_TEST
+}
+
+
+
+
+TEST(RepeatedFieldReflectionTest, ExtensionFields) {
+ TestAllExtensions extended_message;
+ const Reflection* refl = extended_message.GetReflection();
+ const Descriptor* desc = extended_message.GetDescriptor();
+
+ for (int i = 0; i < 10; ++i) {
+ extended_message.AddExtension(
+ unittest::repeated_int64_extension, Func(i, 1));
+ }
+
+ const FieldDescriptor* fd_repeated_int64_extension =
+ desc->file()->FindExtensionByName("repeated_int64_extension");
+ GOOGLE_CHECK(fd_repeated_int64_extension != NULL);
+
+ const RepeatedField<int64>& rf_int64_extension =
+ refl->GetRepeatedField<int64>(extended_message,
+ fd_repeated_int64_extension);
+
+ RepeatedField<int64>* mrf_int64_extension =
+ refl->MutableRepeatedField<int64>(&extended_message,
+ fd_repeated_int64_extension);
+
+ for (int i = 0; i < 10; ++i) {
+ EXPECT_EQ(Func(i, 1), rf_int64_extension.Get(i));
+ mrf_int64_extension->Set(i, Func(i, -1));
+ EXPECT_EQ(Func(i, -1),
+ extended_message.GetExtension(unittest::repeated_int64_extension, i));
+ }
+}
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc
index 7c35f60..f4d48f5 100644
--- a/src/google/protobuf/repeated_field_unittest.cc
+++ b/src/google/protobuf/repeated_field_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -36,6 +36,7 @@
// other proto2 unittests.
#include <algorithm>
+#include <limits>
#include <list>
#include <vector>
@@ -46,7 +47,7 @@
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
using protobuf_unittest::TestAllTypes;
@@ -54,42 +55,48 @@ using protobuf_unittest::TestAllTypes;
namespace protobuf {
namespace {
-// Test operations on a RepeatedField which is small enough that it does
-// not allocate a separate array for storage.
+// Test operations on a small RepeatedField.
TEST(RepeatedField, Small) {
RepeatedField<int> field;
+ EXPECT_TRUE(field.empty());
EXPECT_EQ(field.size(), 0);
field.Add(5);
+ EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 1);
EXPECT_EQ(field.Get(0), 5);
field.Add(42);
+ EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 2);
EXPECT_EQ(field.Get(0), 5);
EXPECT_EQ(field.Get(1), 42);
field.Set(1, 23);
+ EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 2);
EXPECT_EQ(field.Get(0), 5);
EXPECT_EQ(field.Get(1), 23);
- EXPECT_EQ(field.SpaceUsedExcludingSelf(), 0);
field.RemoveLast();
+ EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 1);
EXPECT_EQ(field.Get(0), 5);
field.Clear();
+ EXPECT_TRUE(field.empty());
EXPECT_EQ(field.size(), 0);
- EXPECT_EQ(field.SpaceUsedExcludingSelf(), 0);
+ int expected_usage = 4 * sizeof(int);
+ EXPECT_EQ(field.SpaceUsedExcludingSelf(), expected_usage);
}
+
// Test operations on a RepeatedField which is large enough to allocate a
// separate array.
TEST(RepeatedField, Large) {
@@ -99,6 +106,7 @@ TEST(RepeatedField, Large) {
field.Add(i * i);
}
+ EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 16);
for (int i = 0; i < 16; i++) {
@@ -117,9 +125,20 @@ TEST(RepeatedField, SwapSmallSmall) {
field1.Add(5);
field1.Add(42);
+ EXPECT_FALSE(field1.empty());
+ EXPECT_EQ(field1.size(), 2);
+ EXPECT_EQ(field1.Get(0), 5);
+ EXPECT_EQ(field1.Get(1), 42);
+
+ EXPECT_TRUE(field2.empty());
+ EXPECT_EQ(field2.size(), 0);
+
field1.Swap(&field2);
+ EXPECT_TRUE(field1.empty());
EXPECT_EQ(field1.size(), 0);
+
+ EXPECT_FALSE(field2.empty());
EXPECT_EQ(field2.size(), 2);
EXPECT_EQ(field2.Get(0), 5);
EXPECT_EQ(field2.Get(1), 42);
@@ -211,12 +230,26 @@ TEST(RepeatedField, ReserveLessThanExisting) {
EXPECT_EQ(20, ReservedSpace(&field));
}
+TEST(RepeatedField, Resize) {
+ RepeatedField<int> field;
+ field.Resize(2, 1);
+ EXPECT_EQ(2, field.size());
+ field.Resize(5, 2);
+ EXPECT_EQ(5, field.size());
+ field.Resize(4, 3);
+ ASSERT_EQ(4, field.size());
+ EXPECT_EQ(1, field.Get(0));
+ EXPECT_EQ(1, field.Get(1));
+ EXPECT_EQ(2, field.Get(2));
+ EXPECT_EQ(2, field.Get(3));
+ field.Resize(0, 4);
+ EXPECT_TRUE(field.empty());
+}
+
TEST(RepeatedField, MergeFrom) {
RepeatedField<int> source, destination;
-
source.Add(4);
source.Add(5);
-
destination.Add(1);
destination.Add(2);
destination.Add(3);
@@ -224,7 +257,6 @@ TEST(RepeatedField, MergeFrom) {
destination.MergeFrom(source);
ASSERT_EQ(5, destination.size());
-
EXPECT_EQ(1, destination.Get(0));
EXPECT_EQ(2, destination.Get(1));
EXPECT_EQ(3, destination.Get(2));
@@ -232,6 +264,94 @@ TEST(RepeatedField, MergeFrom) {
EXPECT_EQ(5, destination.Get(4));
}
+#ifdef PROTOBUF_HAS_DEATH_TEST
+TEST(RepeatedField, MergeFromSelf) {
+ RepeatedField<int> me;
+ me.Add(3);
+ EXPECT_DEATH(me.MergeFrom(me), "");
+}
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+TEST(RepeatedField, CopyFrom) {
+ RepeatedField<int> source, destination;
+ source.Add(4);
+ source.Add(5);
+ destination.Add(1);
+ destination.Add(2);
+ destination.Add(3);
+
+ destination.CopyFrom(source);
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ(4, destination.Get(0));
+ EXPECT_EQ(5, destination.Get(1));
+}
+
+TEST(RepeatedField, CopyFromSelf) {
+ RepeatedField<int> me;
+ me.Add(3);
+ me.CopyFrom(me);
+ ASSERT_EQ(1, me.size());
+ EXPECT_EQ(3, me.Get(0));
+}
+
+TEST(RepeatedField, CopyConstruct) {
+ RepeatedField<int> source;
+ source.Add(1);
+ source.Add(2);
+
+ RepeatedField<int> destination(source);
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ(1, destination.Get(0));
+ EXPECT_EQ(2, destination.Get(1));
+}
+
+TEST(RepeatedField, IteratorConstruct) {
+ vector<int> values;
+ values.push_back(1);
+ values.push_back(2);
+
+ RepeatedField<int> field(values.begin(), values.end());
+ ASSERT_EQ(values.size(), field.size());
+ EXPECT_EQ(values[0], field.Get(0));
+ EXPECT_EQ(values[1], field.Get(1));
+
+ RepeatedField<int> other(field.begin(), field.end());
+ ASSERT_EQ(values.size(), other.size());
+ EXPECT_EQ(values[0], other.Get(0));
+ EXPECT_EQ(values[1], other.Get(1));
+}
+
+TEST(RepeatedField, CopyAssign) {
+ RepeatedField<int> source, destination;
+ source.Add(4);
+ source.Add(5);
+ destination.Add(1);
+ destination.Add(2);
+ destination.Add(3);
+
+ destination = source;
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ(4, destination.Get(0));
+ EXPECT_EQ(5, destination.Get(1));
+}
+
+TEST(RepeatedField, SelfAssign) {
+ // Verify that assignment to self does not destroy data.
+ RepeatedField<int> source, *p;
+ p = &source;
+ source.Add(7);
+ source.Add(8);
+
+ *p = source;
+
+ ASSERT_EQ(2, source.size());
+ EXPECT_EQ(7, source.Get(0));
+ EXPECT_EQ(8, source.Get(1));
+}
+
TEST(RepeatedField, MutableDataIsMutable) {
RepeatedField<int> field;
field.Add(1);
@@ -261,12 +381,47 @@ TEST(RepeatedField, Truncate) {
// Truncations that don't change the size are allowed, but growing is not
// allowed.
field.Truncate(field.size());
-#ifdef GTEST_HAS_DEATH_TEST
+#ifdef PROTOBUF_HAS_DEATH_TEST
EXPECT_DEBUG_DEATH(field.Truncate(field.size() + 1), "new_size");
#endif
}
+TEST(RepeatedField, ExtractSubrange) {
+ // Exhaustively test every subrange in arrays of all sizes from 0 through 9.
+ for (int sz = 0; sz < 10; ++sz) {
+ for (int num = 0; num <= sz; ++num) {
+ for (int start = 0; start < sz - num; ++start) {
+ // Create RepeatedField with sz elements having values 0 through sz-1.
+ RepeatedField<int32> field;
+ for (int i = 0; i < sz; ++i)
+ field.Add(i);
+ EXPECT_EQ(field.size(), sz);
+
+ // Create a catcher array and call ExtractSubrange.
+ int32 catcher[10];
+ for (int i = 0; i < 10; ++i)
+ catcher[i] = -1;
+ field.ExtractSubrange(start, num, catcher);
+
+ // Does the resulting array have the right size?
+ EXPECT_EQ(field.size(), sz - num);
+
+ // Were the removed elements extracted into the catcher array?
+ for (int i = 0; i < num; ++i)
+ EXPECT_EQ(catcher[i], start + i);
+ EXPECT_EQ(catcher[num], -1);
+
+ // Does the resulting array contain the right values?
+ for (int i = 0; i < start; ++i)
+ EXPECT_EQ(field.Get(i), i);
+ for (int i = start; i < field.size(); ++i)
+ EXPECT_EQ(field.Get(i), i + num);
+ }
+ }
+ }
+}
+
// ===================================================================
// RepeatedPtrField tests. These pretty much just mirror the RepeatedField
// tests above.
@@ -274,32 +429,38 @@ TEST(RepeatedField, Truncate) {
TEST(RepeatedPtrField, Small) {
RepeatedPtrField<string> field;
+ EXPECT_TRUE(field.empty());
EXPECT_EQ(field.size(), 0);
field.Add()->assign("foo");
+ EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 1);
EXPECT_EQ(field.Get(0), "foo");
field.Add()->assign("bar");
+ EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 2);
EXPECT_EQ(field.Get(0), "foo");
EXPECT_EQ(field.Get(1), "bar");
field.Mutable(1)->assign("baz");
+ EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 2);
EXPECT_EQ(field.Get(0), "foo");
EXPECT_EQ(field.Get(1), "baz");
field.RemoveLast();
+ EXPECT_FALSE(field.empty());
EXPECT_EQ(field.size(), 1);
EXPECT_EQ(field.Get(0), "foo");
field.Clear();
+ EXPECT_TRUE(field.empty());
EXPECT_EQ(field.size(), 0);
}
@@ -325,11 +486,27 @@ TEST(RepeatedPtrField, SwapSmallSmall) {
RepeatedPtrField<string> field1;
RepeatedPtrField<string> field2;
+ EXPECT_TRUE(field1.empty());
+ EXPECT_EQ(field1.size(), 0);
+ EXPECT_TRUE(field2.empty());
+ EXPECT_EQ(field2.size(), 0);
+
field1.Add()->assign("foo");
field1.Add()->assign("bar");
+
+ EXPECT_FALSE(field1.empty());
+ EXPECT_EQ(field1.size(), 2);
+ EXPECT_EQ(field1.Get(0), "foo");
+ EXPECT_EQ(field1.Get(1), "bar");
+
+ EXPECT_TRUE(field2.empty());
+ EXPECT_EQ(field2.size(), 0);
+
field1.Swap(&field2);
+ EXPECT_TRUE(field1.empty());
EXPECT_EQ(field1.size(), 0);
+
EXPECT_EQ(field2.size(), 2);
EXPECT_EQ(field2.Get(0), "foo");
EXPECT_EQ(field2.Get(1), "bar");
@@ -517,10 +694,8 @@ TEST(RepeatedPtrField, AddAlocated) {
TEST(RepeatedPtrField, MergeFrom) {
RepeatedPtrField<string> source, destination;
-
source.Add()->assign("4");
source.Add()->assign("5");
-
destination.Add()->assign("1");
destination.Add()->assign("2");
destination.Add()->assign("3");
@@ -528,7 +703,6 @@ TEST(RepeatedPtrField, MergeFrom) {
destination.MergeFrom(source);
ASSERT_EQ(5, destination.size());
-
EXPECT_EQ("1", destination.Get(0));
EXPECT_EQ("2", destination.Get(1));
EXPECT_EQ("3", destination.Get(2));
@@ -536,6 +710,113 @@ TEST(RepeatedPtrField, MergeFrom) {
EXPECT_EQ("5", destination.Get(4));
}
+#ifdef PROTOBUF_HAS_DEATH_TEST
+TEST(RepeatedPtrField, MergeFromSelf) {
+ RepeatedPtrField<string> me;
+ me.Add()->assign("1");
+ EXPECT_DEATH(me.MergeFrom(me), "");
+}
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+TEST(RepeatedPtrField, CopyFrom) {
+ RepeatedPtrField<string> source, destination;
+ source.Add()->assign("4");
+ source.Add()->assign("5");
+ destination.Add()->assign("1");
+ destination.Add()->assign("2");
+ destination.Add()->assign("3");
+
+ destination.CopyFrom(source);
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ("4", destination.Get(0));
+ EXPECT_EQ("5", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, CopyFromSelf) {
+ RepeatedPtrField<string> me;
+ me.Add()->assign("1");
+ me.CopyFrom(me);
+ ASSERT_EQ(1, me.size());
+ EXPECT_EQ("1", me.Get(0));
+}
+
+TEST(RepeatedPtrField, CopyConstruct) {
+ RepeatedPtrField<string> source;
+ source.Add()->assign("1");
+ source.Add()->assign("2");
+
+ RepeatedPtrField<string> destination(source);
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ("1", destination.Get(0));
+ EXPECT_EQ("2", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, IteratorConstruct_String) {
+ vector<string> values;
+ values.push_back("1");
+ values.push_back("2");
+
+ RepeatedPtrField<string> field(values.begin(), values.end());
+ ASSERT_EQ(values.size(), field.size());
+ EXPECT_EQ(values[0], field.Get(0));
+ EXPECT_EQ(values[1], field.Get(1));
+
+ RepeatedPtrField<string> other(field.begin(), field.end());
+ ASSERT_EQ(values.size(), other.size());
+ EXPECT_EQ(values[0], other.Get(0));
+ EXPECT_EQ(values[1], other.Get(1));
+}
+
+TEST(RepeatedPtrField, IteratorConstruct_Proto) {
+ typedef TestAllTypes::NestedMessage Nested;
+ vector<Nested> values;
+ values.push_back(Nested());
+ values.back().set_bb(1);
+ values.push_back(Nested());
+ values.back().set_bb(2);
+
+ RepeatedPtrField<Nested> field(values.begin(), values.end());
+ ASSERT_EQ(values.size(), field.size());
+ EXPECT_EQ(values[0].bb(), field.Get(0).bb());
+ EXPECT_EQ(values[1].bb(), field.Get(1).bb());
+
+ RepeatedPtrField<Nested> other(field.begin(), field.end());
+ ASSERT_EQ(values.size(), other.size());
+ EXPECT_EQ(values[0].bb(), other.Get(0).bb());
+ EXPECT_EQ(values[1].bb(), other.Get(1).bb());
+}
+
+TEST(RepeatedPtrField, CopyAssign) {
+ RepeatedPtrField<string> source, destination;
+ source.Add()->assign("4");
+ source.Add()->assign("5");
+ destination.Add()->assign("1");
+ destination.Add()->assign("2");
+ destination.Add()->assign("3");
+
+ destination = source;
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ("4", destination.Get(0));
+ EXPECT_EQ("5", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, SelfAssign) {
+ // Verify that assignment to self does not destroy data.
+ RepeatedPtrField<string> source, *p;
+ p = &source;
+ source.Add()->assign("7");
+ source.Add()->assign("8");
+
+ *p = source;
+
+ ASSERT_EQ(2, source.size());
+ EXPECT_EQ("7", source.Get(0));
+ EXPECT_EQ("8", source.Get(1));
+}
+
TEST(RepeatedPtrField, MutableDataIsMutable) {
RepeatedPtrField<string> field;
*field.Add() = "1";
@@ -547,6 +828,77 @@ TEST(RepeatedPtrField, MutableDataIsMutable) {
EXPECT_EQ("2", field.Get(0));
}
+TEST(RepeatedPtrField, ExtractSubrange) {
+ // Exhaustively test every subrange in arrays of all sizes from 0 through 9
+ // with 0 through 3 cleared elements at the end.
+ for (int sz = 0; sz < 10; ++sz) {
+ for (int num = 0; num <= sz; ++num) {
+ for (int start = 0; start < sz - num; ++start) {
+ for (int extra = 0; extra < 4; ++extra) {
+ vector<string*> subject;
+
+ // Create an array with "sz" elements and "extra" cleared elements.
+ RepeatedPtrField<string> field;
+ for (int i = 0; i < sz + extra; ++i) {
+ subject.push_back(new string());
+ field.AddAllocated(subject[i]);
+ }
+ EXPECT_EQ(field.size(), sz + extra);
+ for (int i = 0; i < extra; ++i)
+ field.RemoveLast();
+ EXPECT_EQ(field.size(), sz);
+ EXPECT_EQ(field.ClearedCount(), extra);
+
+ // Create a catcher array and call ExtractSubrange.
+ string* catcher[10];
+ for (int i = 0; i < 10; ++i)
+ catcher[i] = NULL;
+ field.ExtractSubrange(start, num, catcher);
+
+ // Does the resulting array have the right size?
+ EXPECT_EQ(field.size(), sz - num);
+
+ // Were the removed elements extracted into the catcher array?
+ for (int i = 0; i < num; ++i)
+ EXPECT_EQ(catcher[i], subject[start + i]);
+ EXPECT_EQ(NULL, catcher[num]);
+
+ // Does the resulting array contain the right values?
+ for (int i = 0; i < start; ++i)
+ EXPECT_EQ(field.Mutable(i), subject[i]);
+ for (int i = start; i < field.size(); ++i)
+ EXPECT_EQ(field.Mutable(i), subject[i + num]);
+
+ // Reinstate the cleared elements.
+ EXPECT_EQ(field.ClearedCount(), extra);
+ for (int i = 0; i < extra; ++i)
+ field.Add();
+ EXPECT_EQ(field.ClearedCount(), 0);
+ EXPECT_EQ(field.size(), sz - num + extra);
+
+ // Make sure the extra elements are all there (in some order).
+ for (int i = sz; i < sz + extra; ++i) {
+ int count = 0;
+ for (int j = sz; j < sz + extra; ++j) {
+ if (field.Mutable(j - num) == subject[i])
+ count += 1;
+ }
+ EXPECT_EQ(count, 1);
+ }
+
+ // Release the caught elements.
+ for (int i = 0; i < num; ++i)
+ delete catcher[i];
+ }
+ }
+ }
+ }
+}
+
+TEST(RepeatedPtrField, DeleteSubrange) {
+ // DeleteSubrange is a trivial extension of ExtendSubrange.
+}
+
// ===================================================================
// Iterator tests stolen from net/proto/proto-array_unittest.
@@ -564,7 +916,8 @@ class RepeatedFieldIteratorTest : public testing::Test {
TEST_F(RepeatedFieldIteratorTest, Convertible) {
RepeatedField<int>::iterator iter = proto_array_.begin();
RepeatedField<int>::const_iterator c_iter = iter;
- EXPECT_EQ(0, *c_iter);
+ RepeatedField<int>::value_type value = *c_iter;
+ EXPECT_EQ(0, value);
}
TEST_F(RepeatedFieldIteratorTest, MutableIteration) {
@@ -613,6 +966,8 @@ class RepeatedPtrFieldIteratorTest : public testing::Test {
TEST_F(RepeatedPtrFieldIteratorTest, Convertible) {
RepeatedPtrField<string>::iterator iter = proto_array_.begin();
RepeatedPtrField<string>::const_iterator c_iter = iter;
+ RepeatedPtrField<string>::value_type value = *c_iter;
+ EXPECT_EQ("foo", value);
}
TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) {
@@ -638,6 +993,30 @@ TEST_F(RepeatedPtrFieldIteratorTest, ConstIteration) {
EXPECT_EQ("baz", *(--const_proto_array.end()));
}
+TEST_F(RepeatedPtrFieldIteratorTest, MutableReverseIteration) {
+ RepeatedPtrField<string>::reverse_iterator iter = proto_array_.rbegin();
+ EXPECT_EQ("baz", *iter);
+ ++iter;
+ EXPECT_EQ("bar", *(iter++));
+ EXPECT_EQ("foo", *iter);
+ ++iter;
+ EXPECT_TRUE(proto_array_.rend() == iter);
+ EXPECT_EQ("foo", *(--proto_array_.rend()));
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, ConstReverseIteration) {
+ const RepeatedPtrField<string>& const_proto_array = proto_array_;
+ RepeatedPtrField<string>::const_reverse_iterator iter
+ = const_proto_array.rbegin();
+ EXPECT_EQ("baz", *iter);
+ ++iter;
+ EXPECT_EQ("bar", *(iter++));
+ EXPECT_EQ("foo", *iter);
+ ++iter;
+ EXPECT_TRUE(const_proto_array.rend() == iter);
+ EXPECT_EQ("foo", *(--const_proto_array.rend()));
+}
+
TEST_F(RepeatedPtrFieldIteratorTest, RandomAccess) {
RepeatedPtrField<string>::iterator iter = proto_array_.begin();
RepeatedPtrField<string>::iterator iter2 = iter;
@@ -705,14 +1084,23 @@ class RepeatedPtrFieldPtrsIteratorTest : public testing::Test {
proto_array_.Add()->assign("foo");
proto_array_.Add()->assign("bar");
proto_array_.Add()->assign("baz");
+ const_proto_array_ = &proto_array_;
}
RepeatedPtrField<string> proto_array_;
+ const RepeatedPtrField<string>* const_proto_array_;
};
TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertiblePtr) {
RepeatedPtrField<string>::pointer_iterator iter =
proto_array_.pointer_begin();
+ static_cast<void>(iter);
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertibleConstPtr) {
+ RepeatedPtrField<string>::const_pointer_iterator iter =
+ const_proto_array_->pointer_begin();
+ static_cast<void>(iter);
}
TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutablePtrIteration) {
@@ -727,6 +1115,18 @@ TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutablePtrIteration) {
EXPECT_EQ("baz", **(--proto_array_.pointer_end()));
}
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutableConstPtrIteration) {
+ RepeatedPtrField<string>::const_pointer_iterator iter =
+ const_proto_array_->pointer_begin();
+ EXPECT_EQ("foo", **iter);
+ ++iter;
+ EXPECT_EQ("bar", **(iter++));
+ EXPECT_EQ("baz", **iter);
+ ++iter;
+ EXPECT_TRUE(const_proto_array_->pointer_end() == iter);
+ EXPECT_EQ("baz", **(--const_proto_array_->pointer_end()));
+}
+
TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomPtrAccess) {
RepeatedPtrField<string>::pointer_iterator iter =
proto_array_.pointer_begin();
@@ -740,6 +1140,19 @@ TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomPtrAccess) {
EXPECT_EQ(3, proto_array_.end() - proto_array_.begin());
}
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomConstPtrAccess) {
+ RepeatedPtrField<string>::const_pointer_iterator iter =
+ const_proto_array_->pointer_begin();
+ RepeatedPtrField<string>::const_pointer_iterator iter2 = iter;
+ ++iter2;
+ ++iter2;
+ EXPECT_TRUE(iter + 2 == iter2);
+ EXPECT_TRUE(iter == iter2 - 2);
+ EXPECT_EQ("baz", *iter[2]);
+ EXPECT_EQ("baz", **(iter + 2));
+ EXPECT_EQ(3, const_proto_array_->end() - const_proto_array_->begin());
+}
+
TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparablePtr) {
RepeatedPtrField<string>::pointer_iterator iter =
proto_array_.pointer_begin();
@@ -754,6 +1167,20 @@ TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparablePtr) {
EXPECT_TRUE(iter >= iter);
}
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparableConstPtr) {
+ RepeatedPtrField<string>::const_pointer_iterator iter =
+ const_proto_array_->pointer_begin();
+ RepeatedPtrField<string>::const_pointer_iterator iter2 = iter + 1;
+ EXPECT_TRUE(iter == iter);
+ EXPECT_TRUE(iter != iter2);
+ EXPECT_TRUE(iter < iter2);
+ EXPECT_TRUE(iter <= iter2);
+ EXPECT_TRUE(iter <= iter);
+ EXPECT_TRUE(iter2 > iter);
+ EXPECT_TRUE(iter2 >= iter);
+ EXPECT_TRUE(iter >= iter);
+}
+
// Uninitialized iterator does not point to any of the RepeatedPtrOverPtrs.
// Dereferencing an uninitialized iterator crashes the process.
TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedPtrIterator) {
@@ -765,6 +1192,14 @@ TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedPtrIterator) {
EXPECT_TRUE(iter != proto_array_.pointer_end());
}
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedConstPtrIterator) {
+ RepeatedPtrField<string>::const_pointer_iterator iter;
+ EXPECT_TRUE(iter != const_proto_array_->pointer_begin());
+ EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 1);
+ EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 2);
+ EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 3);
+ EXPECT_TRUE(iter != const_proto_array_->pointer_end());
+}
// This comparison functor is required by the tests for RepeatedPtrOverPtrs.
// They operate on strings and need to compare strings as strings in
@@ -774,9 +1209,7 @@ struct StringLessThan {
bool operator()(const string* z, const string& y) {
return *z < y;
}
- bool operator()(const string* z, const string* y) {
- return *z < *y;
- }
+ bool operator()(const string* z, const string* y) const { return *z < *y; }
};
TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrSTLAlgorithms_lower_bound) {
@@ -789,17 +1222,29 @@ TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrSTLAlgorithms_lower_bound) {
proto_array_.Add()->assign("x");
proto_array_.Add()->assign("y");
- RepeatedPtrField<string>::pointer_iterator iter =
- proto_array_.pointer_begin();
- string v = "f";
- RepeatedPtrField<string>::pointer_iterator it =
- lower_bound(proto_array_.pointer_begin(), proto_array_.pointer_end(),
- &v, StringLessThan());
+ {
+ string v = "f";
+ RepeatedPtrField<string>::pointer_iterator it =
+ lower_bound(proto_array_.pointer_begin(), proto_array_.pointer_end(),
+ &v, StringLessThan());
+
+ GOOGLE_CHECK(*it != NULL);
+
+ EXPECT_EQ(**it, "n");
+ EXPECT_TRUE(it == proto_array_.pointer_begin() + 3);
+ }
+ {
+ string v = "f";
+ RepeatedPtrField<string>::const_pointer_iterator it =
+ lower_bound(const_proto_array_->pointer_begin(),
+ const_proto_array_->pointer_end(),
+ &v, StringLessThan());
- GOOGLE_CHECK(*it != NULL);
+ GOOGLE_CHECK(*it != NULL);
- EXPECT_EQ(**it, "n");
- EXPECT_TRUE(it == proto_array_.pointer_begin() + 3);
+ EXPECT_EQ(**it, "n");
+ EXPECT_TRUE(it == const_proto_array_->pointer_begin() + 3);
+ }
}
TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrMutation) {
@@ -925,13 +1370,24 @@ TEST_F(RepeatedFieldInsertionIteratorsTest, Halves) {
TEST_F(RepeatedFieldInsertionIteratorsTest, Words) {
ASSERT_EQ(words.size(), protobuffer.repeated_string_size());
- EXPECT_EQ(words.at(0), protobuffer.repeated_string(0));
- EXPECT_EQ(words.at(1), protobuffer.repeated_string(1));
- EXPECT_EQ(words.at(2), protobuffer.repeated_string(2));
- EXPECT_EQ(words.at(3), protobuffer.repeated_string(3));
- EXPECT_EQ(words.at(4), protobuffer.repeated_string(4));
- EXPECT_EQ(words.at(5), protobuffer.repeated_string(5));
- EXPECT_EQ(words.at(6), protobuffer.repeated_string(6));
+ for (int i = 0; i < words.size(); ++i)
+ EXPECT_EQ(words.at(i), protobuffer.repeated_string(i));
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Words2) {
+ words.clear();
+ words.push_back("sing");
+ words.push_back("a");
+ words.push_back("song");
+ words.push_back("of");
+ words.push_back("six");
+ words.push_back("pence");
+ protobuffer.mutable_repeated_string()->Clear();
+ std::copy(words.begin(), words.end(), RepeatedPtrFieldBackInserter(
+ protobuffer.mutable_repeated_string()));
+ ASSERT_EQ(words.size(), protobuffer.repeated_string_size());
+ for (int i = 0; i < words.size(); ++i)
+ EXPECT_EQ(words.at(i), protobuffer.repeated_string(i));
}
TEST_F(RepeatedFieldInsertionIteratorsTest, Nesteds) {
diff --git a/src/google/protobuf/service.cc b/src/google/protobuf/service.cc
index caf968c..ffa919d 100644
--- a/src/google/protobuf/service.cc
+++ b/src/google/protobuf/service.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/service.h b/src/google/protobuf/service.h
index a6a7d16..cc0b45d 100644
--- a/src/google/protobuf/service.h
+++ b/src/google/protobuf/service.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/stubs/atomicops.h b/src/google/protobuf/stubs/atomicops.h
new file mode 100644
index 0000000..b1336e3
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops.h
@@ -0,0 +1,227 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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.
+
+// The routines exported by this module are subtle. If you use them, even if
+// you get the code right, it will depend on careful reasoning about atomicity
+// and memory ordering; it will be less readable, and harder to maintain. If
+// you plan to use these routines, you should have a good reason, such as solid
+// evidence that performance would otherwise suffer, or there being no
+// alternative. You should assume only properties explicitly guaranteed by the
+// specifications in this file. You are almost certainly _not_ writing code
+// just for the x86; if you assume x86 semantics, x86 hardware bugs and
+// implementations on other archtectures will cause your code to break. If you
+// do not know what you are doing, avoid these routines, and use a Mutex.
+//
+// It is incorrect to make direct assignments to/from an atomic variable.
+// You should use one of the Load or Store routines. The NoBarrier
+// versions are provided when no barriers are needed:
+// NoBarrier_Store()
+// NoBarrier_Load()
+// Although there are currently no compiler enforcement, you are encouraged
+// to use these.
+
+// This header and the implementations for each platform (located in
+// atomicops_internals_*) must be kept in sync with the upstream code (V8).
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_H_
+
+// Don't include this file for people not concerned about thread safety.
+#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
+#include <google/protobuf/stubs/platform_macros.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+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)
+// 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
+typedef int64 Atomic64;
+#else
+typedef intptr_t Atomic64;
+#endif
+#endif
+
+// Use AtomicWord for a machine-sized pointer. It will use the Atomic32 or
+// Atomic64 routines below, depending on your architecture.
+typedef intptr_t AtomicWord;
+
+// Atomically execute:
+// result = *ptr;
+// if (*ptr == old_value)
+// *ptr = new_value;
+// return result;
+//
+// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
+// Always return the old value of "*ptr"
+//
+// This routine implies no memory barriers.
+Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value);
+
+// Atomically store new_value into *ptr, returning the previous value held in
+// *ptr. This routine implies no memory barriers.
+Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
+
+// Atomically increment *ptr by "increment". Returns the new value of
+// *ptr with the increment applied. This routine implies no memory barriers.
+Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment);
+
+Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment);
+
+// These following lower-level operations are typically useful only to people
+// implementing higher-level synchronization operations like spinlocks,
+// mutexes, and condition-variables. They combine CompareAndSwap(), a load, or
+// a store with appropriate memory-ordering instructions. "Acquire" operations
+// ensure that no later memory access can be reordered ahead of the operation.
+// "Release" operations ensure that no previous memory access can be reordered
+// after the operation. "Barrier" operations have both "Acquire" and "Release"
+// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory
+// access.
+Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value);
+Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value);
+
+#if defined(__MINGW32__) && defined(MemoryBarrier)
+#undef MemoryBarrier
+#endif
+void MemoryBarrier();
+void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value);
+void Acquire_Store(volatile Atomic32* ptr, Atomic32 value);
+void Release_Store(volatile Atomic32* ptr, Atomic32 value);
+
+Atomic32 NoBarrier_Load(volatile const Atomic32* ptr);
+Atomic32 Acquire_Load(volatile const Atomic32* ptr);
+Atomic32 Release_Load(volatile const Atomic32* ptr);
+
+// 64-bit atomic operations (only available on 64-bit processors).
+#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
+Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value);
+Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
+Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
+Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
+
+Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value);
+Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value);
+void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value);
+void Acquire_Store(volatile Atomic64* ptr, Atomic64 value);
+void Release_Store(volatile Atomic64* ptr, Atomic64 value);
+Atomic64 NoBarrier_Load(volatile const Atomic64* ptr);
+Atomic64 Acquire_Load(volatile const Atomic64* ptr);
+Atomic64 Release_Load(volatile const Atomic64* ptr);
+#endif // GOOGLE_PROTOBUF_ARCH_64_BIT
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+// Include our platform specific implementation.
+#define GOOGLE_PROTOBUF_ATOMICOPS_ERROR \
+#error "Atomic operations are not supported on your platform"
+
+// ThreadSanitizer, http://clang.llvm.org/docs/ThreadSanitizer.html.
+#if defined(THREAD_SANITIZER)
+#include <google/protobuf/stubs/atomicops_internals_tsan.h>
+// MSVC.
+#elif defined(_MSC_VER)
+#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
+#include <google/protobuf/stubs/atomicops_internals_x86_msvc.h>
+#else
+GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+#endif
+
+// Solaris
+#elif defined(GOOGLE_PROTOBUF_OS_SOLARIS)
+#include <google/protobuf/stubs/atomicops_internals_solaris.h>
+
+// Apple.
+#elif defined(GOOGLE_PROTOBUF_OS_APPLE)
+#include <google/protobuf/stubs/atomicops_internals_macosx.h>
+
+// GCC.
+#elif defined(__GNUC__)
+#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
+#include <google/protobuf/stubs/atomicops_internals_x86_gcc.h>
+#elif defined(GOOGLE_PROTOBUF_ARCH_ARM) && defined(__linux__)
+#include <google/protobuf/stubs/atomicops_internals_arm_gcc.h>
+#elif defined(GOOGLE_PROTOBUF_ARCH_AARCH64)
+#include <google/protobuf/stubs/atomicops_internals_arm64_gcc.h>
+#elif defined(GOOGLE_PROTOBUF_ARCH_ARM_QNX)
+#include <google/protobuf/stubs/atomicops_internals_arm_qnx.h>
+#elif defined(GOOGLE_PROTOBUF_ARCH_MIPS) || defined(GOOGLE_PROTOBUF_ARCH_MIPS64)
+#include <google/protobuf/stubs/atomicops_internals_mips_gcc.h>
+#elif defined(__native_client__)
+#include <google/protobuf/stubs/atomicops_internals_pnacl.h>
+#elif (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
+#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
+#elif defined(__clang__)
+#if __has_extension(c_atomic)
+#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
+#else
+GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+#endif
+#else
+GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+#endif
+
+// Unknown.
+#else
+GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+#endif
+
+// On some platforms we need additional declarations to make AtomicWord
+// compatible with our other Atomic* types.
+#if defined(GOOGLE_PROTOBUF_OS_APPLE)
+#include <google/protobuf/stubs/atomicops_internals_atomicword_compat.h>
+#endif
+
+#undef GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+
+#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h b/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h
new file mode 100644
index 0000000..0a2d2b8
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h
@@ -0,0 +1,325 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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 is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline void MemoryBarrier() {
+ __asm__ __volatile__ ("dmb ish" ::: "memory"); // NOLINT
+}
+
+// NoBarrier versions of the operation include "memory" in the clobber list.
+// This is not required for direct usage of the NoBarrier versions of the
+// operations. However this is required for correctness when they are used as
+// part of the Acquire or Release versions, to ensure that nothing from outside
+// the call is reordered between the operation and the memory barrier. This does
+// not change the code generated, so has no or minimal impact on the
+// NoBarrier operations.
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev;
+ int32_t temp;
+
+ __asm__ __volatile__ ( // NOLINT
+ "0: \n\t"
+ "ldxr %w[prev], %[ptr] \n\t" // Load the previous value.
+ "cmp %w[prev], %w[old_value] \n\t"
+ "bne 1f \n\t"
+ "stxr %w[temp], %w[new_value], %[ptr] \n\t" // Try to store the new value.
+ "cbnz %w[temp], 0b \n\t" // Retry if it did not work.
+ "1: \n\t"
+ : [prev]"=&r" (prev),
+ [temp]"=&r" (temp),
+ [ptr]"+Q" (*ptr)
+ : [old_value]"IJr" (old_value),
+ [new_value]"r" (new_value)
+ : "cc", "memory"
+ ); // NOLINT
+
+ return prev;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ Atomic32 result;
+ int32_t temp;
+
+ __asm__ __volatile__ ( // NOLINT
+ "0: \n\t"
+ "ldxr %w[result], %[ptr] \n\t" // Load the previous value.
+ "stxr %w[temp], %w[new_value], %[ptr] \n\t" // Try to store the new value.
+ "cbnz %w[temp], 0b \n\t" // Retry if it did not work.
+ : [result]"=&r" (result),
+ [temp]"=&r" (temp),
+ [ptr]"+Q" (*ptr)
+ : [new_value]"r" (new_value)
+ : "memory"
+ ); // NOLINT
+
+ return result;
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ Atomic32 result;
+ int32_t temp;
+
+ __asm__ __volatile__ ( // NOLINT
+ "0: \n\t"
+ "ldxr %w[result], %[ptr] \n\t" // Load the previous value.
+ "add %w[result], %w[result], %w[increment]\n\t"
+ "stxr %w[temp], %w[result], %[ptr] \n\t" // Try to store the result.
+ "cbnz %w[temp], 0b \n\t" // Retry on failure.
+ : [result]"=&r" (result),
+ [temp]"=&r" (temp),
+ [ptr]"+Q" (*ptr)
+ : [increment]"IJr" (increment)
+ : "memory"
+ ); // NOLINT
+
+ return result;
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ MemoryBarrier();
+ Atomic32 result = NoBarrier_AtomicIncrement(ptr, increment);
+ MemoryBarrier();
+
+ return result;
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ MemoryBarrier();
+
+ return prev;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ MemoryBarrier();
+ Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+
+ return prev;
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ __asm__ __volatile__ ( // NOLINT
+ "stlr %w[value], %[ptr] \n\t"
+ : [ptr]"=Q" (*ptr)
+ : [value]"r" (value)
+ : "memory"
+ ); // NOLINT
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+ return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ Atomic32 value;
+
+ __asm__ __volatile__ ( // NOLINT
+ "ldar %w[value], %[ptr] \n\t"
+ : [value]"=r" (value)
+ : [ptr]"Q" (*ptr)
+ : "memory"
+ ); // NOLINT
+
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+// 64-bit versions of the operations.
+// See the 32-bit versions for comments.
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 prev;
+ int32_t temp;
+
+ __asm__ __volatile__ ( // NOLINT
+ "0: \n\t"
+ "ldxr %[prev], %[ptr] \n\t"
+ "cmp %[prev], %[old_value] \n\t"
+ "bne 1f \n\t"
+ "stxr %w[temp], %[new_value], %[ptr] \n\t"
+ "cbnz %w[temp], 0b \n\t"
+ "1: \n\t"
+ : [prev]"=&r" (prev),
+ [temp]"=&r" (temp),
+ [ptr]"+Q" (*ptr)
+ : [old_value]"IJr" (old_value),
+ [new_value]"r" (new_value)
+ : "cc", "memory"
+ ); // NOLINT
+
+ return prev;
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value) {
+ Atomic64 result;
+ int32_t temp;
+
+ __asm__ __volatile__ ( // NOLINT
+ "0: \n\t"
+ "ldxr %[result], %[ptr] \n\t"
+ "stxr %w[temp], %[new_value], %[ptr] \n\t"
+ "cbnz %w[temp], 0b \n\t"
+ : [result]"=&r" (result),
+ [temp]"=&r" (temp),
+ [ptr]"+Q" (*ptr)
+ : [new_value]"r" (new_value)
+ : "memory"
+ ); // NOLINT
+
+ return result;
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ Atomic64 result;
+ int32_t temp;
+
+ __asm__ __volatile__ ( // NOLINT
+ "0: \n\t"
+ "ldxr %[result], %[ptr] \n\t"
+ "add %[result], %[result], %[increment] \n\t"
+ "stxr %w[temp], %[result], %[ptr] \n\t"
+ "cbnz %w[temp], 0b \n\t"
+ : [result]"=&r" (result),
+ [temp]"=&r" (temp),
+ [ptr]"+Q" (*ptr)
+ : [increment]"IJr" (increment)
+ : "memory"
+ ); // NOLINT
+
+ return result;
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ MemoryBarrier();
+ Atomic64 result = NoBarrier_AtomicIncrement(ptr, increment);
+ MemoryBarrier();
+
+ return result;
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ MemoryBarrier();
+
+ return prev;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ MemoryBarrier();
+ Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+
+ return prev;
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+ __asm__ __volatile__ ( // NOLINT
+ "stlr %x[value], %[ptr] \n\t"
+ : [ptr]"=Q" (*ptr)
+ : [value]"r" (value)
+ : "memory"
+ ); // NOLINT
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+ return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+ Atomic64 value;
+
+ __asm__ __volatile__ ( // NOLINT
+ "ldar %x[value], %[ptr] \n\t"
+ : [value]"=r" (value)
+ : [ptr]"Q" (*ptr)
+ : "memory"
+ ); // NOLINT
+
+ return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h b/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h
new file mode 100644
index 0000000..90e727b
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h
@@ -0,0 +1,151 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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 is an internal atomic implementation, use atomicops.h instead.
+//
+// LinuxKernelCmpxchg and Barrier_AtomicIncrement are from Google Gears.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// 0xffff0fc0 is the hard coded address of a function provided by
+// the kernel which implements an atomic compare-exchange. On older
+// ARM architecture revisions (pre-v6) this may be implemented using
+// a syscall. This address is stable, and in active use (hard coded)
+// by at least glibc-2.7 and the Android C library.
+typedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value,
+ Atomic32 new_value,
+ volatile Atomic32* ptr);
+LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg __attribute__((weak)) =
+ (LinuxKernelCmpxchgFunc) 0xffff0fc0;
+
+typedef void (*LinuxKernelMemoryBarrierFunc)(void);
+LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) =
+ (LinuxKernelMemoryBarrierFunc) 0xffff0fa0;
+
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev_value = *ptr;
+ do {
+ if (!pLinuxKernelCmpxchg(old_value, new_value,
+ const_cast<Atomic32*>(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ Atomic32 old_value;
+ do {
+ old_value = *ptr;
+ } while (pLinuxKernelCmpxchg(old_value, new_value,
+ const_cast<Atomic32*>(ptr)));
+ return old_value;
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return Barrier_AtomicIncrement(ptr, increment);
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ for (;;) {
+ // Atomic exchange the old value with an incremented one.
+ Atomic32 old_value = *ptr;
+ Atomic32 new_value = old_value + increment;
+ if (pLinuxKernelCmpxchg(old_value, new_value,
+ const_cast<Atomic32*>(ptr)) == 0) {
+ // The exchange took place as expected.
+ return new_value;
+ }
+ // Otherwise, *ptr changed mid-loop and we need to retry.
+ }
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+inline void MemoryBarrier() {
+ pLinuxKernelMemoryBarrier();
+}
+
+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
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h b/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h
new file mode 100644
index 0000000..17dfaa5
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h
@@ -0,0 +1,146 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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 is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_
+
+// For _smp_cmpxchg()
+#include <pthread.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 QNXCmpxchg(Atomic32 old_value,
+ Atomic32 new_value,
+ volatile Atomic32* ptr) {
+ return static_cast<Atomic32>(
+ _smp_cmpxchg((volatile unsigned *)ptr,
+ (unsigned)old_value,
+ (unsigned)new_value));
+}
+
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev_value = *ptr;
+ do {
+ if (!QNXCmpxchg(old_value, new_value,
+ const_cast<Atomic32*>(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ Atomic32 old_value;
+ do {
+ old_value = *ptr;
+ } while (QNXCmpxchg(old_value, new_value,
+ const_cast<Atomic32*>(ptr)));
+ return old_value;
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return Barrier_AtomicIncrement(ptr, increment);
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ for (;;) {
+ // Atomic exchange the old value with an incremented one.
+ Atomic32 old_value = *ptr;
+ Atomic32 new_value = old_value + increment;
+ if (QNXCmpxchg(old_value, new_value,
+ const_cast<Atomic32*>(ptr)) == 0) {
+ // The exchange took place as expected.
+ return new_value;
+ }
+ // Otherwise, *ptr changed mid-loop and we need to retry.
+ }
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+inline void MemoryBarrier() {
+ __sync_synchronize();
+}
+
+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
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h b/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h
new file mode 100644
index 0000000..eb198ff
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h
@@ -0,0 +1,122 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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 is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
+
+// AtomicWord is a synonym for intptr_t, and Atomic32 is a synonym for int32,
+// which in turn means int. On some LP32 platforms, intptr_t is an int, but
+// on others, it's a long. When AtomicWord and Atomic32 are based on different
+// fundamental types, their pointers are incompatible.
+//
+// This file defines function overloads to allow both AtomicWord and Atomic32
+// data to be used with this interface.
+//
+// On LP64 platforms, AtomicWord and Atomic64 are both always long,
+// so this problem doesn't occur.
+
+#if !defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ return NoBarrier_CompareAndSwap(
+ reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
+}
+
+inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr,
+ AtomicWord new_value) {
+ return NoBarrier_AtomicExchange(
+ reinterpret_cast<volatile Atomic32*>(ptr), new_value);
+}
+
+inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr,
+ AtomicWord increment) {
+ return NoBarrier_AtomicIncrement(
+ reinterpret_cast<volatile Atomic32*>(ptr), increment);
+}
+
+inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr,
+ AtomicWord increment) {
+ return Barrier_AtomicIncrement(
+ reinterpret_cast<volatile Atomic32*>(ptr), increment);
+}
+
+inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ return Acquire_CompareAndSwap(
+ reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
+}
+
+inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ return Release_CompareAndSwap(
+ reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) {
+ NoBarrier_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
+}
+
+inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
+ return Acquire_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
+}
+
+inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
+ return Release_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
+}
+
+inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) {
+ return NoBarrier_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
+}
+
+inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
+ return Acquire_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
+}
+
+inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
+ return Release_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // !defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h b/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
new file mode 100644
index 0000000..dd7abf6
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
@@ -0,0 +1,137 @@
+// Copyright 2013 Red Hat Inc. All rights reserved.
+//
+// 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 Red Hat 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 is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+ __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+ return old_value;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ return __atomic_exchange_n(ptr, new_value, __ATOMIC_RELAXED);
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return __atomic_add_fetch(ptr, increment, __ATOMIC_RELAXED);
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return __atomic_add_fetch(ptr, increment, __ATOMIC_SEQ_CST);
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ __atomic_compare_exchange(ptr, &old_value, &new_value, true,
+ __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+ return old_value;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+ __ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
+ return old_value;
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ __atomic_store_n(ptr, value, __ATOMIC_RELAXED);
+}
+
+inline void MemoryBarrier() {
+ __sync_synchronize();
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ __atomic_store_n(ptr, value, __ATOMIC_SEQ_CST);
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ __atomic_store_n(ptr, value, __ATOMIC_RELEASE);
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+ return __atomic_load_n(ptr, __ATOMIC_RELAXED);
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+ return __atomic_load_n(ptr, __ATOMIC_SEQ_CST);
+}
+
+#ifdef __LP64__
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+ __atomic_store_n(ptr, value, __ATOMIC_RELEASE);
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+ return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+ __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+ return old_value;
+}
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+ __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+ return old_value;
+}
+
+#endif // defined(__LP64__)
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_macosx.h b/src/google/protobuf/stubs/atomicops_internals_macosx.h
new file mode 100644
index 0000000..7963324
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_macosx.h
@@ -0,0 +1,225 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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 is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
+
+#include <libkern/OSAtomic.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev_value;
+ do {
+ if (OSAtomicCompareAndSwap32(old_value, new_value,
+ const_cast<Atomic32*>(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ Atomic32 old_value;
+ do {
+ old_value = *ptr;
+ } while (!OSAtomicCompareAndSwap32(old_value, new_value,
+ const_cast<Atomic32*>(ptr)));
+ return old_value;
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return OSAtomicAdd32(increment, const_cast<Atomic32*>(ptr));
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr));
+}
+
+inline void MemoryBarrier() {
+ OSMemoryBarrier();
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev_value;
+ do {
+ if (OSAtomicCompareAndSwap32Barrier(old_value, new_value,
+ const_cast<Atomic32*>(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return Acquire_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+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;
+}
+
+#ifdef __LP64__
+
+// 64-bit implementation on 64-bit platform
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 prev_value;
+ do {
+ if (OSAtomicCompareAndSwap64(old_value, new_value,
+ reinterpret_cast<volatile int64_t*>(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value) {
+ Atomic64 old_value;
+ do {
+ old_value = *ptr;
+ } while (!OSAtomicCompareAndSwap64(old_value, new_value,
+ reinterpret_cast<volatile int64_t*>(ptr)));
+ return old_value;
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ return OSAtomicAdd64(increment, reinterpret_cast<volatile int64_t*>(ptr));
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ return OSAtomicAdd64Barrier(increment,
+ reinterpret_cast<volatile int64_t*>(ptr));
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 prev_value;
+ do {
+ if (OSAtomicCompareAndSwap64Barrier(
+ old_value, new_value, reinterpret_cast<volatile int64_t*>(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ // The lib kern interface does not distinguish between
+ // Acquire and Release memory barriers; they are equivalent.
+ return Acquire_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+ return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+ Atomic64 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+#endif // defined(__LP64__)
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h b/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h
new file mode 100644
index 0000000..e3cd14c
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h
@@ -0,0 +1,313 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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 is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
+
+#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Atomically execute:
+// result = *ptr;
+// if (*ptr == old_value)
+// *ptr = new_value;
+// return result;
+//
+// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
+// Always return the old value of "*ptr"
+//
+// This routine implies no memory barriers.
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev, tmp;
+ __asm__ __volatile__(".set push\n"
+ ".set noreorder\n"
+ "1:\n"
+ "ll %0, %5\n" // prev = *ptr
+ "bne %0, %3, 2f\n" // if (prev != old_value) goto 2
+ "move %2, %4\n" // tmp = new_value
+ "sc %2, %1\n" // *ptr = tmp (with atomic check)
+ "beqz %2, 1b\n" // start again on atomic error
+ "nop\n" // delay slot nop
+ "2:\n"
+ ".set pop\n"
+ : "=&r" (prev), "=m" (*ptr), "=&r" (tmp)
+ : "Ir" (old_value), "r" (new_value), "m" (*ptr)
+ : "memory");
+ return prev;
+}
+
+// Atomically store new_value into *ptr, returning the previous value held in
+// *ptr. This routine implies no memory barriers.
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ Atomic32 temp, old;
+ __asm__ __volatile__(".set push\n"
+ ".set noreorder\n"
+ "1:\n"
+ "ll %1, %4\n" // old = *ptr
+ "move %0, %3\n" // temp = new_value
+ "sc %0, %2\n" // *ptr = temp (with atomic check)
+ "beqz %0, 1b\n" // start again on atomic error
+ "nop\n" // delay slot nop
+ ".set pop\n"
+ : "=&r" (temp), "=&r" (old), "=m" (*ptr)
+ : "r" (new_value), "m" (*ptr)
+ : "memory");
+
+ return old;
+}
+
+// Atomically increment *ptr by "increment". Returns the new value of
+// *ptr with the increment applied. This routine implies no memory barriers.
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ Atomic32 temp, temp2;
+
+ __asm__ __volatile__(".set push\n"
+ ".set noreorder\n"
+ "1:\n"
+ "ll %0, %4\n" // temp = *ptr
+ "addu %1, %0, %3\n" // temp2 = temp + increment
+ "sc %1, %2\n" // *ptr = temp2 (with atomic check)
+ "beqz %1, 1b\n" // start again on atomic error
+ "addu %1, %0, %3\n" // temp2 = temp + increment
+ ".set pop\n"
+ : "=&r" (temp), "=&r" (temp2), "=m" (*ptr)
+ : "Ir" (increment), "m" (*ptr)
+ : "memory");
+ // temp2 now holds the final value.
+ return temp2;
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ ATOMICOPS_COMPILER_BARRIER();
+ Atomic32 res = NoBarrier_AtomicIncrement(ptr, increment);
+ ATOMICOPS_COMPILER_BARRIER();
+ return res;
+}
+
+// "Acquire" operations
+// ensure that no later memory access can be reordered ahead of the operation.
+// "Release" operations ensure that no previous memory access can be reordered
+// after the operation. "Barrier" operations have both "Acquire" and "Release"
+// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory
+// access.
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ ATOMICOPS_COMPILER_BARRIER();
+ Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ ATOMICOPS_COMPILER_BARRIER();
+ return res;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ ATOMICOPS_COMPILER_BARRIER();
+ Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ ATOMICOPS_COMPILER_BARRIER();
+ 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;
+}
+
+#if defined(__LP64__)
+// 64-bit versions of the atomic ops.
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 prev, tmp;
+ __asm__ __volatile__(".set push\n"
+ ".set noreorder\n"
+ "1:\n"
+ "lld %0, %5\n" // prev = *ptr
+ "bne %0, %3, 2f\n" // if (prev != old_value) goto 2
+ "move %2, %4\n" // tmp = new_value
+ "scd %2, %1\n" // *ptr = tmp (with atomic check)
+ "beqz %2, 1b\n" // start again on atomic error
+ "nop\n" // delay slot nop
+ "2:\n"
+ ".set pop\n"
+ : "=&r" (prev), "=m" (*ptr), "=&r" (tmp)
+ : "Ir" (old_value), "r" (new_value), "m" (*ptr)
+ : "memory");
+ return prev;
+}
+
+// Atomically store new_value into *ptr, returning the previous value held in
+// *ptr. This routine implies no memory barriers.
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value) {
+ Atomic64 temp, old;
+ __asm__ __volatile__(".set push\n"
+ ".set noreorder\n"
+ "1:\n"
+ "lld %1, %4\n" // old = *ptr
+ "move %0, %3\n" // temp = new_value
+ "scd %0, %2\n" // *ptr = temp (with atomic check)
+ "beqz %0, 1b\n" // start again on atomic error
+ "nop\n" // delay slot nop
+ ".set pop\n"
+ : "=&r" (temp), "=&r" (old), "=m" (*ptr)
+ : "r" (new_value), "m" (*ptr)
+ : "memory");
+
+ return old;
+}
+
+// Atomically increment *ptr by "increment". Returns the new value of
+// *ptr with the increment applied. This routine implies no memory barriers.
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ Atomic64 temp, temp2;
+
+ __asm__ __volatile__(".set push\n"
+ ".set noreorder\n"
+ "1:\n"
+ "lld %0, %4\n" // temp = *ptr
+ "daddu %1, %0, %3\n" // temp2 = temp + increment
+ "scd %1, %2\n" // *ptr = temp2 (with atomic check)
+ "beqz %1, 1b\n" // start again on atomic error
+ "daddu %1, %0, %3\n" // temp2 = temp + increment
+ ".set pop\n"
+ : "=&r" (temp), "=&r" (temp2), "=m" (*ptr)
+ : "Ir" (increment), "m" (*ptr)
+ : "memory");
+ // temp2 now holds the final value.
+ return temp2;
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ MemoryBarrier();
+ Atomic64 res = NoBarrier_AtomicIncrement(ptr, increment);
+ MemoryBarrier();
+ return res;
+}
+
+// "Acquire" operations
+// ensure that no later memory access can be reordered ahead of the operation.
+// "Release" operations ensure that no previous memory access can be reordered
+// after the operation. "Barrier" operations have both "Acquire" and "Release"
+// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory
+// access.
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ MemoryBarrier();
+ return res;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ MemoryBarrier();
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+ return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+ Atomic64 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+#endif
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#undef ATOMICOPS_COMPILER_BARRIER
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_pnacl.h b/src/google/protobuf/stubs/atomicops_internals_pnacl.h
new file mode 100644
index 0000000..b10ac02
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_pnacl.h
@@ -0,0 +1,73 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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 is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
+
+inline void MemoryBarrier() {
+ __sync_synchronize();
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ MemoryBarrier();
+ return ret;
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ Atomic32 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_solaris.h b/src/google/protobuf/stubs/atomicops_internals_solaris.h
new file mode 100644
index 0000000..d8057ec
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_solaris.h
@@ -0,0 +1,188 @@
+// 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.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
+
+#include <atomic.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return (Atomic32)atomic_cas_32((volatile uint32_t*)ptr, (uint32_t)old_value, (uint32_t)new_value);
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ return (Atomic32)atomic_swap_32((volatile uint32_t*)ptr, (uint32_t)new_value);
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return (Atomic32)atomic_add_32_nv((volatile uint32_t*)ptr, (uint32_t)increment);
+}
+
+inline void MemoryBarrier(void) {
+ membar_producer();
+ membar_consumer();
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ MemoryBarrier();
+ Atomic32 ret = NoBarrier_AtomicIncrement(ptr, increment);
+ MemoryBarrier();
+
+ return ret;
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ MemoryBarrier();
+
+ return ret;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ MemoryBarrier();
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+ membar_producer();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ membar_consumer();
+ *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+ return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ Atomic32 val = *ptr;
+ membar_consumer();
+ return val;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+ membar_producer();
+ return *ptr;
+}
+
+#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ return atomic_cas_64((volatile uint64_t*)ptr, (uint64_t)old_value, (uint64_t)new_value);
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value) {
+ return atomic_swap_64((volatile uint64_t*)ptr, (uint64_t)new_value);
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment) {
+ return atomic_add_64_nv((volatile uint64_t*)ptr, increment);
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment) {
+ MemoryBarrier();
+ Atomic64 ret = atomic_add_64_nv((volatile uint64_t*)ptr, increment);
+ MemoryBarrier();
+ return ret;
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ MemoryBarrier();
+ return ret;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ MemoryBarrier();
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+ membar_producer();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+ membar_consumer();
+ *ptr = value;
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+ return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+ Atomic64 ret = *ptr;
+ membar_consumer();
+ return ret;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+ membar_producer();
+ return *ptr;
+}
+#endif
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
+
diff --git a/src/google/protobuf/stubs/atomicops_internals_tsan.h b/src/google/protobuf/stubs/atomicops_internals_tsan.h
new file mode 100644
index 0000000..0c90354
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_tsan.h
@@ -0,0 +1,219 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2013 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 is an internal atomic implementation for compiler-based
+// ThreadSanitizer (http://clang.llvm.org/docs/ThreadSanitizer.html).
+// Use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
+
+#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
+
+#include <sanitizer/tsan_interface_atomic.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 cmp = old_value;
+ __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
+ __tsan_memory_order_relaxed, __tsan_memory_order_relaxed);
+ return cmp;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
+ Atomic32 new_value) {
+ return __tsan_atomic32_exchange(ptr, new_value,
+ __tsan_memory_order_relaxed);
+}
+
+inline Atomic32 Acquire_AtomicExchange(volatile Atomic32 *ptr,
+ Atomic32 new_value) {
+ return __tsan_atomic32_exchange(ptr, new_value,
+ __tsan_memory_order_acquire);
+}
+
+inline Atomic32 Release_AtomicExchange(volatile Atomic32 *ptr,
+ Atomic32 new_value) {
+ return __tsan_atomic32_exchange(ptr, new_value,
+ __tsan_memory_order_release);
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr,
+ Atomic32 increment) {
+ return increment + __tsan_atomic32_fetch_add(ptr, increment,
+ __tsan_memory_order_relaxed);
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr,
+ Atomic32 increment) {
+ return increment + __tsan_atomic32_fetch_add(ptr, increment,
+ __tsan_memory_order_acq_rel);
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 cmp = old_value;
+ __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
+ __tsan_memory_order_acquire, __tsan_memory_order_acquire);
+ return cmp;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 cmp = old_value;
+ __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
+ __tsan_memory_order_release, __tsan_memory_order_relaxed);
+ return cmp;
+}
+
+inline void NoBarrier_Store(volatile Atomic32 *ptr, Atomic32 value) {
+ __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed);
+}
+
+inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {
+ __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed);
+ __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
+}
+
+inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
+ __tsan_atomic32_store(ptr, value, __tsan_memory_order_release);
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr) {
+ return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed);
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
+ return __tsan_atomic32_load(ptr, __tsan_memory_order_acquire);
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32 *ptr) {
+ __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
+ return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed);
+}
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 cmp = old_value;
+ __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
+ __tsan_memory_order_relaxed, __tsan_memory_order_relaxed);
+ return cmp;
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,
+ Atomic64 new_value) {
+ return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_relaxed);
+}
+
+inline Atomic64 Acquire_AtomicExchange(volatile Atomic64 *ptr,
+ Atomic64 new_value) {
+ return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_acquire);
+}
+
+inline Atomic64 Release_AtomicExchange(volatile Atomic64 *ptr,
+ Atomic64 new_value) {
+ return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_release);
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64 *ptr,
+ Atomic64 increment) {
+ return increment + __tsan_atomic64_fetch_add(ptr, increment,
+ __tsan_memory_order_relaxed);
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64 *ptr,
+ Atomic64 increment) {
+ return increment + __tsan_atomic64_fetch_add(ptr, increment,
+ __tsan_memory_order_acq_rel);
+}
+
+inline void NoBarrier_Store(volatile Atomic64 *ptr, Atomic64 value) {
+ __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed);
+}
+
+inline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) {
+ __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed);
+ __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
+}
+
+inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {
+ __tsan_atomic64_store(ptr, value, __tsan_memory_order_release);
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64 *ptr) {
+ return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed);
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {
+ return __tsan_atomic64_load(ptr, __tsan_memory_order_acquire);
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64 *ptr) {
+ __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
+ return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed);
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 cmp = old_value;
+ __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
+ __tsan_memory_order_acquire, __tsan_memory_order_acquire);
+ return cmp;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 cmp = old_value;
+ __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
+ __tsan_memory_order_release, __tsan_memory_order_relaxed);
+ return cmp;
+}
+
+inline void MemoryBarrier() {
+ __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#undef ATOMICOPS_COMPILER_BARRIER
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc b/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
new file mode 100644
index 0000000..53c9eae
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
@@ -0,0 +1,137 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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 module gets enough CPU information to optimize the
+// atomicops module on x86.
+
+#include <cstring>
+
+#include <google/protobuf/stubs/atomicops.h>
+
+// This file only makes sense with atomicops_internals_x86_gcc.h -- it
+// depends on structs that are defined in that file. If atomicops.h
+// doesn't sub-include that file, then we aren't needed, and shouldn't
+// try to do anything.
+#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
+
+// Inline cpuid instruction. In PIC compilations, %ebx contains the address
+// of the global offset table. To avoid breaking such executables, this code
+// must preserve that register's value across cpuid instructions.
+#if defined(__i386__)
+#define cpuid(a, b, c, d, inp) \
+ asm("mov %%ebx, %%edi\n" \
+ "cpuid\n" \
+ "xchg %%edi, %%ebx\n" \
+ : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
+#elif defined(__x86_64__)
+#define cpuid(a, b, c, d, inp) \
+ asm("mov %%rbx, %%rdi\n" \
+ "cpuid\n" \
+ "xchg %%rdi, %%rbx\n" \
+ : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
+#endif
+
+#if defined(cpuid) // initialize the struct only on x86
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Set the flags so that code will run correctly and conservatively, so even
+// if we haven't been initialized yet, we're probably single threaded, and our
+// default values should hopefully be pretty safe.
+struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = {
+ false, // bug can't exist before process spawns multiple threads
+ false, // no SSE2
+};
+
+namespace {
+
+// Initialize the AtomicOps_Internalx86CPUFeatures struct.
+void AtomicOps_Internalx86CPUFeaturesInit() {
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+
+ // Get vendor string (issue CPUID with eax = 0)
+ cpuid(eax, ebx, ecx, edx, 0);
+ char vendor[13];
+ memcpy(vendor, &ebx, 4);
+ memcpy(vendor + 4, &edx, 4);
+ memcpy(vendor + 8, &ecx, 4);
+ vendor[12] = 0;
+
+ // get feature flags in ecx/edx, and family/model in eax
+ cpuid(eax, ebx, ecx, edx, 1);
+
+ int family = (eax >> 8) & 0xf; // family and model fields
+ int model = (eax >> 4) & 0xf;
+ if (family == 0xf) { // use extended family and model fields
+ family += (eax >> 20) & 0xff;
+ model += ((eax >> 16) & 0xf) << 4;
+ }
+
+ // Opteron Rev E has a bug in which on very rare occasions a locked
+ // instruction doesn't act as a read-acquire barrier if followed by a
+ // non-locked read-modify-write instruction. Rev F has this bug in
+ // pre-release versions, but not in versions released to customers,
+ // so we test only for Rev E, which is family 15, model 32..63 inclusive.
+ if (strcmp(vendor, "AuthenticAMD") == 0 && // AMD
+ family == 15 &&
+ 32 <= model && model <= 63) {
+ AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = true;
+ } else {
+ AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = false;
+ }
+
+ // edx bit 26 is SSE2 which we use to tell use whether we can use mfence
+ AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1);
+}
+
+class AtomicOpsx86Initializer {
+ public:
+ AtomicOpsx86Initializer() {
+ AtomicOps_Internalx86CPUFeaturesInit();
+ }
+};
+
+// A global to get use initialized on startup via static initialization :/
+AtomicOpsx86Initializer g_initer;
+
+} // namespace
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // __i386__
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h b/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h
new file mode 100644
index 0000000..edccc59
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h
@@ -0,0 +1,293 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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 is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// This struct is not part of the public API of this module; clients may not
+// use it.
+// Features of this x86. Values may not be correct before main() is run,
+// but are set conservatively.
+struct AtomicOps_x86CPUFeatureStruct {
+ bool has_amd_lock_mb_bug; // Processor has AMD memory-barrier bug; do lfence
+ // after acquire compare-and-swap.
+ bool has_sse2; // Processor has SSE2.
+};
+extern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures;
+
+#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
+
+// 32-bit low-level operations on any platform.
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev;
+ __asm__ __volatile__("lock; cmpxchgl %1,%2"
+ : "=a" (prev)
+ : "q" (new_value), "m" (*ptr), "0" (old_value)
+ : "memory");
+ return prev;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ __asm__ __volatile__("xchgl %1,%0" // The lock prefix is implicit for xchg.
+ : "=r" (new_value)
+ : "m" (*ptr), "0" (new_value)
+ : "memory");
+ return new_value; // Now it's the previous value.
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ Atomic32 temp = increment;
+ __asm__ __volatile__("lock; xaddl %0,%1"
+ : "+r" (temp), "+m" (*ptr)
+ : : "memory");
+ // temp now holds the old value of *ptr
+ return temp + increment;
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ Atomic32 temp = increment;
+ __asm__ __volatile__("lock; xaddl %0,%1"
+ : "+r" (temp), "+m" (*ptr)
+ : : "memory");
+ // temp now holds the old value of *ptr
+ if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+ __asm__ __volatile__("lfence" : : : "memory");
+ }
+ return temp + increment;
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+ __asm__ __volatile__("lfence" : : : "memory");
+ }
+ return x;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+#if defined(__x86_64__)
+
+// 64-bit implementations of memory barrier can be simpler, because it
+// "mfence" is guaranteed to exist.
+inline void MemoryBarrier() {
+ __asm__ __volatile__("mfence" : : : "memory");
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+#else
+
+inline void MemoryBarrier() {
+ if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
+ __asm__ __volatile__("mfence" : : : "memory");
+ } else { // mfence is faster but not present on PIII
+ Atomic32 x = 0;
+ NoBarrier_AtomicExchange(&x, 0); // acts as a barrier on PIII
+ }
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
+ *ptr = value;
+ __asm__ __volatile__("mfence" : : : "memory");
+ } else {
+ NoBarrier_AtomicExchange(ptr, value);
+ // acts as a barrier on PIII
+ }
+}
+#endif
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ ATOMICOPS_COMPILER_BARRIER();
+ *ptr = value; // An x86 store acts as a release barrier.
+ // See comments in Atomic64 version of Release_Store(), below.
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+ return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ Atomic32 value = *ptr; // An x86 load acts as a acquire barrier.
+ // See comments in Atomic64 version of Release_Store(), below.
+ ATOMICOPS_COMPILER_BARRIER();
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+#if defined(__x86_64__)
+
+// 64-bit low-level operations on 64-bit platform.
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 prev;
+ __asm__ __volatile__("lock; cmpxchgq %1,%2"
+ : "=a" (prev)
+ : "q" (new_value), "m" (*ptr), "0" (old_value)
+ : "memory");
+ return prev;
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value) {
+ __asm__ __volatile__("xchgq %1,%0" // The lock prefix is implicit for xchg.
+ : "=r" (new_value)
+ : "m" (*ptr), "0" (new_value)
+ : "memory");
+ return new_value; // Now it's the previous value.
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ Atomic64 temp = increment;
+ __asm__ __volatile__("lock; xaddq %0,%1"
+ : "+r" (temp), "+m" (*ptr)
+ : : "memory");
+ // temp now contains the previous value of *ptr
+ return temp + increment;
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ Atomic64 temp = increment;
+ __asm__ __volatile__("lock; xaddq %0,%1"
+ : "+r" (temp), "+m" (*ptr)
+ : : "memory");
+ // temp now contains the previous value of *ptr
+ if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+ __asm__ __volatile__("lfence" : : : "memory");
+ }
+ return temp + increment;
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+ ATOMICOPS_COMPILER_BARRIER();
+
+ *ptr = value; // An x86 store acts as a release barrier
+ // for current AMD/Intel chips as of Jan 2008.
+ // See also Acquire_Load(), below.
+
+ // When new chips come out, check:
+ // IA-32 Intel Architecture Software Developer's Manual, Volume 3:
+ // System Programming Guide, Chatper 7: Multiple-processor management,
+ // Section 7.2, Memory Ordering.
+ // Last seen at:
+ // http://developer.intel.com/design/pentium4/manuals/index_new.htm
+ //
+ // x86 stores/loads fail to act as barriers for a few instructions (clflush
+ // maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are
+ // not generated by the compiler, and are rare. Users of these instructions
+ // need to know about cache behaviour in any case since all of these involve
+ // either flushing cache lines or non-temporal cache hints.
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+ return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+ Atomic64 value = *ptr; // An x86 load acts as a acquire barrier,
+ // for current AMD/Intel chips as of Jan 2008.
+ // See also Release_Store(), above.
+ ATOMICOPS_COMPILER_BARRIER();
+ return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+ __asm__ __volatile__("lfence" : : : "memory");
+ }
+ return x;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+#endif // defined(__x86_64__)
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#undef ATOMICOPS_COMPILER_BARRIER
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc b/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
new file mode 100644
index 0000000..741b164
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
@@ -0,0 +1,112 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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.
+
+// The compilation of extension_set.cc fails when windows.h is included.
+// Therefore we move the code depending on windows.h to this separate cc file.
+
+// Don't compile this file for people not concerned about thread safety.
+#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
+#include <google/protobuf/stubs/atomicops.h>
+
+#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
+
+#include <windows.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline void MemoryBarrier() {
+ // We use MemoryBarrier from WinNT.h
+ ::MemoryBarrier();
+}
+
+Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ LONG result = InterlockedCompareExchange(
+ reinterpret_cast<volatile LONG*>(ptr),
+ static_cast<LONG>(new_value),
+ static_cast<LONG>(old_value));
+ return static_cast<Atomic32>(result);
+}
+
+Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ LONG result = InterlockedExchange(
+ reinterpret_cast<volatile LONG*>(ptr),
+ static_cast<LONG>(new_value));
+ return static_cast<Atomic32>(result);
+}
+
+Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return InterlockedExchangeAdd(
+ reinterpret_cast<volatile LONG*>(ptr),
+ static_cast<LONG>(increment)) + increment;
+}
+
+#if defined(_WIN64)
+
+// 64-bit low-level operations on 64-bit platform.
+
+Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ PVOID result = InterlockedCompareExchangePointer(
+ reinterpret_cast<volatile PVOID*>(ptr),
+ reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value));
+ return reinterpret_cast<Atomic64>(result);
+}
+
+Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value) {
+ PVOID result = InterlockedExchangePointer(
+ reinterpret_cast<volatile PVOID*>(ptr),
+ reinterpret_cast<PVOID>(new_value));
+ return reinterpret_cast<Atomic64>(result);
+}
+
+Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ return InterlockedExchangeAdd64(
+ reinterpret_cast<volatile LONGLONG*>(ptr),
+ static_cast<LONGLONG>(increment)) + increment;
+}
+
+#endif // defined(_WIN64)
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
+#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
diff --git a/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h b/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h
new file mode 100644
index 0000000..e53a641
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h
@@ -0,0 +1,150 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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 is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return Barrier_AtomicIncrement(ptr, increment);
+}
+
+#if !(defined(_MSC_VER) && _MSC_VER >= 1400)
+#error "We require at least vs2005 for MemoryBarrier"
+#endif
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ NoBarrier_AtomicExchange(ptr, value);
+ // acts as a barrier in this implementation
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value; // works w/o barrier for current Intel chips as of June 2005
+ // See comments in Atomic64 version of Release_Store() below.
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+ return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ Atomic32 value = *ptr;
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+#if defined(_WIN64)
+
+// 64-bit low-level operations on 64-bit platform.
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ return Barrier_AtomicIncrement(ptr, increment);
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+ NoBarrier_AtomicExchange(ptr, value);
+ // acts as a barrier in this implementation
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value; // works w/o barrier for current Intel chips as of June 2005
+
+ // When new chips come out, check:
+ // IA-32 Intel Architecture Software Developer's Manual, Volume 3:
+ // System Programming Guide, Chatper 7: Multiple-processor management,
+ // Section 7.2, Memory Ordering.
+ // Last seen at:
+ // http://developer.intel.com/design/pentium4/manuals/index_new.htm
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+ return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+ Atomic64 value = *ptr;
+ return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+#endif // defined(_WIN64)
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc
index 1e2d68d..1e02b22 100644
--- a/src/google/protobuf/stubs/common.cc
+++ b/src/google/protobuf/stubs/common.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -110,13 +110,13 @@ void DefaultLogHandler(LogLevel level, const char* filename, int line,
// We use fprintf() instead of cerr because we want this to work at static
// initialization time.
- fprintf(stderr, "libprotobuf %s %s:%d] %s\n",
+ fprintf(stderr, "[libprotobuf %s %s:%d] %s\n",
level_names[level], filename, line, message.c_str());
fflush(stderr); // Needed on MSVC.
}
-void NullLogHandler(LogLevel level, const char* filename, int line,
- const string& message) {
+void NullLogHandler(LogLevel /* level */, const char* /* filename */,
+ int /* line */, const string& /* message */) {
// Nothing.
}
@@ -183,15 +183,19 @@ void LogMessage::Finish() {
if (level_ != LOGLEVEL_FATAL) {
InitLogSilencerCountOnce();
MutexLock lock(log_silencer_count_mutex_);
- suppress = internal::log_silencer_count_ > 0;
+ suppress = log_silencer_count_ > 0;
}
if (!suppress) {
- internal::log_handler_(level_, filename_, line_, message_);
+ log_handler_(level_, filename_, line_, message_);
}
if (level_ == LOGLEVEL_FATAL) {
+#if PROTOBUF_USE_EXCEPTIONS
+ throw FatalException(filename_, line_, message_);
+#else
abort();
+#endif
}
}
@@ -316,6 +320,24 @@ void Mutex::AssertHeld() {
#endif
// ===================================================================
+// emulates google3/util/endian/endian.h
+//
+// TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in
+// google/protobuf/io/coded_stream.h and therefore can not be used here.
+// Maybe move that macro definition here in the furture.
+uint32 ghtonl(uint32 x) {
+ union {
+ uint32 result;
+ uint8 result_array[4];
+ };
+ result_array[0] = static_cast<uint8>(x >> 24);
+ result_array[1] = static_cast<uint8>((x >> 16) & 0xFF);
+ result_array[2] = static_cast<uint8>((x >> 8) & 0xFF);
+ result_array[3] = static_cast<uint8>(x & 0xFF);
+ return result;
+}
+
+// ===================================================================
// Shutdown support.
namespace internal {
@@ -361,5 +383,13 @@ void ShutdownProtobufLibrary() {
internal::shutdown_functions_mutex = NULL;
}
+#if PROTOBUF_USE_EXCEPTIONS
+FatalException::~FatalException() throw() {}
+
+const char* FatalException::what() const throw() {
+ return message_.c_str();
+}
+#endif
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index 551ee4a..f096fa9 100644
--- a/src/google/protobuf/stubs/common.h
+++ b/src/google/protobuf/stubs/common.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -48,13 +48,43 @@
#include <stdint.h>
#endif
+#ifndef PROTOBUF_USE_EXCEPTIONS
+#if defined(_MSC_VER) && defined(_CPPUNWIND)
+ #define PROTOBUF_USE_EXCEPTIONS 1
+#elif defined(__EXCEPTIONS)
+ #define PROTOBUF_USE_EXCEPTIONS 1
+#else
+ #define PROTOBUF_USE_EXCEPTIONS 0
+#endif
+#endif
+
+#if PROTOBUF_USE_EXCEPTIONS
+#include <exception>
+#endif
+
+#if defined(_WIN32) && defined(GetMessage)
+// Allow GetMessage to be used as a valid method name in protobuf classes.
+// windows.h defines GetMessage() as a macro. Let's re-define it as an inline
+// function. The inline function should be equivalent for C++ users.
+inline BOOL GetMessage_Win32(
+ LPMSG lpMsg, HWND hWnd,
+ UINT wMsgFilterMin, UINT wMsgFilterMax) {
+ return GetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
+}
+#undef GetMessage
+inline BOOL GetMessage(
+ LPMSG lpMsg, HWND hWnd,
+ UINT wMsgFilterMin, UINT wMsgFilterMax) {
+ return GetMessage_Win32(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
+}
+#endif
+
+
namespace std {}
namespace google {
namespace protobuf {
-using namespace std; // Don't do this at home, kids.
-
#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \
TypeName(const TypeName&); \
@@ -83,24 +113,24 @@ namespace internal {
// The current version, represented as a single integer to make comparison
// easier: major * 10^6 + minor * 10^3 + micro
-#define GOOGLE_PROTOBUF_VERSION 2003000
+#define GOOGLE_PROTOBUF_VERSION 2006001
// The minimum library version which works with the current version of the
// headers.
-#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2003000
+#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2006000
// The minimum header version which works with the current version of
// the library. This constant should only be used by protoc's C++ code
// generator.
-static const int kMinHeaderVersionForLibrary = 2003000;
+static const int kMinHeaderVersionForLibrary = 2006000;
// The minimum protoc version which works with the current version of the
// headers.
-#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2003000
+#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2006000
// The minimum header version which works with the current version of
// protoc. This constant should only be used in VerifyVersion().
-static const int kMinHeaderVersionForProtoc = 2003000;
+static const int kMinHeaderVersionForProtoc = 2006000;
// Verifies that the headers and libraries are compatible. Use the macro
// below to call this.
@@ -108,7 +138,7 @@ void LIBPROTOBUF_EXPORT VerifyVersion(int headerVersion, int minLibraryVersion,
const char* filename);
// Converts a numeric version number to a string.
-string LIBPROTOBUF_EXPORT VersionString(int version);
+std::string LIBPROTOBUF_EXPORT VersionString(int version);
} // namespace internal
@@ -351,6 +381,7 @@ struct CompileAssert {
typedef ::google::protobuf::internal::CompileAssert<(bool(expr))> \
msg[bool(expr) ? 1 : -1]
+
// Implementation details of COMPILE_ASSERT:
//
// - COMPILE_ASSERT works by defining an array type that has -1
@@ -618,7 +649,7 @@ class LIBPROTOBUF_EXPORT LogMessage {
LogMessage(LogLevel level, const char* filename, int line);
~LogMessage();
- LogMessage& operator<<(const string& value);
+ LogMessage& operator<<(const std::string& value);
LogMessage& operator<<(const char* value);
LogMessage& operator<<(char value);
LogMessage& operator<<(int value);
@@ -634,7 +665,7 @@ class LIBPROTOBUF_EXPORT LogMessage {
LogLevel level_;
const char* filename_;
int line_;
- string message_;
+ std::string message_;
};
// Used to make the entire "LOG(BLAH) << etc." expression have a void return
@@ -654,12 +685,14 @@ class LIBPROTOBUF_EXPORT LogFinisher {
#undef GOOGLE_LOG_IF
#undef GOOGLE_CHECK
+#undef GOOGLE_CHECK_OK
#undef GOOGLE_CHECK_EQ
#undef GOOGLE_CHECK_NE
#undef GOOGLE_CHECK_LT
#undef GOOGLE_CHECK_LE
#undef GOOGLE_CHECK_GT
#undef GOOGLE_CHECK_GE
+#undef GOOGLE_CHECK_NOTNULL
#undef GOOGLE_DLOG
#undef GOOGLE_DCHECK
@@ -679,6 +712,7 @@ class LIBPROTOBUF_EXPORT LogFinisher {
#define GOOGLE_CHECK(EXPRESSION) \
GOOGLE_LOG_IF(FATAL, !(EXPRESSION)) << "CHECK failed: " #EXPRESSION ": "
+#define GOOGLE_CHECK_OK(A) GOOGLE_CHECK(A)
#define GOOGLE_CHECK_EQ(A, B) GOOGLE_CHECK((A) == (B))
#define GOOGLE_CHECK_NE(A, B) GOOGLE_CHECK((A) != (B))
#define GOOGLE_CHECK_LT(A, B) GOOGLE_CHECK((A) < (B))
@@ -686,6 +720,19 @@ class LIBPROTOBUF_EXPORT LogFinisher {
#define GOOGLE_CHECK_GT(A, B) GOOGLE_CHECK((A) > (B))
#define GOOGLE_CHECK_GE(A, B) GOOGLE_CHECK((A) >= (B))
+namespace internal {
+template<typename T>
+T* CheckNotNull(const char* /* file */, int /* line */,
+ const char* name, T* val) {
+ if (val == NULL) {
+ GOOGLE_LOG(FATAL) << name;
+ }
+ return val;
+}
+} // namespace internal
+#define GOOGLE_CHECK_NOTNULL(A) \
+ internal::CheckNotNull(__FILE__, __LINE__, "'" #A "' must not be NULL", (A))
+
#ifdef NDEBUG
#define GOOGLE_DLOG GOOGLE_LOG_IF(INFO, false)
@@ -713,7 +760,7 @@ class LIBPROTOBUF_EXPORT LogFinisher {
#endif // !NDEBUG
typedef void LogHandler(LogLevel level, const char* filename, int line,
- const string& message);
+ const std::string& message);
// The protobuf library sometimes writes warning and error messages to
// stderr. These messages are primarily useful for developers, but may
@@ -825,8 +872,9 @@ class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure {
~FunctionClosure0();
void Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
function_();
- if (self_deleting_) delete this;
+ if (needs_delete) delete this;
}
private:
@@ -844,8 +892,9 @@ class MethodClosure0 : public Closure {
~MethodClosure0() {}
void Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
(object_->*method_)();
- if (self_deleting_) delete this;
+ if (needs_delete) delete this;
}
private:
@@ -866,8 +915,9 @@ class FunctionClosure1 : public Closure {
~FunctionClosure1() {}
void Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
function_(arg1_);
- if (self_deleting_) delete this;
+ if (needs_delete) delete this;
}
private:
@@ -888,8 +938,9 @@ class MethodClosure1 : public Closure {
~MethodClosure1() {}
void Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
(object_->*method_)(arg1_);
- if (self_deleting_) delete this;
+ if (needs_delete) delete this;
}
private:
@@ -911,8 +962,9 @@ class FunctionClosure2 : public Closure {
~FunctionClosure2() {}
void Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
function_(arg1_, arg2_);
- if (self_deleting_) delete this;
+ if (needs_delete) delete this;
}
private:
@@ -934,8 +986,9 @@ class MethodClosure2 : public Closure {
~MethodClosure2() {}
void Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
(object_->*method_)(arg1_, arg2_);
- if (self_deleting_) delete this;
+ if (needs_delete) delete this;
}
private:
@@ -1104,20 +1157,10 @@ using internal::WriterMutexLock;
using internal::MutexLockMaybe;
// ===================================================================
-// from google3/base/type_traits.h
+// from google3/util/utf8/public/unilib.h
namespace internal {
-// Specified by TR1 [4.7.4] Pointer modifications.
-template<typename T> struct remove_pointer { typedef T type; };
-template<typename T> struct remove_pointer<T*> { typedef T type; };
-template<typename T> struct remove_pointer<T* const> { typedef T type; };
-template<typename T> struct remove_pointer<T* volatile> { typedef T type; };
-template<typename T> struct remove_pointer<T* const volatile> {
- typedef T type; };
-
-// ===================================================================
-
// Checks if the buffer contains structurally-valid UTF-8. Implemented in
// structurally_valid.cc.
LIBPROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len);
@@ -1125,6 +1168,10 @@ LIBPROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len);
} // namespace internal
// ===================================================================
+// from google3/util/endian/endian.h
+LIBPROTOBUF_EXPORT uint32 ghtonl(uint32 x);
+
+// ===================================================================
// Shutdown support.
// Shut down the entire protocol buffers library, deleting all static-duration
@@ -1149,6 +1196,30 @@ LIBPROTOBUF_EXPORT void OnShutdown(void (*func)());
} // namespace internal
+#if PROTOBUF_USE_EXCEPTIONS
+class FatalException : public std::exception {
+ public:
+ FatalException(const char* filename, int line, const std::string& message)
+ : filename_(filename), line_(line), message_(message) {}
+ virtual ~FatalException() throw();
+
+ virtual const char* what() const throw();
+
+ const char* filename() const { return filename_; }
+ int line() const { return line_; }
+ const std::string& message() const { return message_; }
+
+ private:
+ const char* filename_;
+ const int line_;
+ const std::string message_;
+};
+#endif
+
+// This is at the end of the file instead of the beginning to work around a bug
+// in some versions of MSVC.
+using namespace std; // Don't do this at home, kids.
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/stubs/common_unittest.cc b/src/google/protobuf/stubs/common_unittest.cc
index 32c1d08..cb89207 100644
--- a/src/google/protobuf/stubs/common_unittest.cc
+++ b/src/google/protobuf/stubs/common_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -94,9 +94,9 @@ TEST(LoggingTest, DefaultLogging) {
string text = GetCapturedTestStderr();
EXPECT_EQ(
- "libprotobuf INFO "__FILE__":" + SimpleItoa(line + 1) + "] A message.\n"
- "libprotobuf WARNING "__FILE__":" + SimpleItoa(line + 2) + "] A warning.\n"
- "libprotobuf ERROR "__FILE__":" + SimpleItoa(line + 3) + "] An error.\n",
+ "[libprotobuf INFO "__FILE__":" + SimpleItoa(line + 1) + "] A message.\n"
+ "[libprotobuf WARNING "__FILE__":" + SimpleItoa(line + 2) + "] A warning.\n"
+ "[libprotobuf ERROR "__FILE__":" + SimpleItoa(line + 3) + "] An error.\n",
text);
}
@@ -182,11 +182,17 @@ class ClosureTest : public testing::Test {
a_ = 0;
b_ = NULL;
c_.clear();
+ permanent_closure_ = NULL;
+ }
+
+ void DeleteClosureInCallback() {
+ delete permanent_closure_;
}
int a_;
const char* b_;
string c_;
+ Closure* permanent_closure_;
static ClosureTest* current_instance_;
};
@@ -340,6 +346,12 @@ TEST_F(ClosureTest, TestPermanentClosureMethod2) {
delete closure;
}
+TEST_F(ClosureTest, TestPermanentClosureDeleteInCallback) {
+ permanent_closure_ = NewPermanentCallback((ClosureTest*) this,
+ &ClosureTest::DeleteClosureInCallback);
+ permanent_closure_->Run();
+}
+
} // anonymous namespace
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h
index 822d605..5b6a073 100644
--- a/src/google/protobuf/stubs/hash.h
+++ b/src/google/protobuf/stubs/hash.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -90,12 +90,16 @@ template <typename Key, typename Data,
typename HashFcn = hash<Key>,
typename EqualKey = int >
class hash_map : public std::map<Key, Data, HashFcn> {
+ public:
+ hash_map(int = 0) {}
};
template <typename Key,
typename HashFcn = hash<Key>,
typename EqualKey = int >
class hash_set : public std::set<Key, HashFcn> {
+ public:
+ hash_set(int = 0) {}
};
#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION)
@@ -123,6 +127,8 @@ template <typename Key, typename Data,
typename EqualKey = int >
class hash_map : public HASH_NAMESPACE::hash_map<
Key, Data, HashFcn> {
+ public:
+ hash_map(int = 0) {}
};
template <typename Key,
@@ -130,6 +136,8 @@ template <typename Key,
typename EqualKey = int >
class hash_set : public HASH_NAMESPACE::hash_set<
Key, HashFcn> {
+ public:
+ hash_set(int = 0) {}
};
#else
@@ -163,6 +171,8 @@ template <typename Key, typename Data,
typename EqualKey = std::equal_to<Key> >
class hash_map : public HASH_NAMESPACE::HASH_MAP_CLASS<
Key, Data, HashFcn, EqualKey> {
+ public:
+ hash_map(int = 0) {}
};
template <typename Key,
@@ -170,6 +180,8 @@ template <typename Key,
typename EqualKey = std::equal_to<Key> >
class hash_set : public HASH_NAMESPACE::HASH_SET_CLASS<
Key, HashFcn, EqualKey> {
+ public:
+ hash_set(int = 0) {}
};
#endif
diff --git a/src/google/protobuf/stubs/map_util.h b/src/google/protobuf/stubs/map_util.h
new file mode 100644
index 0000000..7495cb6
--- /dev/null
+++ b/src/google/protobuf/stubs/map_util.h
@@ -0,0 +1,771 @@
+// 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.
+
+// from google3/util/gtl/map_util.h
+// Author: Anton Carver
+
+#ifndef GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
+#define GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
+
+#include <stddef.h>
+#include <iterator>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+// Local implementation of RemoveConst to avoid including base/type_traits.h.
+template <class T> struct RemoveConst { typedef T type; };
+template <class T> struct RemoveConst<const T> : RemoveConst<T> {};
+} // namespace internal
+
+//
+// Find*()
+//
+
+// Returns a const reference to the value associated with the given key if it
+// exists. Crashes otherwise.
+//
+// This is intended as a replacement for operator[] as an rvalue (for reading)
+// when the key is guaranteed to exist.
+//
+// operator[] for lookup is discouraged for several reasons:
+// * It has a side-effect of inserting missing keys
+// * It is not thread-safe (even when it is not inserting, it can still
+// choose to resize the underlying storage)
+// * It invalidates iterators (when it chooses to resize)
+// * It default constructs a value object even if it doesn't need to
+//
+// This version assumes the key is printable, and includes it in the fatal log
+// message.
+template <class Collection>
+const typename Collection::value_type::second_type&
+FindOrDie(const Collection& collection,
+ const typename Collection::value_type::first_type& key) {
+ typename Collection::const_iterator it = collection.find(key);
+ GOOGLE_CHECK(it != collection.end()) << "Map key not found: " << key;
+ return it->second;
+}
+
+// Same as above, but returns a non-const reference.
+template <class Collection>
+typename Collection::value_type::second_type&
+FindOrDie(Collection& collection, // NOLINT
+ const typename Collection::value_type::first_type& key) {
+ typename Collection::iterator it = collection.find(key);
+ GOOGLE_CHECK(it != collection.end()) << "Map key not found: " << key;
+ return it->second;
+}
+
+// Same as FindOrDie above, but doesn't log the key on failure.
+template <class Collection>
+const typename Collection::value_type::second_type&
+FindOrDieNoPrint(const Collection& collection,
+ const typename Collection::value_type::first_type& key) {
+ typename Collection::const_iterator it = collection.find(key);
+ GOOGLE_CHECK(it != collection.end()) << "Map key not found";
+ return it->second;
+}
+
+// Same as above, but returns a non-const reference.
+template <class Collection>
+typename Collection::value_type::second_type&
+FindOrDieNoPrint(Collection& collection, // NOLINT
+ const typename Collection::value_type::first_type& key) {
+ typename Collection::iterator it = collection.find(key);
+ GOOGLE_CHECK(it != collection.end()) << "Map key not found";
+ return it->second;
+}
+
+// Returns a const reference to the value associated with the given key if it
+// exists, otherwise returns a const reference to the provided default value.
+//
+// WARNING: If a temporary object is passed as the default "value,"
+// this function will return a reference to that temporary object,
+// which will be destroyed at the end of the statement. A common
+// example: if you have a map with string values, and you pass a char*
+// as the default "value," either use the returned value immediately
+// or store it in a string (not string&).
+// Details: http://go/findwithdefault
+template <class Collection>
+const typename Collection::value_type::second_type&
+FindWithDefault(const Collection& collection,
+ const typename Collection::value_type::first_type& key,
+ const typename Collection::value_type::second_type& value) {
+ typename Collection::const_iterator it = collection.find(key);
+ if (it == collection.end()) {
+ return value;
+ }
+ return it->second;
+}
+
+// Returns a pointer to the const value associated with the given key if it
+// exists, or NULL otherwise.
+template <class Collection>
+const typename Collection::value_type::second_type*
+FindOrNull(const Collection& collection,
+ const typename Collection::value_type::first_type& key) {
+ typename Collection::const_iterator it = collection.find(key);
+ if (it == collection.end()) {
+ return 0;
+ }
+ return &it->second;
+}
+
+// Same as above but returns a pointer to the non-const value.
+template <class Collection>
+typename Collection::value_type::second_type*
+FindOrNull(Collection& collection, // NOLINT
+ const typename Collection::value_type::first_type& key) {
+ typename Collection::iterator it = collection.find(key);
+ if (it == collection.end()) {
+ return 0;
+ }
+ return &it->second;
+}
+
+// Returns the pointer value associated with the given key. If none is found,
+// NULL is returned. The function is designed to be used with a map of keys to
+// pointers.
+//
+// This function does not distinguish between a missing key and a key mapped
+// to a NULL value.
+template <class Collection>
+typename Collection::value_type::second_type
+FindPtrOrNull(const Collection& collection,
+ const typename Collection::value_type::first_type& key) {
+ typename Collection::const_iterator it = collection.find(key);
+ if (it == collection.end()) {
+ return typename Collection::value_type::second_type();
+ }
+ return it->second;
+}
+
+// Same as above, except takes non-const reference to collection.
+//
+// This function is needed for containers that propagate constness to the
+// pointee, such as boost::ptr_map.
+template <class Collection>
+typename Collection::value_type::second_type
+FindPtrOrNull(Collection& collection, // NOLINT
+ const typename Collection::value_type::first_type& key) {
+ typename Collection::iterator it = collection.find(key);
+ if (it == collection.end()) {
+ return typename Collection::value_type::second_type();
+ }
+ return it->second;
+}
+
+// Finds the pointer value associated with the given key in a map whose values
+// are linked_ptrs. Returns NULL if key is not found.
+template <class Collection>
+typename Collection::value_type::second_type::element_type*
+FindLinkedPtrOrNull(const Collection& collection,
+ const typename Collection::value_type::first_type& key) {
+ typename Collection::const_iterator it = collection.find(key);
+ if (it == collection.end()) {
+ return 0;
+ }
+ // Since linked_ptr::get() 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.get();
+}
+
+// Same as above, but dies if the key is not found.
+template <class Collection>
+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;
+ // 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;
+}
+
+// Finds the value associated with the given key and copies it to *value (if not
+// NULL). Returns false if the key was not found, true otherwise.
+template <class Collection, class Key, class Value>
+bool FindCopy(const Collection& collection,
+ const Key& key,
+ Value* const value) {
+ typename Collection::const_iterator it = collection.find(key);
+ if (it == collection.end()) {
+ return false;
+ }
+ if (value) {
+ *value = it->second;
+ }
+ return true;
+}
+
+//
+// Contains*()
+//
+
+// Returns true if and only if the given collection contains the given key.
+template <class Collection, class Key>
+bool ContainsKey(const Collection& collection, const Key& key) {
+ return collection.find(key) != collection.end();
+}
+
+// Returns true if and only if the given collection contains the given key-value
+// pair.
+template <class Collection, class Key, class Value>
+bool ContainsKeyValuePair(const Collection& collection,
+ const Key& key,
+ const Value& value) {
+ typedef typename Collection::const_iterator const_iterator;
+ std::pair<const_iterator, const_iterator> range = collection.equal_range(key);
+ for (const_iterator it = range.first; it != range.second; ++it) {
+ if (it->second == value) {
+ return true;
+ }
+ }
+ return false;
+}
+
+//
+// Insert*()
+//
+
+// Inserts the given key-value pair into the collection. Returns true if and
+// only if the key from the given pair didn't previously exist. Otherwise, the
+// value in the map is replaced with the value from the given pair.
+template <class Collection>
+bool InsertOrUpdate(Collection* const collection,
+ const typename Collection::value_type& vt) {
+ std::pair<typename Collection::iterator, bool> ret = collection->insert(vt);
+ if (!ret.second) {
+ // update
+ ret.first->second = vt.second;
+ return false;
+ }
+ return true;
+}
+
+// Same as above, except that the key and value are passed separately.
+template <class Collection>
+bool InsertOrUpdate(Collection* const collection,
+ const typename Collection::value_type::first_type& key,
+ const typename Collection::value_type::second_type& value) {
+ return InsertOrUpdate(
+ collection, typename Collection::value_type(key, value));
+}
+
+// Inserts/updates all the key-value pairs from the range defined by the
+// iterators "first" and "last" into the given collection.
+template <class Collection, class InputIterator>
+void InsertOrUpdateMany(Collection* const collection,
+ InputIterator first, InputIterator last) {
+ for (; first != last; ++first) {
+ InsertOrUpdate(collection, *first);
+ }
+}
+
+// Change the value associated with a particular key in a map or hash_map
+// of the form map<Key, Value*> which owns the objects pointed to by the
+// value pointers. If there was an existing value for the key, it is deleted.
+// True indicates an insert took place, false indicates an update + delete.
+template <class Collection>
+bool InsertAndDeleteExisting(
+ Collection* const collection,
+ const typename Collection::value_type::first_type& key,
+ const typename Collection::value_type::second_type& value) {
+ std::pair<typename Collection::iterator, bool> ret =
+ collection->insert(typename Collection::value_type(key, value));
+ if (!ret.second) {
+ delete ret.first->second;
+ ret.first->second = value;
+ return false;
+ }
+ return true;
+}
+
+// Inserts the given key and value into the given collection if and only if the
+// given key did NOT already exist in the collection. If the key previously
+// existed in the collection, the value is not changed. Returns true if the
+// key-value pair was inserted; returns false if the key was already present.
+template <class Collection>
+bool InsertIfNotPresent(Collection* const collection,
+ const typename Collection::value_type& vt) {
+ return collection->insert(vt).second;
+}
+
+// Same as above except the key and value are passed separately.
+template <class Collection>
+bool InsertIfNotPresent(
+ Collection* const collection,
+ const typename Collection::value_type::first_type& key,
+ const typename Collection::value_type::second_type& value) {
+ return InsertIfNotPresent(
+ collection, typename Collection::value_type(key, value));
+}
+
+// Same as above except dies if the key already exists in the collection.
+template <class Collection>
+void InsertOrDie(Collection* const collection,
+ const typename Collection::value_type& value) {
+ 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.";
+}
+
+// Inserts the key-value pair into the collection. Dies if key was already
+// present.
+template <class Collection>
+void InsertOrDie(Collection* const collection,
+ const typename Collection::value_type::first_type& key,
+ const typename Collection::value_type::second_type& data) {
+ typedef typename Collection::value_type value_type;
+ GOOGLE_CHECK(InsertIfNotPresent(collection, key, data))
+ << "duplicate key: " << key;
+}
+
+// Same as above except doesn't log the key on error.
+template <class Collection>
+void InsertOrDieNoPrint(
+ Collection* const collection,
+ const typename Collection::value_type::first_type& key,
+ const typename Collection::value_type::second_type& data) {
+ typedef typename Collection::value_type value_type;
+ GOOGLE_CHECK(InsertIfNotPresent(collection, key, data)) << "duplicate key.";
+}
+
+// Inserts a new key and default-initialized value. Dies if the key was already
+// present. Returns a reference to the value. Example usage:
+//
+// map<int, SomeProto> m;
+// SomeProto& proto = InsertKeyOrDie(&m, 3);
+// proto.set_field("foo");
+template <class Collection>
+typename Collection::value_type::second_type& InsertKeyOrDie(
+ Collection* const collection,
+ const typename Collection::value_type::first_type& key) {
+ typedef typename Collection::value_type value_type;
+ std::pair<typename Collection::iterator, bool> res =
+ collection->insert(value_type(key, typename value_type::second_type()));
+ GOOGLE_CHECK(res.second) << "duplicate key: " << key;
+ return res.first->second;
+}
+
+//
+// Lookup*()
+//
+
+// Looks up a given key and value pair in a collection and inserts the key-value
+// pair if it's not already present. Returns a reference to the value associated
+// with the key.
+template <class Collection>
+typename Collection::value_type::second_type&
+LookupOrInsert(Collection* const collection,
+ const typename Collection::value_type& vt) {
+ return collection->insert(vt).first->second;
+}
+
+// Same as above except the key-value are passed separately.
+template <class Collection>
+typename Collection::value_type::second_type&
+LookupOrInsert(Collection* const collection,
+ const typename Collection::value_type::first_type& key,
+ const typename Collection::value_type::second_type& value) {
+ return LookupOrInsert(
+ collection, typename Collection::value_type(key, value));
+}
+
+// Counts the number of equivalent elements in the given "sequence", and stores
+// the results in "count_map" with element as the key and count as the value.
+//
+// Example:
+// vector<string> v = {"a", "b", "c", "a", "b"};
+// map<string, int> m;
+// AddTokenCounts(v, 1, &m);
+// assert(m["a"] == 2);
+// assert(m["b"] == 2);
+// assert(m["c"] == 1);
+template <typename Sequence, typename Collection>
+void AddTokenCounts(
+ const Sequence& sequence,
+ const typename Collection::value_type::second_type& increment,
+ Collection* const count_map) {
+ for (typename Sequence::const_iterator it = sequence.begin();
+ it != sequence.end(); ++it) {
+ typename Collection::value_type::second_type& value =
+ LookupOrInsert(count_map, *it,
+ typename Collection::value_type::second_type());
+ value += increment;
+ }
+}
+
+// Returns a reference to the value associated with key. If not found, a value
+// is default constructed on the heap and added to the map.
+//
+// This function is useful for containers of the form map<Key, Value*>, where
+// inserting a new key, value pair involves constructing a new heap-allocated
+// Value, and storing a pointer to that in the collection.
+template <class Collection>
+typename Collection::value_type::second_type&
+LookupOrInsertNew(Collection* const collection,
+ const typename Collection::value_type::first_type& key) {
+ typedef typename std::iterator_traits<
+ typename Collection::value_type::second_type>::value_type Element;
+ std::pair<typename Collection::iterator, bool> ret =
+ collection->insert(typename Collection::value_type(
+ key,
+ static_cast<typename Collection::value_type::second_type>(NULL)));
+ if (ret.second) {
+ ret.first->second = new Element();
+ }
+ return ret.first->second;
+}
+
+// Same as above but constructs the value using the single-argument constructor
+// and the given "arg".
+template <class Collection, class Arg>
+typename Collection::value_type::second_type&
+LookupOrInsertNew(Collection* const collection,
+ const typename Collection::value_type::first_type& key,
+ const Arg& arg) {
+ typedef typename std::iterator_traits<
+ typename Collection::value_type::second_type>::value_type Element;
+ std::pair<typename Collection::iterator, bool> ret =
+ collection->insert(typename Collection::value_type(
+ key,
+ static_cast<typename Collection::value_type::second_type>(NULL)));
+ if (ret.second) {
+ ret.first->second = new Element(arg);
+ }
+ return ret.first->second;
+}
+
+// Lookup of linked/shared pointers is used in two scenarios:
+//
+// Use LookupOrInsertNewLinkedPtr if the container owns the elements.
+// In this case it is fine working with the raw pointer as long as it is
+// guaranteed that no other thread can delete/update an accessed element.
+// A mutex will need to lock the container operation as well as the use
+// of the returned elements. Finding an element may be performed using
+// FindLinkedPtr*().
+//
+// Use LookupOrInsertNewSharedPtr if the container does not own the elements
+// for their whole lifetime. This is typically the case when a reader allows
+// parallel updates to the container. In this case a Mutex only needs to lock
+// container operations, but all element operations must be performed on the
+// shared pointer. Finding an element must be performed using FindPtr*() and
+// cannot be done with FindLinkedPtr*() even though it compiles.
+
+// Lookup a key in a map or hash_map whose values are linked_ptrs. If it is
+// missing, set collection[key].reset(new Value::element_type) and return that.
+// Value::element_type must be default constructable.
+template <class Collection>
+typename Collection::value_type::second_type::element_type*
+LookupOrInsertNewLinkedPtr(
+ Collection* const collection,
+ const typename Collection::value_type::first_type& key) {
+ typedef typename Collection::value_type::second_type Value;
+ std::pair<typename Collection::iterator, bool> ret =
+ collection->insert(typename Collection::value_type(key, Value()));
+ if (ret.second) {
+ ret.first->second.reset(new typename Value::element_type);
+ }
+ return ret.first->second.get();
+}
+
+// A variant of LookupOrInsertNewLinkedPtr where the value is constructed using
+// a single-parameter constructor. Note: the constructor argument is computed
+// even if it will not be used, so only values cheap to compute should be passed
+// here. On the other hand it does not matter how expensive the construction of
+// the actual stored value is, as that only occurs if necessary.
+template <class Collection, class Arg>
+typename Collection::value_type::second_type::element_type*
+LookupOrInsertNewLinkedPtr(
+ Collection* const collection,
+ const typename Collection::value_type::first_type& key,
+ const Arg& arg) {
+ typedef typename Collection::value_type::second_type Value;
+ std::pair<typename Collection::iterator, bool> ret =
+ collection->insert(typename Collection::value_type(key, Value()));
+ if (ret.second) {
+ ret.first->second.reset(new typename Value::element_type(arg));
+ }
+ return ret.first->second.get();
+}
+
+// Lookup a key in a map or hash_map whose values are shared_ptrs. If it is
+// missing, set collection[key].reset(new Value::element_type). Unlike
+// LookupOrInsertNewLinkedPtr, this function returns the shared_ptr instead of
+// the raw pointer. Value::element_type must be default constructable.
+template <class Collection>
+typename Collection::value_type::second_type&
+LookupOrInsertNewSharedPtr(
+ Collection* const collection,
+ const typename Collection::value_type::first_type& key) {
+ typedef typename Collection::value_type::second_type SharedPtr;
+ typedef typename Collection::value_type::second_type::element_type Element;
+ std::pair<typename Collection::iterator, bool> ret =
+ collection->insert(typename Collection::value_type(key, SharedPtr()));
+ if (ret.second) {
+ ret.first->second.reset(new Element());
+ }
+ return ret.first->second;
+}
+
+// A variant of LookupOrInsertNewSharedPtr where the value is constructed using
+// a single-parameter constructor. Note: the constructor argument is computed
+// even if it will not be used, so only values cheap to compute should be passed
+// here. On the other hand it does not matter how expensive the construction of
+// the actual stored value is, as that only occurs if necessary.
+template <class Collection, class Arg>
+typename Collection::value_type::second_type&
+LookupOrInsertNewSharedPtr(
+ Collection* const collection,
+ const typename Collection::value_type::first_type& key,
+ const Arg& arg) {
+ typedef typename Collection::value_type::second_type SharedPtr;
+ typedef typename Collection::value_type::second_type::element_type Element;
+ std::pair<typename Collection::iterator, bool> ret =
+ collection->insert(typename Collection::value_type(key, SharedPtr()));
+ if (ret.second) {
+ ret.first->second.reset(new Element(arg));
+ }
+ return ret.first->second;
+}
+
+//
+// Misc Utility Functions
+//
+
+// Updates the value associated with the given key. If the key was not already
+// present, then the key-value pair are inserted and "previous" is unchanged. If
+// the key was already present, the value is updated and "*previous" will
+// contain a copy of the old value.
+//
+// InsertOrReturnExisting has complementary behavior that returns the
+// address of an already existing value, rather than updating it.
+template <class Collection>
+bool UpdateReturnCopy(Collection* const collection,
+ const typename Collection::value_type::first_type& key,
+ const typename Collection::value_type::second_type& value,
+ typename Collection::value_type::second_type* previous) {
+ std::pair<typename Collection::iterator, bool> ret =
+ collection->insert(typename Collection::value_type(key, value));
+ if (!ret.second) {
+ // update
+ if (previous) {
+ *previous = ret.first->second;
+ }
+ ret.first->second = value;
+ return true;
+ }
+ return false;
+}
+
+// Same as above except that the key and value are passed as a pair.
+template <class Collection>
+bool UpdateReturnCopy(Collection* const collection,
+ const typename Collection::value_type& vt,
+ typename Collection::value_type::second_type* previous) {
+ std::pair<typename Collection::iterator, bool> ret = collection->insert(vt);
+ if (!ret.second) {
+ // update
+ if (previous) {
+ *previous = ret.first->second;
+ }
+ ret.first->second = vt.second;
+ return true;
+ }
+ return false;
+}
+
+// Tries to insert the given key-value pair into the collection. Returns NULL if
+// the insert succeeds. Otherwise, returns a pointer to the existing value.
+//
+// This complements UpdateReturnCopy in that it allows to update only after
+// verifying the old value and still insert quickly without having to look up
+// twice. Unlike UpdateReturnCopy this also does not come with the issue of an
+// undefined previous* in case new data was inserted.
+template <class Collection>
+typename Collection::value_type::second_type* const
+InsertOrReturnExisting(Collection* const collection,
+ const typename Collection::value_type& vt) {
+ std::pair<typename Collection::iterator, bool> ret = collection->insert(vt);
+ if (ret.second) {
+ return NULL; // Inserted, no existing previous value.
+ } else {
+ return &ret.first->second; // Return address of already existing value.
+ }
+}
+
+// Same as above, except for explicit key and data.
+template <class Collection>
+typename Collection::value_type::second_type* const
+InsertOrReturnExisting(
+ Collection* const collection,
+ const typename Collection::value_type::first_type& key,
+ const typename Collection::value_type::second_type& data) {
+ return InsertOrReturnExisting(collection,
+ typename Collection::value_type(key, data));
+}
+
+// Erases the collection item identified by the given key, and returns the value
+// associated with that key. It is assumed that the value (i.e., the
+// mapped_type) is a pointer. Returns NULL if the key was not found in the
+// collection.
+//
+// Examples:
+// map<string, MyType*> my_map;
+//
+// One line cleanup:
+// delete EraseKeyReturnValuePtr(&my_map, "abc");
+//
+// Use returned value:
+// scoped_ptr<MyType> value_ptr(EraseKeyReturnValuePtr(&my_map, "abc"));
+// if (value_ptr.get())
+// value_ptr->DoSomething();
+//
+template <class Collection>
+typename Collection::value_type::second_type EraseKeyReturnValuePtr(
+ Collection* const collection,
+ const typename Collection::value_type::first_type& key) {
+ typename Collection::iterator it = collection->find(key);
+ if (it == collection->end()) {
+ return NULL;
+ }
+ typename Collection::value_type::second_type v = it->second;
+ collection->erase(it);
+ return v;
+}
+
+// Inserts all the keys from map_container into key_container, which must
+// support insert(MapContainer::key_type).
+//
+// Note: any initial contents of the key_container are not cleared.
+template <class MapContainer, class KeyContainer>
+void InsertKeysFromMap(const MapContainer& map_container,
+ KeyContainer* key_container) {
+ GOOGLE_CHECK(key_container != NULL);
+ for (typename MapContainer::const_iterator it = map_container.begin();
+ it != map_container.end(); ++it) {
+ key_container->insert(it->first);
+ }
+}
+
+// Appends all the keys from map_container into key_container, which must
+// support push_back(MapContainer::key_type).
+//
+// Note: any initial contents of the key_container are not cleared.
+template <class MapContainer, class KeyContainer>
+void AppendKeysFromMap(const MapContainer& map_container,
+ KeyContainer* key_container) {
+ GOOGLE_CHECK(key_container != NULL);
+ for (typename MapContainer::const_iterator it = map_container.begin();
+ it != map_container.end(); ++it) {
+ key_container->push_back(it->first);
+ }
+}
+
+// A more specialized overload of AppendKeysFromMap to optimize reallocations
+// for the common case in which we're appending keys to a vector and hence can
+// (and sometimes should) call reserve() first.
+//
+// (It would be possible to play SFINAE games to call reserve() for any
+// container that supports it, but this seems to get us 99% of what we need
+// without the complexity of a SFINAE-based solution.)
+template <class MapContainer, class KeyType>
+void AppendKeysFromMap(const MapContainer& map_container,
+ vector<KeyType>* key_container) {
+ GOOGLE_CHECK(key_container != NULL);
+ // We now have the opportunity to call reserve(). Calling reserve() every
+ // time is a bad idea for some use cases: libstdc++'s implementation of
+ // vector<>::reserve() resizes the vector's backing store to exactly the
+ // given size (unless it's already at least that big). Because of this,
+ // the use case that involves appending a lot of small maps (total size
+ // N) one by one to a vector would be O(N^2). But never calling reserve()
+ // loses the opportunity to improve the use case of adding from a large
+ // map to an empty vector (this improves performance by up to 33%). A
+ // number of heuristics are possible; see the discussion in
+ // cl/34081696. Here we use the simplest one.
+ if (key_container->empty()) {
+ key_container->reserve(map_container.size());
+ }
+ for (typename MapContainer::const_iterator it = map_container.begin();
+ it != map_container.end(); ++it) {
+ key_container->push_back(it->first);
+ }
+}
+
+// Inserts all the values from map_container into value_container, which must
+// support push_back(MapContainer::mapped_type).
+//
+// Note: any initial contents of the value_container are not cleared.
+template <class MapContainer, class ValueContainer>
+void AppendValuesFromMap(const MapContainer& map_container,
+ ValueContainer* value_container) {
+ GOOGLE_CHECK(value_container != NULL);
+ for (typename MapContainer::const_iterator it = map_container.begin();
+ it != map_container.end(); ++it) {
+ value_container->push_back(it->second);
+ }
+}
+
+// A more specialized overload of AppendValuesFromMap to optimize reallocations
+// for the common case in which we're appending values to a vector and hence
+// can (and sometimes should) call reserve() first.
+//
+// (It would be possible to play SFINAE games to call reserve() for any
+// container that supports it, but this seems to get us 99% of what we need
+// without the complexity of a SFINAE-based solution.)
+template <class MapContainer, class ValueType>
+void AppendValuesFromMap(const MapContainer& map_container,
+ vector<ValueType>* value_container) {
+ GOOGLE_CHECK(value_container != NULL);
+ // See AppendKeysFromMap for why this is done.
+ if (value_container->empty()) {
+ value_container->reserve(map_container.size());
+ }
+ for (typename MapContainer::const_iterator it = map_container.begin();
+ it != map_container.end(); ++it) {
+ value_container->push_back(it->second);
+ }
+}
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
diff --git a/src/google/protobuf/stubs/once.cc b/src/google/protobuf/stubs/once.cc
index 5b7af9c..889c647 100644
--- a/src/google/protobuf/stubs/once.cc
+++ b/src/google/protobuf/stubs/once.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,54 +35,65 @@
// This header is intended to be included only by internal .cc files and
// generated .pb.cc files. Users should not use this directly.
+#include <google/protobuf/stubs/once.h>
+
+#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
#ifdef _WIN32
#include <windows.h>
+#else
+#include <sched.h>
#endif
-#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/stubs/atomicops.h>
namespace google {
namespace protobuf {
-#ifdef _WIN32
-
-struct ProtobufOnceInternal {
- ProtobufOnceInternal() {
- InitializeCriticalSection(&critical_section);
- }
- ~ProtobufOnceInternal() {
- DeleteCriticalSection(&critical_section);
- }
- CRITICAL_SECTION critical_section;
-};
-
-ProtobufOnceType::~ProtobufOnceType()
-{
- delete internal_;
- internal_ = NULL;
-}
+namespace {
-ProtobufOnceType::ProtobufOnceType() {
- // internal_ may be non-NULL if Init() was already called.
- if (internal_ == NULL) internal_ = new ProtobufOnceInternal;
+void SchedYield() {
+#ifdef _WIN32
+ Sleep(0);
+#else // POSIX
+ sched_yield();
+#endif
}
-void ProtobufOnceType::Init(void (*init_func)()) {
- // internal_ may be NULL if we're still in dynamic initialization and the
- // constructor has not been called yet. As mentioned in once.h, we assume
- // that the program is still single-threaded at this time, and therefore it
- // should be safe to initialize internal_ like so.
- if (internal_ == NULL) internal_ = new ProtobufOnceInternal;
+} // namespace
- EnterCriticalSection(&internal_->critical_section);
- if (!initialized_) {
- init_func();
- initialized_ = true;
+void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure) {
+ internal::AtomicWord state = internal::Acquire_Load(once);
+ // Fast path. The provided closure was already executed.
+ if (state == ONCE_STATE_DONE) {
+ return;
+ }
+ // The closure execution did not complete yet. The once object can be in one
+ // of the two following states:
+ // - UNINITIALIZED: We are the first thread calling this function.
+ // - EXECUTING_CLOSURE: Another thread is already executing the closure.
+ //
+ // First, try to change the state from UNINITIALIZED to EXECUTING_CLOSURE
+ // atomically.
+ state = internal::Acquire_CompareAndSwap(
+ once, ONCE_STATE_UNINITIALIZED, ONCE_STATE_EXECUTING_CLOSURE);
+ if (state == ONCE_STATE_UNINITIALIZED) {
+ // We are the first thread to call this function, so we have to call the
+ // closure.
+ closure->Run();
+ internal::Release_Store(once, ONCE_STATE_DONE);
+ } else {
+ // Another thread has already started executing the closure. We need to
+ // wait until it completes the initialization.
+ while (state == ONCE_STATE_EXECUTING_CLOSURE) {
+ // Note that futex() could be used here on Linux as an improvement.
+ SchedYield();
+ state = internal::Acquire_Load(once);
+ }
}
- LeaveCriticalSection(&internal_->critical_section);
}
-#endif
-
} // namespace protobuf
} // namespace google
+
+#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
diff --git a/src/google/protobuf/stubs/once.h b/src/google/protobuf/stubs/once.h
index 0dee407..cc62bba 100644
--- a/src/google/protobuf/stubs/once.h
+++ b/src/google/protobuf/stubs/once.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -37,16 +37,22 @@
//
// This is basically a portable version of pthread_once().
//
-// This header declares three things:
+// This header declares:
// * A type called ProtobufOnceType.
// * A macro GOOGLE_PROTOBUF_DECLARE_ONCE() which declares a variable of type
// ProtobufOnceType. This is the only legal way to declare such a variable.
-// The macro may only be used at the global scope (you cannot create local
-// or class member variables of this type).
-// * A function GogoleOnceInit(ProtobufOnceType* once, void (*init_func)()).
+// The macro may only be used at the global scope (you cannot create local or
+// class member variables of this type).
+// * A function GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()).
// This function, when invoked multiple times given the same ProtobufOnceType
// object, will invoke init_func on the first call only, and will make sure
// none of the calls return before that first call to init_func has finished.
+// * The user can provide a parameter which GoogleOnceInit() forwards to the
+// user-provided function when it is called. Usage example:
+// int a = 10;
+// GoogleOnceInit(&my_once, &MyFunctionExpectingIntArgument, &a);
+// * This implementation guarantees that ProtobufOnceType is a POD (i.e. no
+// static initializer generated).
//
// This implements a way to perform lazy initialization. It's more efficient
// than using mutexes as no lock is needed if initialization has already
@@ -72,50 +78,87 @@
#ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__
#define GOOGLE_PROTOBUF_STUBS_ONCE_H__
+#include <google/protobuf/stubs/atomicops.h>
#include <google/protobuf/stubs/common.h>
-#ifndef _WIN32
-#include <pthread.h>
-#endif
-
namespace google {
namespace protobuf {
-#ifdef _WIN32
-
-struct ProtobufOnceInternal;
+#ifdef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
-struct LIBPROTOBUF_EXPORT ProtobufOnceType {
- ProtobufOnceType();
- ~ProtobufOnceType();
- void Init(void (*init_func)());
+typedef bool ProtobufOnceType;
- volatile bool initialized_;
- ProtobufOnceInternal* internal_;
-};
-
-#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \
- ::google::protobuf::ProtobufOnceType NAME
+#define GOOGLE_PROTOBUF_ONCE_INIT false
inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
- // Note: Double-checked locking is safe on x86.
- if (!once->initialized_) {
- once->Init(init_func);
+ if (!*once) {
+ *once = true;
+ init_func();
+ }
+}
+
+template <typename Arg>
+inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg),
+ Arg arg) {
+ if (!*once) {
+ *once = true;
+ init_func(arg);
}
}
#else
-typedef pthread_once_t ProtobufOnceType;
+enum {
+ ONCE_STATE_UNINITIALIZED = 0,
+ ONCE_STATE_EXECUTING_CLOSURE = 1,
+ ONCE_STATE_DONE = 2
+};
+
+typedef internal::AtomicWord ProtobufOnceType;
-#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \
- pthread_once_t NAME = PTHREAD_ONCE_INIT
+#define GOOGLE_PROTOBUF_ONCE_INIT ::google::protobuf::ONCE_STATE_UNINITIALIZED
+
+LIBPROTOBUF_EXPORT
+void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure);
inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
- pthread_once(once, init_func);
+ if (internal::Acquire_Load(once) != ONCE_STATE_DONE) {
+ internal::FunctionClosure0 func(init_func, false);
+ GoogleOnceInitImpl(once, &func);
+ }
+}
+
+template <typename Arg>
+inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg*),
+ Arg* arg) {
+ if (internal::Acquire_Load(once) != ONCE_STATE_DONE) {
+ internal::FunctionClosure1<Arg*> func(init_func, false, arg);
+ GoogleOnceInitImpl(once, &func);
+ }
}
-#endif
+#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
+class GoogleOnceDynamic {
+ public:
+ GoogleOnceDynamic() : state_(GOOGLE_PROTOBUF_ONCE_INIT) { }
+
+ // If this->Init() has not been called before by any thread,
+ // execute (*func_with_arg)(arg) then return.
+ // Otherwise, wait until that prior invocation has finished
+ // executing its function, then return.
+ template<typename T>
+ void Init(void (*func_with_arg)(T*), T* arg) {
+ GoogleOnceInit<T>(&this->state_,
+ func_with_arg,
+ arg);
+ }
+ private:
+ ProtobufOnceType state_;
+};
+
+#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \
+ ::google::protobuf::ProtobufOnceType NAME = GOOGLE_PROTOBUF_ONCE_INIT
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/stubs/once_unittest.cc b/src/google/protobuf/stubs/once_unittest.cc
index b8f86a0..cb5a20d 100644
--- a/src/google/protobuf/stubs/once_unittest.cc
+++ b/src/google/protobuf/stubs/once_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/stubs/platform_macros.h b/src/google/protobuf/stubs/platform_macros.h
new file mode 100644
index 0000000..7956d07
--- /dev/null
+++ b/src/google/protobuf/stubs/platform_macros.h
@@ -0,0 +1,103 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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_PLATFORM_MACROS_H_
+#define GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
+
+#include <google/protobuf/stubs/common.h>
+
+#define GOOGLE_PROTOBUF_PLATFORM_ERROR \
+#error "Host platform was not detected as supported by protobuf"
+
+// Processor architecture detection. For more info on what's defined, see:
+// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
+// http://www.agner.org/optimize/calling_conventions.pdf
+// or with gcc, run: "echo | gcc -E -dM -"
+#if defined(_M_X64) || defined(__x86_64__)
+#define GOOGLE_PROTOBUF_ARCH_X64 1
+#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+#elif defined(_M_IX86) || defined(__i386__)
+#define GOOGLE_PROTOBUF_ARCH_IA32 1
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#elif defined(__QNX__)
+#define GOOGLE_PROTOBUF_ARCH_ARM_QNX 1
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#elif defined(__ARMEL__)
+#define GOOGLE_PROTOBUF_ARCH_ARM 1
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#elif defined(__aarch64__)
+#define GOOGLE_PROTOBUF_ARCH_AARCH64 1
+#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+#elif defined(__MIPSEL__)
+#if defined(__LP64__)
+#define GOOGLE_PROTOBUF_ARCH_MIPS64 1
+#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+#else
+#define GOOGLE_PROTOBUF_ARCH_MIPS 1
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#endif
+#elif defined(__pnacl__)
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#elif defined(sparc)
+#define GOOGLE_PROTOBUF_ARCH_SPARC 1
+#ifdef SOLARIS_64BIT_ENABLED
+#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+#else
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#endif
+#elif defined(__GNUC__)
+# if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
+// We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h
+# elif defined(__clang__)
+# if !__has_extension(c_atomic)
+GOOGLE_PROTOBUF_PLATFORM_ERROR
+# endif
+// We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h
+# endif
+# if __LP64__
+# define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+# else
+# define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+# endif
+#else
+GOOGLE_PROTOBUF_PLATFORM_ERROR
+#endif
+
+#if defined(__APPLE__)
+#define GOOGLE_PROTOBUF_OS_APPLE
+#elif defined(__native_client__)
+#define GOOGLE_PROTOBUF_OS_NACL
+#elif defined(sun)
+#define GOOGLE_PROTOBUF_OS_SOLARIS
+#endif
+
+#undef GOOGLE_PROTOBUF_PLATFORM_ERROR
+
+#endif // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
diff --git a/src/google/protobuf/stubs/shared_ptr.h b/src/google/protobuf/stubs/shared_ptr.h
new file mode 100644
index 0000000..d250bf4
--- /dev/null
+++ b/src/google/protobuf/stubs/shared_ptr.h
@@ -0,0 +1,470 @@
+// 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.
+
+// from google3/util/gtl/shared_ptr.h
+
+#ifndef GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
+#define GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
+
+#include <google/protobuf/stubs/atomicops.h>
+
+#include <algorithm> // for swap
+#include <stddef.h>
+#include <memory>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Alias to std::shared_ptr for any C++11 platform,
+// and for any supported MSVC compiler.
+#if !defined(UTIL_GTL_USE_STD_SHARED_PTR) && \
+ (defined(COMPILER_MSVC) || defined(LANG_CXX11))
+#define UTIL_GTL_USE_STD_SHARED_PTR 1
+#endif
+
+#if defined(UTIL_GTL_USE_STD_SHARED_PTR) && UTIL_GTL_USE_STD_SHARED_PTR
+
+// These are transitional. They will be going away soon.
+// Please just #include <memory> and just type std::shared_ptr yourself, instead
+// of relying on this file.
+//
+// Migration doc: http://go/std-shared-ptr-lsc
+using std::enable_shared_from_this;
+using std::shared_ptr;
+using std::static_pointer_cast;
+using std::weak_ptr;
+
+#else // below, UTIL_GTL_USE_STD_SHARED_PTR not set or set to 0.
+
+// For everything else there is the google3 implementation.
+inline bool RefCountDec(volatile Atomic32 *ptr) {
+ return Barrier_AtomicIncrement(ptr, -1) != 0;
+}
+
+inline void RefCountInc(volatile Atomic32 *ptr) {
+ NoBarrier_AtomicIncrement(ptr, 1);
+}
+
+template <typename T> class shared_ptr;
+template <typename T> class weak_ptr;
+
+// This class is an internal implementation detail for shared_ptr. If two
+// shared_ptrs point to the same object, they also share a control block.
+// An "empty" shared_pointer refers to NULL and also has a NULL control block.
+// It contains all of the state that's needed for reference counting or any
+// other kind of resource management. In this implementation the control block
+// happens to consist of two atomic words, the reference count (the number
+// of shared_ptrs that share ownership of the object) and the weak count
+// (the number of weak_ptrs that observe the object, plus 1 if the
+// refcount is nonzero).
+//
+// The "plus 1" is to prevent a race condition in the shared_ptr and
+// weak_ptr destructors. We need to make sure the control block is
+// only deleted once, so we need to make sure that at most one
+// object sees the weak count decremented from 1 to 0.
+class SharedPtrControlBlock {
+ template <typename T> friend class shared_ptr;
+ template <typename T> friend class weak_ptr;
+ private:
+ SharedPtrControlBlock() : refcount_(1), weak_count_(1) { }
+ Atomic32 refcount_;
+ Atomic32 weak_count_;
+};
+
+// Forward declaration. The class is defined below.
+template <typename T> class enable_shared_from_this;
+
+template <typename T>
+class shared_ptr {
+ template <typename U> friend class weak_ptr;
+ public:
+ typedef T element_type;
+
+ shared_ptr() : ptr_(NULL), control_block_(NULL) {}
+
+ explicit shared_ptr(T* ptr)
+ : ptr_(ptr),
+ control_block_(ptr != NULL ? new SharedPtrControlBlock : NULL) {
+ // If p is non-null and T inherits from enable_shared_from_this, we
+ // set up the data that shared_from_this needs.
+ MaybeSetupWeakThis(ptr);
+ }
+
+ // Copy constructor: makes this object a copy of ptr, and increments
+ // the reference count.
+ template <typename U>
+ shared_ptr(const shared_ptr<U>& ptr)
+ : ptr_(NULL),
+ control_block_(NULL) {
+ Initialize(ptr);
+ }
+ // Need non-templated version to prevent the compiler-generated default
+ shared_ptr(const shared_ptr<T>& ptr)
+ : ptr_(NULL),
+ control_block_(NULL) {
+ Initialize(ptr);
+ }
+
+ // Assignment operator. Replaces the existing shared_ptr with ptr.
+ // Increment ptr's reference count and decrement the one being replaced.
+ template <typename U>
+ shared_ptr<T>& operator=(const shared_ptr<U>& ptr) {
+ if (ptr_ != ptr.ptr_) {
+ shared_ptr<T> me(ptr); // will hold our previous state to be destroyed.
+ swap(me);
+ }
+ return *this;
+ }
+
+ // Need non-templated version to prevent the compiler-generated default
+ shared_ptr<T>& operator=(const shared_ptr<T>& ptr) {
+ if (ptr_ != ptr.ptr_) {
+ shared_ptr<T> me(ptr); // will hold our previous state to be destroyed.
+ swap(me);
+ }
+ return *this;
+ }
+
+ // TODO(austern): Consider providing this constructor. The draft C++ standard
+ // (20.8.10.2.1) includes it. However, it says that this constructor throws
+ // a bad_weak_ptr exception when ptr is expired. Is it better to provide this
+ // constructor and make it do something else, like fail with a CHECK, or to
+ // leave this constructor out entirely?
+ //
+ // template <typename U>
+ // shared_ptr(const weak_ptr<U>& ptr);
+
+ ~shared_ptr() {
+ if (ptr_ != NULL) {
+ if (!RefCountDec(&control_block_->refcount_)) {
+ delete ptr_;
+
+ // weak_count_ is defined as the number of weak_ptrs that observe
+ // ptr_, plus 1 if refcount_ is nonzero.
+ if (!RefCountDec(&control_block_->weak_count_)) {
+ delete control_block_;
+ }
+ }
+ }
+ }
+
+ // Replaces underlying raw pointer with the one passed in. The reference
+ // count is set to one (or zero if the pointer is NULL) for the pointer
+ // being passed in and decremented for the one being replaced.
+ //
+ // If you have a compilation error with this code, make sure you aren't
+ // passing NULL, nullptr, or 0 to this function. Call reset without an
+ // argument to reset to a null ptr.
+ template <typename Y>
+ void reset(Y* p) {
+ if (p != ptr_) {
+ shared_ptr<T> tmp(p);
+ tmp.swap(*this);
+ }
+ }
+
+ void reset() {
+ reset(static_cast<T*>(NULL));
+ }
+
+ // Exchanges the contents of this with the contents of r. This function
+ // supports more efficient swapping since it eliminates the need for a
+ // temporary shared_ptr object.
+ void swap(shared_ptr<T>& r) {
+ using std::swap; // http://go/using-std-swap
+ swap(ptr_, r.ptr_);
+ swap(control_block_, r.control_block_);
+ }
+
+ // The following function is useful for gaining access to the underlying
+ // pointer when a shared_ptr remains in scope so the reference-count is
+ // known to be > 0 (e.g. for parameter passing).
+ T* get() const {
+ return ptr_;
+ }
+
+ T& operator*() const {
+ return *ptr_;
+ }
+
+ T* operator->() const {
+ return ptr_;
+ }
+
+ long use_count() const {
+ return control_block_ ? control_block_->refcount_ : 1;
+ }
+
+ bool unique() const {
+ return use_count() == 1;
+ }
+
+ private:
+ // If r is non-empty, initialize *this to share ownership with r,
+ // increasing the underlying reference count.
+ // If r is empty, *this remains empty.
+ // Requires: this is empty, namely this->ptr_ == NULL.
+ template <typename U>
+ void Initialize(const shared_ptr<U>& r) {
+ // This performs a static_cast on r.ptr_ to U*, which is a no-op since it
+ // is already a U*. So initialization here requires that r.ptr_ is
+ // implicitly convertible to T*.
+ InitializeWithStaticCast<U>(r);
+ }
+
+ // Initializes *this as described in Initialize, but additionally performs a
+ // static_cast from r.ptr_ (V*) to U*.
+ // NOTE(gfc): We'd need a more general form to support const_pointer_cast and
+ // dynamic_pointer_cast, but those operations are sufficiently discouraged
+ // that supporting static_pointer_cast is sufficient.
+ template <typename U, typename V>
+ void InitializeWithStaticCast(const shared_ptr<V>& r) {
+ if (r.control_block_ != NULL) {
+ RefCountInc(&r.control_block_->refcount_);
+
+ ptr_ = static_cast<U*>(r.ptr_);
+ control_block_ = r.control_block_;
+ }
+ }
+
+ // Helper function for the constructor that takes a raw pointer. If T
+ // doesn't inherit from enable_shared_from_this<T> then we have nothing to
+ // do, so this function is trivial and inline. The other version is declared
+ // out of line, after the class definition of enable_shared_from_this.
+ void MaybeSetupWeakThis(enable_shared_from_this<T>* ptr);
+ void MaybeSetupWeakThis(...) { }
+
+ T* ptr_;
+ SharedPtrControlBlock* control_block_;
+
+#ifndef SWIG
+ template <typename U>
+ friend class shared_ptr;
+
+ template <typename U, typename V>
+ friend shared_ptr<U> static_pointer_cast(const shared_ptr<V>& rhs);
+#endif
+};
+
+// Matches the interface of std::swap as an aid to generic programming.
+template <typename T> void swap(shared_ptr<T>& r, shared_ptr<T>& s) {
+ r.swap(s);
+}
+
+template <typename T, typename U>
+shared_ptr<T> static_pointer_cast(const shared_ptr<U>& rhs) {
+ shared_ptr<T> lhs;
+ lhs.template InitializeWithStaticCast<T>(rhs);
+ return lhs;
+}
+
+// See comments at the top of the file for a description of why this
+// class exists, and the draft C++ standard (as of July 2009 the
+// latest draft is N2914) for the detailed specification.
+template <typename T>
+class weak_ptr {
+ template <typename U> friend class weak_ptr;
+ public:
+ typedef T element_type;
+
+ // Create an empty (i.e. already expired) weak_ptr.
+ weak_ptr() : ptr_(NULL), control_block_(NULL) { }
+
+ // Create a weak_ptr that observes the same object that ptr points
+ // to. Note that there is no race condition here: we know that the
+ // control block can't disappear while we're looking at it because
+ // it is owned by at least one shared_ptr, ptr.
+ template <typename U> weak_ptr(const shared_ptr<U>& ptr) {
+ CopyFrom(ptr.ptr_, ptr.control_block_);
+ }
+
+ // Copy a weak_ptr. The object it points to might disappear, but we
+ // don't care: we're only working with the control block, and it can't
+ // disappear while we're looking at because it's owned by at least one
+ // weak_ptr, ptr.
+ template <typename U> weak_ptr(const weak_ptr<U>& ptr) {
+ CopyFrom(ptr.ptr_, ptr.control_block_);
+ }
+
+ // Need non-templated version to prevent default copy constructor
+ weak_ptr(const weak_ptr& ptr) {
+ CopyFrom(ptr.ptr_, ptr.control_block_);
+ }
+
+ // Destroy the weak_ptr. If no shared_ptr owns the control block, and if
+ // we are the last weak_ptr to own it, then it can be deleted. Note that
+ // weak_count_ is defined as the number of weak_ptrs sharing this control
+ // block, plus 1 if there are any shared_ptrs. We therefore know that it's
+ // safe to delete the control block when weak_count_ reaches 0, without
+ // having to perform any additional tests.
+ ~weak_ptr() {
+ if (control_block_ != NULL &&
+ !RefCountDec(&control_block_->weak_count_)) {
+ delete control_block_;
+ }
+ }
+
+ weak_ptr& operator=(const weak_ptr& ptr) {
+ if (&ptr != this) {
+ weak_ptr tmp(ptr);
+ tmp.swap(*this);
+ }
+ return *this;
+ }
+ template <typename U> weak_ptr& operator=(const weak_ptr<U>& ptr) {
+ weak_ptr tmp(ptr);
+ tmp.swap(*this);
+ return *this;
+ }
+ template <typename U> weak_ptr& operator=(const shared_ptr<U>& ptr) {
+ weak_ptr tmp(ptr);
+ tmp.swap(*this);
+ return *this;
+ }
+
+ void swap(weak_ptr& ptr) {
+ using std::swap; // http://go/using-std-swap
+ swap(ptr_, ptr.ptr_);
+ swap(control_block_, ptr.control_block_);
+ }
+
+ void reset() {
+ weak_ptr tmp;
+ tmp.swap(*this);
+ }
+
+ // Return the number of shared_ptrs that own the object we are observing.
+ // Note that this number can be 0 (if this pointer has expired).
+ long use_count() const {
+ return control_block_ != NULL ? control_block_->refcount_ : 0;
+ }
+
+ bool expired() const { return use_count() == 0; }
+
+ // Return a shared_ptr that owns the object we are observing. If we
+ // have expired, the shared_ptr will be empty. We have to be careful
+ // about concurrency, though, since some other thread might be
+ // destroying the last owning shared_ptr while we're in this
+ // function. We want to increment the refcount only if it's nonzero
+ // and get the new value, and we want that whole operation to be
+ // atomic.
+ shared_ptr<T> lock() const {
+ shared_ptr<T> result;
+ if (control_block_ != NULL) {
+ Atomic32 old_refcount;
+ do {
+ old_refcount = control_block_->refcount_;
+ if (old_refcount == 0)
+ break;
+ } while (old_refcount !=
+ NoBarrier_CompareAndSwap(
+ &control_block_->refcount_, old_refcount,
+ old_refcount + 1));
+ if (old_refcount > 0) {
+ result.ptr_ = ptr_;
+ result.control_block_ = control_block_;
+ }
+ }
+
+ return result;
+ }
+
+ private:
+ void CopyFrom(T* ptr, SharedPtrControlBlock* control_block) {
+ ptr_ = ptr;
+ control_block_ = control_block;
+ if (control_block_ != NULL)
+ RefCountInc(&control_block_->weak_count_);
+ }
+
+ private:
+ element_type* ptr_;
+ SharedPtrControlBlock* control_block_;
+};
+
+template <typename T> void swap(weak_ptr<T>& r, weak_ptr<T>& s) {
+ r.swap(s);
+}
+
+// See comments at the top of the file for a description of why this class
+// exists, and section 20.8.10.5 of the draft C++ standard (as of July 2009
+// the latest draft is N2914) for the detailed specification.
+template <typename T>
+class enable_shared_from_this {
+ friend class shared_ptr<T>;
+ public:
+ // Precondition: there must be a shared_ptr that owns *this and that was
+ // created, directly or indirectly, from a raw pointer of type T*. (The
+ // latter part of the condition is technical but not quite redundant; it
+ // rules out some complicated uses involving inheritance hierarchies.)
+ shared_ptr<T> shared_from_this() {
+ // Behavior is undefined if the precondition isn't satisfied; we choose
+ // to die with a CHECK failure.
+ CHECK(!weak_this_.expired()) << "No shared_ptr owns this object";
+ return weak_this_.lock();
+ }
+ shared_ptr<const T> shared_from_this() const {
+ CHECK(!weak_this_.expired()) << "No shared_ptr owns this object";
+ return weak_this_.lock();
+ }
+
+ protected:
+ enable_shared_from_this() { }
+ enable_shared_from_this(const enable_shared_from_this& other) { }
+ enable_shared_from_this& operator=(const enable_shared_from_this& other) {
+ return *this;
+ }
+ ~enable_shared_from_this() { }
+
+ private:
+ weak_ptr<T> weak_this_;
+};
+
+// This is a helper function called by shared_ptr's constructor from a raw
+// pointer. If T inherits from enable_shared_from_this<T>, it sets up
+// weak_this_ so that shared_from_this works correctly. If T does not inherit
+// from weak_this we get a different overload, defined inline, which does
+// nothing.
+template<typename T>
+void shared_ptr<T>::MaybeSetupWeakThis(enable_shared_from_this<T>* ptr) {
+ if (ptr) {
+ CHECK(ptr->weak_this_.expired()) << "Object already owned by a shared_ptr";
+ ptr->weak_this_ = *this;
+ }
+}
+
+#endif // UTIL_GTL_USE_STD_SHARED_PTR
+
+} // internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
diff --git a/src/google/protobuf/stubs/stl_util.h b/src/google/protobuf/stubs/stl_util.h
new file mode 100644
index 0000000..9e4c82a
--- /dev/null
+++ b/src/google/protobuf/stubs/stl_util.h
@@ -0,0 +1,121 @@
+// 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.
+
+// from google3/util/gtl/stl_util.h
+
+#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
+#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+// STLDeleteContainerPointers()
+// For a range within a container of pointers, calls delete
+// (non-array version) on these pointers.
+// NOTE: for these three functions, we could just implement a DeleteObject
+// functor and then call for_each() on the range and functor, but this
+// requires us to pull in all of algorithm.h, which seems expensive.
+// For hash_[multi]set, it is important that this deletes behind the iterator
+// because the hash_set may call the hash function on the iterator when it is
+// advanced, which could result in the hash function trying to deference a
+// stale pointer.
+template <class ForwardIterator>
+void STLDeleteContainerPointers(ForwardIterator begin,
+ ForwardIterator end) {
+ while (begin != end) {
+ ForwardIterator temp = begin;
+ ++begin;
+ delete *temp;
+ }
+}
+
+// Inside Google, this function implements a horrible, disgusting hack in which
+// we reach into the string's private implementation and resize it without
+// initializing the new bytes. In some cases doing this can significantly
+// improve performance. However, since it's totally non-portable it has no
+// place in open source code. Feel free to fill this function in with your
+// own disgusting hack if you want the perf boost.
+inline void STLStringResizeUninitialized(string* s, size_t new_size) {
+ s->resize(new_size);
+}
+
+// Return a mutable char* pointing to a string's internal buffer,
+// which may not be null-terminated. Writing through this pointer will
+// modify the string.
+//
+// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the
+// next call to a string method that invalidates iterators.
+//
+// As of 2006-04, there is no standard-blessed way of getting a
+// mutable reference to a string's internal buffer. However, issue 530
+// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530)
+// proposes this as the method. According to Matt Austern, this should
+// already work on all current implementations.
+inline char* string_as_array(string* str) {
+ // DO NOT USE const_cast<char*>(str->data())! See the unittest for why.
+ return str->empty() ? NULL : &*str->begin();
+}
+
+// STLDeleteElements() deletes all the elements in an STL container and clears
+// the container. This function is suitable for use with a vector, set,
+// hash_set, or any other STL container which defines sensible begin(), end(),
+// and clear() methods.
+//
+// If container is NULL, this function is a no-op.
+//
+// As an alternative to calling STLDeleteElements() directly, consider
+// ElementDeleter (defined below), which ensures that your container's elements
+// are deleted when the ElementDeleter goes out of scope.
+template <class T>
+void STLDeleteElements(T *container) {
+ if (!container) return;
+ STLDeleteContainerPointers(container->begin(), container->end());
+ container->clear();
+}
+
+// Given an STL container consisting of (key, value) pairs, STLDeleteValues
+// deletes all the "value" components and clears the container. Does nothing
+// in the case it's given a NULL pointer.
+
+template <class T>
+void STLDeleteValues(T *v) {
+ if (!v) return;
+ for (typename T::iterator i = v->begin(); i != v->end(); ++i) {
+ delete i->second;
+ }
+ v->clear();
+}
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
diff --git a/src/google/protobuf/stubs/stringprintf.cc b/src/google/protobuf/stubs/stringprintf.cc
new file mode 100644
index 0000000..3272d8e
--- /dev/null
+++ b/src/google/protobuf/stubs/stringprintf.cc
@@ -0,0 +1,175 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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.
+
+// from google3/base/stringprintf.cc
+
+#include <google/protobuf/stubs/stringprintf.h>
+
+#include <errno.h>
+#include <stdarg.h> // For va_list and related operations
+#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 {
+
+#ifdef _MSC_VER
+enum { IS_COMPILER_MSVC = 1 };
+#ifndef va_copy
+// Define va_copy for MSVC. This is a hack, assuming va_list is simply a
+// pointer into the stack and is safe to copy.
+#define va_copy(dest, src) ((dest) = (src))
+#endif
+#else
+enum { IS_COMPILER_MSVC = 0 };
+#endif
+
+void StringAppendV(string* dst, const char* format, va_list ap) {
+ // First try with a small fixed size buffer
+ static const int kSpaceLength = 1024;
+ char space[kSpaceLength];
+
+ // It's possible for methods that use a va_list to invalidate
+ // the data in it upon use. The fix is to make a copy
+ // of the structure before using it and use that copy instead.
+ va_list backup_ap;
+ va_copy(backup_ap, ap);
+ int result = vsnprintf(space, kSpaceLength, format, backup_ap);
+ va_end(backup_ap);
+
+ if (result < kSpaceLength) {
+ if (result >= 0) {
+ // Normal case -- everything fit.
+ dst->append(space, result);
+ return;
+ }
+
+ if (IS_COMPILER_MSVC) {
+ // Error or MSVC running out of space. MSVC 8.0 and higher
+ // can be asked about space needed with the special idiom below:
+ va_copy(backup_ap, ap);
+ result = vsnprintf(NULL, 0, format, backup_ap);
+ va_end(backup_ap);
+ }
+
+ if (result < 0) {
+ // Just an error.
+ return;
+ }
+ }
+
+ // Increase the buffer size to the size requested by vsnprintf,
+ // plus one for the closing \0.
+ int length = result+1;
+ char* buf = new char[length];
+
+ // Restore the va_list before we use it again
+ va_copy(backup_ap, ap);
+ result = vsnprintf(buf, length, format, backup_ap);
+ va_end(backup_ap);
+
+ if (result >= 0 && result < length) {
+ // It fit
+ dst->append(buf, result);
+ }
+ delete[] buf;
+}
+
+
+string StringPrintf(const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ string result;
+ StringAppendV(&result, format, ap);
+ va_end(ap);
+ return result;
+}
+
+const string& SStringPrintf(string* dst, const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ dst->clear();
+ StringAppendV(dst, format, ap);
+ va_end(ap);
+ return *dst;
+}
+
+void StringAppendF(string* dst, const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ StringAppendV(dst, format, ap);
+ va_end(ap);
+}
+
+// Max arguments supported by StringPrintVector
+const int kStringPrintfVectorMaxArgs = 32;
+
+// An empty block of zero for filler arguments. This is const so that if
+// printf tries to write to it (via %n) then the program gets a SIGSEGV
+// and we can fix the problem or protect against an attack.
+static const char string_printf_empty_block[256] = { '\0' };
+
+string StringPrintfVector(const char* format, const vector<string>& v) {
+ GOOGLE_CHECK_LE(v.size(), kStringPrintfVectorMaxArgs)
+ << "StringPrintfVector currently only supports up to "
+ << kStringPrintfVectorMaxArgs << " arguments. "
+ << "Feel free to add support for more if you need it.";
+
+ // Add filler arguments so that bogus format+args have a harder time
+ // crashing the program, corrupting the program (%n),
+ // or displaying random chunks of memory to users.
+
+ const char* cstr[kStringPrintfVectorMaxArgs];
+ for (int i = 0; i < v.size(); ++i) {
+ cstr[i] = v[i].c_str();
+ }
+ for (int i = v.size(); i < GOOGLE_ARRAYSIZE(cstr); ++i) {
+ cstr[i] = &string_printf_empty_block[0];
+ }
+
+ // I do not know any way to pass kStringPrintfVectorMaxArgs arguments,
+ // or any way to build a va_list by hand, or any API for printf
+ // that accepts an array of arguments. The best I can do is stick
+ // this COMPILE_ASSERT right next to the actual statement.
+
+ GOOGLE_COMPILE_ASSERT(kStringPrintfVectorMaxArgs == 32, arg_count_mismatch);
+ return StringPrintf(format,
+ cstr[0], cstr[1], cstr[2], cstr[3], cstr[4],
+ cstr[5], cstr[6], cstr[7], cstr[8], cstr[9],
+ cstr[10], cstr[11], cstr[12], cstr[13], cstr[14],
+ cstr[15], cstr[16], cstr[17], cstr[18], cstr[19],
+ cstr[20], cstr[21], cstr[22], cstr[23], cstr[24],
+ cstr[25], cstr[26], cstr[27], cstr[28], cstr[29],
+ cstr[30], cstr[31]);
+}
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/stubs/stringprintf.h b/src/google/protobuf/stubs/stringprintf.h
new file mode 100644
index 0000000..ab1ab55
--- /dev/null
+++ b/src/google/protobuf/stubs/stringprintf.h
@@ -0,0 +1,76 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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.
+
+// from google3/base/stringprintf.h
+//
+// Printf variants that place their output in a C++ string.
+//
+// Usage:
+// string result = StringPrintf("%d %s\n", 10, "hello");
+// SStringPrintf(&result, "%d %s\n", 10, "hello");
+// StringAppendF(&result, "%d %s\n", 20, "there");
+
+#ifndef GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H
+#define GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H
+
+#include <stdarg.h>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+// Return a C++ string
+LIBPROTOBUF_EXPORT extern string StringPrintf(const char* format, ...);
+
+// Store result into a supplied string and return it
+LIBPROTOBUF_EXPORT extern const string& SStringPrintf(string* dst, const char* format, ...);
+
+// Append result to a supplied string
+LIBPROTOBUF_EXPORT extern void StringAppendF(string* dst, const char* format, ...);
+
+// Lower-level routine that takes a va_list and appends to a specified
+// string. All other routines are just convenience wrappers around it.
+LIBPROTOBUF_EXPORT extern void StringAppendV(string* dst, const char* format, va_list ap);
+
+// The max arguments supported by StringPrintfVector
+LIBPROTOBUF_EXPORT extern const int kStringPrintfVectorMaxArgs;
+
+// You can use this version when all your arguments are strings, but
+// you don't know how many arguments you'll have at compile time.
+// StringPrintfVector will LOG(FATAL) if v.size() > kStringPrintfVectorMaxArgs
+LIBPROTOBUF_EXPORT extern string StringPrintfVector(const char* format, const vector<string>& v);
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H
diff --git a/src/google/protobuf/stubs/stringprintf_unittest.cc b/src/google/protobuf/stubs/stringprintf_unittest.cc
new file mode 100644
index 0000000..15895e5
--- /dev/null
+++ b/src/google/protobuf/stubs/stringprintf_unittest.cc
@@ -0,0 +1,152 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 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.
+
+// from google3/base/stringprintf_unittest.cc
+
+#include <google/protobuf/stubs/stringprintf.h>
+
+#include <cerrno>
+#include <string>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+TEST(StringPrintfTest, Empty) {
+#if 0
+ // gcc 2.95.3, gcc 4.1.0, and gcc 4.2.2 all warn about this:
+ // warning: zero-length printf format string.
+ // so we do not allow them in google3.
+ EXPECT_EQ("", StringPrintf(""));
+#endif
+ EXPECT_EQ("", StringPrintf("%s", string().c_str()));
+ EXPECT_EQ("", StringPrintf("%s", ""));
+}
+
+TEST(StringPrintfTest, Misc) {
+// MSVC and mingw does not support $ format specifier.
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+ EXPECT_EQ("123hello w", StringPrintf("%3$d%2$s %1$c", 'w', "hello", 123));
+#endif // !_MSC_VER
+}
+
+TEST(StringAppendFTest, Empty) {
+ string value("Hello");
+ const char* empty = "";
+ StringAppendF(&value, "%s", empty);
+ EXPECT_EQ("Hello", value);
+}
+
+TEST(StringAppendFTest, EmptyString) {
+ string value("Hello");
+ StringAppendF(&value, "%s", "");
+ EXPECT_EQ("Hello", value);
+}
+
+TEST(StringAppendFTest, String) {
+ string value("Hello");
+ StringAppendF(&value, " %s", "World");
+ EXPECT_EQ("Hello World", value);
+}
+
+TEST(StringAppendFTest, Int) {
+ string value("Hello");
+ StringAppendF(&value, " %d", 123);
+ EXPECT_EQ("Hello 123", value);
+}
+
+TEST(StringPrintfTest, Multibyte) {
+ // If we are in multibyte mode and feed invalid multibyte sequence,
+ // StringPrintf should return an empty string instead of running
+ // out of memory while trying to determine destination buffer size.
+ // see b/4194543.
+
+ char* old_locale = setlocale(LC_CTYPE, NULL);
+ // Push locale with multibyte mode
+ setlocale(LC_CTYPE, "en_US.utf8");
+
+ const char kInvalidCodePoint[] = "\375\067s";
+ string value = StringPrintf("%.*s", 3, kInvalidCodePoint);
+
+ // In some versions of glibc (e.g. eglibc-2.11.1, aka GRTEv2), snprintf
+ // returns error given an invalid codepoint. Other versions
+ // (e.g. eglibc-2.15, aka pre-GRTEv3) emit the codepoint verbatim.
+ // We test that the output is one of the above.
+ EXPECT_TRUE(value.empty() || value == kInvalidCodePoint);
+
+ // Repeat with longer string, to make sure that the dynamically
+ // allocated path in StringAppendV is handled correctly.
+ int n = 2048;
+ char* buf = new char[n+1];
+ memset(buf, ' ', n-3);
+ memcpy(buf + n - 3, kInvalidCodePoint, 4);
+ value = StringPrintf("%.*s", n, buf);
+ // See GRTEv2 vs. GRTEv3 comment above.
+ EXPECT_TRUE(value.empty() || value == buf);
+ delete[] buf;
+
+ setlocale(LC_CTYPE, old_locale);
+}
+
+TEST(StringPrintfTest, NoMultibyte) {
+ // No multibyte handling, but the string contains funny chars.
+ char* old_locale = setlocale(LC_CTYPE, NULL);
+ setlocale(LC_CTYPE, "POSIX");
+ string value = StringPrintf("%.*s", 3, "\375\067s");
+ setlocale(LC_CTYPE, old_locale);
+ EXPECT_EQ("\375\067s", value);
+}
+
+TEST(StringPrintfTest, DontOverwriteErrno) {
+ // Check that errno isn't overwritten unless we're printing
+ // something significantly larger than what people are normally
+ // printing in their badly written PLOG() statements.
+ errno = ECHILD;
+ string value = StringPrintf("Hello, %s!", "World");
+ EXPECT_EQ(ECHILD, errno);
+}
+
+TEST(StringPrintfTest, LargeBuf) {
+ // Check that the large buffer is handled correctly.
+ int n = 2048;
+ char* buf = new char[n+1];
+ memset(buf, ' ', n);
+ buf[n] = 0;
+ string value = StringPrintf("%s", buf);
+ EXPECT_EQ(buf, value);
+ delete[] buf;
+}
+
+} // anonymous namespace
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc
index bb658ba..a898259 100644
--- a/src/google/protobuf/stubs/strutil.cc
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -189,6 +189,44 @@ void SplitStringUsing(const string& full,
SplitStringToIteratorUsing(full, delim, it);
}
+// Split a string using a character delimiter. Append the components
+// to 'result'. If there are consecutive delimiters, this function
+// will return corresponding empty strings. The string is split into
+// at most the specified number of pieces greedily. This means that the
+// last piece may possibly be split further. To split into as many pieces
+// as possible, specify 0 as the number of pieces.
+//
+// If "full" is the empty string, yields an empty string as the only value.
+//
+// If "pieces" is negative for some reason, it returns the whole string
+// ----------------------------------------------------------------------
+template <typename StringType, typename ITR>
+static inline
+void SplitStringToIteratorAllowEmpty(const StringType& full,
+ const char* delim,
+ int pieces,
+ ITR& result) {
+ string::size_type begin_index, end_index;
+ begin_index = 0;
+
+ for (int i = 0; (i < pieces-1) || (pieces == 0); i++) {
+ end_index = full.find_first_of(delim, begin_index);
+ if (end_index == string::npos) {
+ *result++ = full.substr(begin_index);
+ return;
+ }
+ *result++ = full.substr(begin_index, (end_index - begin_index));
+ begin_index = end_index + 1;
+ }
+ *result++ = full.substr(begin_index);
+}
+
+void SplitStringAllowEmpty(const string& full, const char* delim,
+ vector<string>* result) {
+ back_insert_iterator<vector<string> > it(*result);
+ SplitStringToIteratorAllowEmpty(full, delim, 0, it);
+}
+
// ----------------------------------------------------------------------
// JoinStrings()
// This merges a vector of string components with delim inserted
@@ -558,6 +596,120 @@ uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) {
return static_cast<uint32>(result);
}
+inline bool safe_parse_sign(string* text /*inout*/,
+ bool* negative_ptr /*output*/) {
+ const char* start = text->data();
+ const char* end = start + text->size();
+
+ // Consume whitespace.
+ while (start < end && (start[0] == ' ')) {
+ ++start;
+ }
+ while (start < end && (end[-1] == ' ')) {
+ --end;
+ }
+ if (start >= end) {
+ return false;
+ }
+
+ // Consume sign.
+ *negative_ptr = (start[0] == '-');
+ if (*negative_ptr || start[0] == '+') {
+ ++start;
+ if (start >= end) {
+ return false;
+ }
+ }
+ *text = text->substr(start - text->data(), end - start);
+ return true;
+}
+
+inline bool safe_parse_positive_int(
+ string text, int32* value_p) {
+ int base = 10;
+ int32 value = 0;
+ const int32 vmax = std::numeric_limits<int32>::max();
+ assert(vmax > 0);
+ assert(vmax >= base);
+ const int32 vmax_over_base = vmax / base;
+ const char* start = text.data();
+ const char* end = start + text.size();
+ // loop over digits
+ for (; start < end; ++start) {
+ unsigned char c = static_cast<unsigned char>(start[0]);
+ int digit = c - '0';
+ if (digit >= base || digit < 0) {
+ *value_p = value;
+ return false;
+ }
+ if (value > vmax_over_base) {
+ *value_p = vmax;
+ return false;
+ }
+ value *= base;
+ if (value > vmax - digit) {
+ *value_p = vmax;
+ return false;
+ }
+ value += digit;
+ }
+ *value_p = value;
+ return true;
+}
+
+inline bool safe_parse_negative_int(
+ string text, int32* value_p) {
+ int base = 10;
+ int32 value = 0;
+ const int32 vmin = std::numeric_limits<int32>::min();
+ assert(vmin < 0);
+ assert(vmin <= 0 - base);
+ int32 vmin_over_base = vmin / base;
+ // 2003 c++ standard [expr.mul]
+ // "... the sign of the remainder is implementation-defined."
+ // Although (vmin/base)*base + vmin%base is always vmin.
+ // 2011 c++ standard tightens the spec but we cannot rely on it.
+ if (vmin % base > 0) {
+ vmin_over_base += 1;
+ }
+ const char* start = text.data();
+ const char* end = start + text.size();
+ // loop over digits
+ for (; start < end; ++start) {
+ unsigned char c = static_cast<unsigned char>(start[0]);
+ int digit = c - '0';
+ if (digit >= base || digit < 0) {
+ *value_p = value;
+ return false;
+ }
+ if (value < vmin_over_base) {
+ *value_p = vmin;
+ return false;
+ }
+ value *= base;
+ if (value < vmin + digit) {
+ *value_p = vmin;
+ return false;
+ }
+ value -= digit;
+ }
+ *value_p = value;
+ return true;
+}
+
+bool safe_int(string text, int32* value_p) {
+ *value_p = 0;
+ bool negative;
+ if (!safe_parse_sign(&text, &negative)) {
+ return false;
+ }
+ if (!negative) {
+ return safe_parse_positive_int(text, value_p);
+ } else {
+ return safe_parse_negative_int(text, value_p);
+ }
+}
+
// ----------------------------------------------------------------------
// FastIntToBuffer()
// FastInt64ToBuffer()
@@ -670,7 +822,14 @@ char *InternalFastHexToBuffer(uint64 value, char* buffer, int num_byte) {
static const char *hexdigits = "0123456789abcdef";
buffer[num_byte] = '\0';
for (int i = num_byte - 1; i >= 0; i--) {
+#ifdef _M_X64
+ // MSVC x64 platform has a bug optimizing the uint32(value) in the #else
+ // block. Given that the uint32 cast was to improve performance on 32-bit
+ // platforms, we use 64-bit '&' directly.
+ buffer[i] = hexdigits[value & 0xf];
+#else
buffer[i] = hexdigits[uint32(value) & 0xf];
+#endif
value >>= 4;
}
return buffer;
@@ -1098,68 +1257,22 @@ char* FloatToBuffer(float value, char* buffer) {
return buffer;
}
-// ----------------------------------------------------------------------
-// NoLocaleStrtod()
-// This code will make you cry.
-// ----------------------------------------------------------------------
-
-// Returns a string identical to *input except that the character pointed to
-// by radix_pos (which should be '.') is replaced with the locale-specific
-// radix character.
-string LocalizeRadix(const char* input, const char* radix_pos) {
- // Determine the locale-specific radix character by calling sprintf() to
- // print the number 1.5, then stripping off the digits. As far as I can
- // tell, this is the only portable, thread-safe way to get the C library
- // to divuldge the locale's radix character. No, localeconv() is NOT
- // thread-safe.
- char temp[16];
- int size = sprintf(temp, "%.1f", 1.5);
- GOOGLE_CHECK_EQ(temp[0], '1');
- GOOGLE_CHECK_EQ(temp[size-1], '5');
- GOOGLE_CHECK_LE(size, 6);
-
- // Now replace the '.' in the input with it.
- string result;
- result.reserve(strlen(input) + size - 3);
- result.append(input, radix_pos);
- result.append(temp + 1, size - 2);
- result.append(radix_pos + 1);
- return result;
-}
+string ToHex(uint64 num) {
+ if (num == 0) {
+ return string("0");
+ }
-double NoLocaleStrtod(const char* text, char** original_endptr) {
- // We cannot simply set the locale to "C" temporarily with setlocale()
- // as this is not thread-safe. Instead, we try to parse in the current
- // locale first. If parsing stops at a '.' character, then this is a
- // pretty good hint that we're actually in some other locale in which
- // '.' is not the radix character.
-
- char* temp_endptr;
- double result = strtod(text, &temp_endptr);
- if (original_endptr != NULL) *original_endptr = temp_endptr;
- if (*temp_endptr != '.') return result;
-
- // Parsing halted on a '.'. Perhaps we're in a different locale? Let's
- // try to replace the '.' with a locale-specific radix character and
- // try again.
- string localized = LocalizeRadix(text, temp_endptr);
- const char* localized_cstr = localized.c_str();
- char* localized_endptr;
- result = strtod(localized_cstr, &localized_endptr);
- if ((localized_endptr - localized_cstr) >
- (temp_endptr - text)) {
- // This attempt got further, so replacing the decimal must have helped.
- // Update original_endptr to point at the right location.
- if (original_endptr != NULL) {
- // size_diff is non-zero if the localized radix has multiple bytes.
- int size_diff = localized.size() - strlen(text);
- // const_cast is necessary to match the strtod() interface.
- *original_endptr = const_cast<char*>(
- text + (localized_endptr - localized_cstr - size_diff));
- }
+ // Compute hex bytes in reverse order, writing to the back of the
+ // buffer.
+ char buf[16]; // No more than 16 hex digits needed.
+ char* bufptr = buf + 16;
+ static const char kHexChars[] = "0123456789abcdef";
+ while (num != 0) {
+ *--bufptr = kHexChars[num & 0xf];
+ num >>= 4;
}
- return result;
+ return string(bufptr, buf + 16 - bufptr);
}
} // namespace protobuf
diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h
index 777694b..4178ac9 100644
--- a/src/google/protobuf/stubs/strutil.h
+++ b/src/google/protobuf/stubs/strutil.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -126,6 +126,7 @@ LIBPROTOBUF_EXPORT void StripString(string* s, const char* remove,
// ----------------------------------------------------------------------
// LowerString()
// UpperString()
+// ToUpper()
// Convert the characters in "s" to lowercase or uppercase. ASCII-only:
// these functions intentionally ignore locale because they are applied to
// identifiers used in the Protocol Buffer language, not to natural-language
@@ -148,6 +149,12 @@ inline void UpperString(string * s) {
}
}
+inline string ToUpper(const string& s) {
+ string out = s;
+ UpperString(&out);
+ return out;
+}
+
// ----------------------------------------------------------------------
// StringReplace()
// Give me a string and two patterns "old" and "new", and I replace
@@ -168,6 +175,33 @@ LIBPROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub,
LIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim,
vector<string>* res);
+// Split a string using one or more byte delimiters, presented
+// as a nul-terminated c string. Append the components to 'result'.
+// If there are consecutive delimiters, this function will return
+// corresponding empty strings. If you want to drop the empty
+// strings, try SplitStringUsing().
+//
+// If "full" is the empty string, yields an empty string as the only value.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT void SplitStringAllowEmpty(const string& full,
+ const char* delim,
+ vector<string>* result);
+
+// ----------------------------------------------------------------------
+// Split()
+// Split a string using a character delimiter.
+// ----------------------------------------------------------------------
+inline vector<string> Split(
+ const string& full, const char* delim, bool skip_empty = true) {
+ vector<string> result;
+ if (skip_empty) {
+ SplitStringUsing(full, delim, &result);
+ } else {
+ SplitStringAllowEmpty(full, delim, &result);
+ }
+ return result;
+}
+
// ----------------------------------------------------------------------
// JoinStrings()
// These methods concatenate a vector of strings into a C++ string, using
@@ -207,9 +241,7 @@ inline string JoinStrings(const vector<string>& components,
// hex digits, upper or lower case) to specify a Unicode code
// point. The dest array will contain the UTF8-encoded version of
// that code-point (e.g., if source contains \u2019, then dest will
-// contain the three bytes 0xE2, 0x80, and 0x99). For the inverse
-// transformation, use UniLib::UTF8EscapeString
-// (util/utf8/unilib.h), not CEscapeString.
+// contain the three bytes 0xE2, 0x80, and 0x99).
//
// Errors: In the first form of the call, errors are reported with
// LOG(ERROR). The same is true for the second form of the call if
@@ -317,6 +349,15 @@ inline uint64 strtou64(const char *nptr, char **endptr, int base) {
}
// ----------------------------------------------------------------------
+// safe_strto32()
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT bool safe_int(string text, int32* value_p);
+
+inline bool safe_strto32(string text, int32* value) {
+ return safe_int(text, value);
+}
+
+// ----------------------------------------------------------------------
// FastIntToBuffer()
// FastHexToBuffer()
// FastHex64ToBuffer()
@@ -444,16 +485,78 @@ static const int kDoubleToBufferSize = 32;
static const int kFloatToBufferSize = 24;
// ----------------------------------------------------------------------
-// NoLocaleStrtod()
-// Exactly like strtod(), except it always behaves as if in the "C"
-// locale (i.e. decimal points must be '.'s).
+// ToString() are internal help methods used in StrCat() and Join()
// ----------------------------------------------------------------------
+namespace internal {
+inline string ToString(int i) {
+ return SimpleItoa(i);
+}
-LIBPROTOBUF_EXPORT double NoLocaleStrtod(const char* text, char** endptr);
+inline string ToString(string a) {
+ return a;
+}
+} // namespace internal
+
+// ----------------------------------------------------------------------
+// StrCat()
+// These methods join some strings together.
+// ----------------------------------------------------------------------
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+string StrCat(
+ const T1& a, const T2& b, const T3& c, const T4& d, const T5& e) {
+ return internal::ToString(a) + internal::ToString(b) +
+ internal::ToString(c) + internal::ToString(d) + internal::ToString(e);
+}
+
+template <typename T1, typename T2, typename T3, typename T4>
+string StrCat(
+ const T1& a, const T2& b, const T3& c, const T4& d) {
+ return internal::ToString(a) + internal::ToString(b) +
+ internal::ToString(c) + internal::ToString(d);
+}
+
+template <typename T1, typename T2, typename T3>
+string StrCat(const T1& a, const T2& b, const T3& c) {
+ return internal::ToString(a) + internal::ToString(b) +
+ internal::ToString(c);
+}
+
+template <typename T1, typename T2>
+string StrCat(const T1& a, const T2& b) {
+ return internal::ToString(a) + internal::ToString(b);
+}
+
+// ----------------------------------------------------------------------
+// Join()
+// These methods concatenate a range of components into a C++ string, using
+// the C-string "delim" as a separator between components.
+// ----------------------------------------------------------------------
+template <typename Iterator>
+void Join(Iterator start, Iterator end,
+ const char* delim, string* result) {
+ for (Iterator it = start; it != end; ++it) {
+ if (it != start) {
+ result->append(delim);
+ }
+ result->append(internal::ToString(*it));
+ }
+}
+
+template <typename Range>
+string Join(const Range& components,
+ const char* delim) {
+ string result;
+ Join(components.begin(), components.end(), delim, &result);
+ return result;
+}
+
+// ----------------------------------------------------------------------
+// ToHex()
+// Return a lower-case hex string representation of the given integer.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT string ToHex(uint64 num);
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
-
-
diff --git a/src/google/protobuf/stubs/strutil_unittest.cc b/src/google/protobuf/stubs/strutil_unittest.cc
index b9c9253..7f27dca 100644
--- a/src/google/protobuf/stubs/strutil_unittest.cc
+++ b/src/google/protobuf/stubs/strutil_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -51,27 +51,17 @@ TEST(StringUtilityTest, ImmuneToLocales) {
// Set the locale to "C".
ASSERT_TRUE(setlocale(LC_NUMERIC, "C") != NULL);
- EXPECT_EQ(1.5, NoLocaleStrtod("1.5", NULL));
EXPECT_EQ("1.5", SimpleDtoa(1.5));
EXPECT_EQ("1.5", SimpleFtoa(1.5));
- // Verify that the endptr is set correctly even if not all text was parsed.
- const char* text = "1.5f";
- char* endptr;
- EXPECT_EQ(1.5, NoLocaleStrtod(text, &endptr));
- EXPECT_EQ(3, endptr - text);
-
if (setlocale(LC_NUMERIC, "es_ES") == NULL &&
setlocale(LC_NUMERIC, "es_ES.utf8") == NULL) {
// Some systems may not have the desired locale available.
GOOGLE_LOG(WARNING)
<< "Couldn't set locale to es_ES. Skipping this test.";
} else {
- EXPECT_EQ(1.5, NoLocaleStrtod("1.5", NULL));
EXPECT_EQ("1.5", SimpleDtoa(1.5));
EXPECT_EQ("1.5", SimpleFtoa(1.5));
- EXPECT_EQ(1.5, NoLocaleStrtod(text, &endptr));
- EXPECT_EQ(3, endptr - text);
}
// Return to original locale.
diff --git a/src/google/protobuf/stubs/substitute.cc b/src/google/protobuf/stubs/substitute.cc
index b542aaa..c9d9589 100644
--- a/src/google/protobuf/stubs/substitute.cc
+++ b/src/google/protobuf/stubs/substitute.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,7 +32,7 @@
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/stubs/substitute.h b/src/google/protobuf/stubs/substitute.h
index 2581793..7ee442a 100644
--- a/src/google/protobuf/stubs/substitute.h
+++ b/src/google/protobuf/stubs/substitute.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/stubs/template_util.h b/src/google/protobuf/stubs/template_util.h
new file mode 100644
index 0000000..4f30ffa
--- /dev/null
+++ b/src/google/protobuf/stubs/template_util.h
@@ -0,0 +1,138 @@
+// Copyright 2005 Google Inc.
+// All rights reserved.
+//
+// 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: lar@google.com (Laramie Leavitt)
+//
+// Template metaprogramming utility functions.
+//
+// This code is compiled directly on many platforms, including client
+// platforms like Windows, Mac, and embedded systems. Before making
+// any changes here, make sure that you're not breaking any platforms.
+//
+//
+// The names choosen here reflect those used in tr1 and the boost::mpl
+// library, there are similar operations used in the Loki library as
+// well. I prefer the boost names for 2 reasons:
+// 1. I think that portions of the Boost libraries are more likely to
+// be included in the c++ standard.
+// 2. It is not impossible that some of the boost libraries will be
+// included in our own build in the future.
+// Both of these outcomes means that we may be able to directly replace
+// some of these with boost equivalents.
+//
+#ifndef GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
+#define GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Types small_ and big_ are guaranteed such that sizeof(small_) <
+// sizeof(big_)
+typedef char small_;
+
+struct big_ {
+ char dummy[2];
+};
+
+// Identity metafunction.
+template <class T>
+struct identity_ {
+ typedef T type;
+};
+
+// integral_constant, defined in tr1, is a wrapper for an integer
+// value. We don't really need this generality; we could get away
+// with hardcoding the integer type to bool. We use the fully
+// general integer_constant for compatibility with tr1.
+
+template<class T, T v>
+struct integral_constant {
+ static const T value = v;
+ typedef T value_type;
+ typedef integral_constant<T, v> type;
+};
+
+template <class T, T v> const T integral_constant<T, v>::value;
+
+
+// Abbreviations: true_type and false_type are structs that represent boolean
+// true and false values. Also define the boost::mpl versions of those names,
+// true_ and false_.
+typedef integral_constant<bool, true> true_type;
+typedef integral_constant<bool, false> false_type;
+typedef true_type true_;
+typedef false_type false_;
+
+// if_ is a templatized conditional statement.
+// if_<cond, A, B> is a compile time evaluation of cond.
+// if_<>::type contains A if cond is true, B otherwise.
+template<bool cond, typename A, typename B>
+struct if_{
+ typedef A type;
+};
+
+template<typename A, typename B>
+struct if_<false, A, B> {
+ typedef B type;
+};
+
+
+// type_equals_ is a template type comparator, similar to Loki IsSameType.
+// type_equals_<A, B>::value is true iff "A" is the same type as "B".
+//
+// New code should prefer base::is_same, defined in base/type_traits.h.
+// It is functionally identical, but is_same is the standard spelling.
+template<typename A, typename B>
+struct type_equals_ : public false_ {
+};
+
+template<typename A>
+struct type_equals_<A, A> : public true_ {
+};
+
+// and_ is a template && operator.
+// and_<A, B>::value evaluates "A::value && B::value".
+template<typename A, typename B>
+struct and_ : public integral_constant<bool, (A::value && B::value)> {
+};
+
+// or_ is a template || operator.
+// or_<A, B>::value evaluates "A::value || B::value".
+template<typename A, typename B>
+struct or_ : public integral_constant<bool, (A::value || B::value)> {
+};
+
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
diff --git a/src/google/protobuf/stubs/template_util_unittest.cc b/src/google/protobuf/stubs/template_util_unittest.cc
new file mode 100644
index 0000000..b1745e2
--- /dev/null
+++ b/src/google/protobuf/stubs/template_util_unittest.cc
@@ -0,0 +1,130 @@
+// Copyright 2005 Google Inc.
+// All rights reserved.
+//
+// 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: lar@google.com (Laramie Leavitt)
+//
+// These tests are really compile time tests.
+// If you try to step through this in a debugger
+// you will not see any evaluations, merely that
+// value is assigned true or false sequentially.
+
+#include <google/protobuf/stubs/template_util.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace GOOGLE_NAMESPACE = google::protobuf::internal;
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST(TemplateUtilTest, TestSize) {
+ EXPECT_GT(sizeof(GOOGLE_NAMESPACE::big_), sizeof(GOOGLE_NAMESPACE::small_));
+}
+
+TEST(TemplateUtilTest, TestIntegralConstants) {
+ // test the built-in types.
+ EXPECT_TRUE(true_type::value);
+ EXPECT_FALSE(false_type::value);
+
+ typedef integral_constant<int, 1> one_type;
+ EXPECT_EQ(1, one_type::value);
+}
+
+TEST(TemplateUtilTest, TestTemplateIf) {
+ typedef if_<true, true_type, false_type>::type if_true;
+ EXPECT_TRUE(if_true::value);
+
+ typedef if_<false, true_type, false_type>::type if_false;
+ EXPECT_FALSE(if_false::value);
+}
+
+TEST(TemplateUtilTest, TestTemplateTypeEquals) {
+ // Check that the TemplateTypeEquals works correctly.
+ bool value = false;
+
+ // Test the same type is true.
+ value = type_equals_<int, int>::value;
+ EXPECT_TRUE(value);
+
+ // Test different types are false.
+ value = type_equals_<float, int>::value;
+ EXPECT_FALSE(value);
+
+ // Test type aliasing.
+ typedef const int foo;
+ value = type_equals_<const foo, const int>::value;
+ EXPECT_TRUE(value);
+}
+
+TEST(TemplateUtilTest, TestTemplateAndOr) {
+ // Check that the TemplateTypeEquals works correctly.
+ bool value = false;
+
+ // Yes && Yes == true.
+ value = and_<true_, true_>::value;
+ EXPECT_TRUE(value);
+ // Yes && No == false.
+ value = and_<true_, false_>::value;
+ EXPECT_FALSE(value);
+ // No && Yes == false.
+ value = and_<false_, true_>::value;
+ EXPECT_FALSE(value);
+ // No && No == false.
+ value = and_<false_, false_>::value;
+ EXPECT_FALSE(value);
+
+ // Yes || Yes == true.
+ value = or_<true_, true_>::value;
+ EXPECT_TRUE(value);
+ // Yes || No == true.
+ value = or_<true_, false_>::value;
+ EXPECT_TRUE(value);
+ // No || Yes == true.
+ value = or_<false_, true_>::value;
+ EXPECT_TRUE(value);
+ // No || No == false.
+ value = or_<false_, false_>::value;
+ EXPECT_FALSE(value);
+}
+
+TEST(TemplateUtilTest, TestIdentity) {
+ EXPECT_TRUE(
+ (type_equals_<GOOGLE_NAMESPACE::identity_<int>::type, int>::value));
+ EXPECT_TRUE(
+ (type_equals_<GOOGLE_NAMESPACE::identity_<void>::type, void>::value));
+}
+
+} // anonymous namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/stubs/type_traits.h b/src/google/protobuf/stubs/type_traits.h
new file mode 100644
index 0000000..e41f5e6
--- /dev/null
+++ b/src/google/protobuf/stubs/type_traits.h
@@ -0,0 +1,336 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// 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: Matt Austern
+//
+// This code is compiled directly on many platforms, including client
+// platforms like Windows, Mac, and embedded systems. Before making
+// any changes here, make sure that you're not breaking any platforms.
+//
+// Define a small subset of tr1 type traits. The traits we define are:
+// is_integral
+// is_floating_point
+// is_pointer
+// is_enum
+// is_reference
+// is_pod
+// has_trivial_constructor
+// has_trivial_copy
+// has_trivial_assign
+// has_trivial_destructor
+// remove_const
+// remove_volatile
+// remove_cv
+// remove_reference
+// add_reference
+// remove_pointer
+// is_same
+// is_convertible
+// We can add more type traits as required.
+
+#ifndef GOOGLE_PROTOBUF_TYPE_TRAITS_H_
+#define GOOGLE_PROTOBUF_TYPE_TRAITS_H_
+
+#include <utility> // For pair
+
+#include <google/protobuf/stubs/template_util.h> // For true_type and false_type
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+template <class T> struct is_integral;
+template <class T> struct is_floating_point;
+template <class T> struct is_pointer;
+// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least)
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+// is_enum uses is_convertible, which is not available on MSVC.
+template <class T> struct is_enum;
+#endif
+template <class T> struct is_reference;
+template <class T> struct is_pod;
+template <class T> struct has_trivial_constructor;
+template <class T> struct has_trivial_copy;
+template <class T> struct has_trivial_assign;
+template <class T> struct has_trivial_destructor;
+template <class T> struct remove_const;
+template <class T> struct remove_volatile;
+template <class T> struct remove_cv;
+template <class T> struct remove_reference;
+template <class T> struct add_reference;
+template <class T> struct remove_pointer;
+template <class T, class U> struct is_same;
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+template <class From, class To> struct is_convertible;
+#endif
+
+// is_integral is false except for the built-in integer types. A
+// cv-qualified type is integral if and only if the underlying type is.
+template <class T> struct is_integral : false_type { };
+template<> struct is_integral<bool> : true_type { };
+template<> struct is_integral<char> : true_type { };
+template<> struct is_integral<unsigned char> : true_type { };
+template<> struct is_integral<signed char> : true_type { };
+#if defined(_MSC_VER)
+// wchar_t is not by default a distinct type from unsigned short in
+// Microsoft C.
+// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx
+template<> struct is_integral<__wchar_t> : true_type { };
+#else
+template<> struct is_integral<wchar_t> : true_type { };
+#endif
+template<> struct is_integral<short> : true_type { };
+template<> struct is_integral<unsigned short> : true_type { };
+template<> struct is_integral<int> : true_type { };
+template<> struct is_integral<unsigned int> : true_type { };
+template<> struct is_integral<long> : true_type { };
+template<> struct is_integral<unsigned long> : true_type { };
+#ifdef HAVE_LONG_LONG
+template<> struct is_integral<long long> : true_type { };
+template<> struct is_integral<unsigned long long> : true_type { };
+#endif
+template <class T> struct is_integral<const T> : is_integral<T> { };
+template <class T> struct is_integral<volatile T> : is_integral<T> { };
+template <class T> struct is_integral<const volatile T> : is_integral<T> { };
+
+// is_floating_point is false except for the built-in floating-point types.
+// A cv-qualified type is integral if and only if the underlying type is.
+template <class T> struct is_floating_point : false_type { };
+template<> struct is_floating_point<float> : true_type { };
+template<> struct is_floating_point<double> : true_type { };
+template<> struct is_floating_point<long double> : true_type { };
+template <class T> struct is_floating_point<const T>
+ : is_floating_point<T> { };
+template <class T> struct is_floating_point<volatile T>
+ : is_floating_point<T> { };
+template <class T> struct is_floating_point<const volatile T>
+ : is_floating_point<T> { };
+
+// is_pointer is false except for pointer types. A cv-qualified type (e.g.
+// "int* const", as opposed to "int const*") is cv-qualified if and only if
+// the underlying type is.
+template <class T> struct is_pointer : false_type { };
+template <class T> struct is_pointer<T*> : true_type { };
+template <class T> struct is_pointer<const T> : is_pointer<T> { };
+template <class T> struct is_pointer<volatile T> : is_pointer<T> { };
+template <class T> struct is_pointer<const volatile T> : is_pointer<T> { };
+
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+
+namespace internal {
+
+template <class T> struct is_class_or_union {
+ template <class U> static small_ tester(void (U::*)());
+ template <class U> static big_ tester(...);
+ static const bool value = sizeof(tester<T>(0)) == sizeof(small_);
+};
+
+// is_convertible chokes if the first argument is an array. That's why
+// we use add_reference here.
+template <bool NotUnum, class T> struct is_enum_impl
+ : is_convertible<typename add_reference<T>::type, int> { };
+
+template <class T> struct is_enum_impl<true, T> : false_type { };
+
+} // namespace internal
+
+// Specified by TR1 [4.5.1] primary type categories.
+
+// Implementation note:
+//
+// Each type is either void, integral, floating point, array, pointer,
+// reference, member object pointer, member function pointer, enum,
+// union or class. Out of these, only integral, floating point, reference,
+// class and enum types are potentially convertible to int. Therefore,
+// if a type is not a reference, integral, floating point or class and
+// is convertible to int, it's a enum. Adding cv-qualification to a type
+// does not change whether it's an enum.
+//
+// Is-convertible-to-int check is done only if all other checks pass,
+// because it can't be used with some types (e.g. void or classes with
+// inaccessible conversion operators).
+template <class T> struct is_enum
+ : internal::is_enum_impl<
+ is_same<T, void>::value ||
+ is_integral<T>::value ||
+ is_floating_point<T>::value ||
+ is_reference<T>::value ||
+ internal::is_class_or_union<T>::value,
+ T> { };
+
+template <class T> struct is_enum<const T> : is_enum<T> { };
+template <class T> struct is_enum<volatile T> : is_enum<T> { };
+template <class T> struct is_enum<const volatile T> : is_enum<T> { };
+
+#endif
+
+// is_reference is false except for reference types.
+template<typename T> struct is_reference : false_type {};
+template<typename T> struct is_reference<T&> : true_type {};
+
+
+// We can't get is_pod right without compiler help, so fail conservatively.
+// We will assume it's false except for arithmetic types, enumerations,
+// pointers and cv-qualified versions thereof. Note that std::pair<T,U>
+// is not a POD even if T and U are PODs.
+template <class T> struct is_pod
+ : integral_constant<bool, (is_integral<T>::value ||
+ is_floating_point<T>::value ||
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+ // is_enum is not available on MSVC.
+ is_enum<T>::value ||
+#endif
+ is_pointer<T>::value)> { };
+template <class T> struct is_pod<const T> : is_pod<T> { };
+template <class T> struct is_pod<volatile T> : is_pod<T> { };
+template <class T> struct is_pod<const volatile T> : is_pod<T> { };
+
+
+// We can't get has_trivial_constructor right without compiler help, so
+// fail conservatively. We will assume it's false except for: (1) types
+// for which is_pod is true. (2) std::pair of types with trivial
+// constructors. (3) array of a type with a trivial constructor.
+// (4) const versions thereof.
+template <class T> struct has_trivial_constructor : is_pod<T> { };
+template <class T, class U> struct has_trivial_constructor<std::pair<T, U> >
+ : integral_constant<bool,
+ (has_trivial_constructor<T>::value &&
+ has_trivial_constructor<U>::value)> { };
+template <class A, int N> struct has_trivial_constructor<A[N]>
+ : has_trivial_constructor<A> { };
+template <class T> struct has_trivial_constructor<const T>
+ : has_trivial_constructor<T> { };
+
+// We can't get has_trivial_copy right without compiler help, so fail
+// conservatively. We will assume it's false except for: (1) types
+// for which is_pod is true. (2) std::pair of types with trivial copy
+// constructors. (3) array of a type with a trivial copy constructor.
+// (4) const versions thereof.
+template <class T> struct has_trivial_copy : is_pod<T> { };
+template <class T, class U> struct has_trivial_copy<std::pair<T, U> >
+ : integral_constant<bool,
+ (has_trivial_copy<T>::value &&
+ has_trivial_copy<U>::value)> { };
+template <class A, int N> struct has_trivial_copy<A[N]>
+ : has_trivial_copy<A> { };
+template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { };
+
+// We can't get has_trivial_assign right without compiler help, so fail
+// conservatively. We will assume it's false except for: (1) types
+// for which is_pod is true. (2) std::pair of types with trivial copy
+// constructors. (3) array of a type with a trivial assign constructor.
+template <class T> struct has_trivial_assign : is_pod<T> { };
+template <class T, class U> struct has_trivial_assign<std::pair<T, U> >
+ : integral_constant<bool,
+ (has_trivial_assign<T>::value &&
+ has_trivial_assign<U>::value)> { };
+template <class A, int N> struct has_trivial_assign<A[N]>
+ : has_trivial_assign<A> { };
+
+// We can't get has_trivial_destructor right without compiler help, so
+// fail conservatively. We will assume it's false except for: (1) types
+// for which is_pod is true. (2) std::pair of types with trivial
+// destructors. (3) array of a type with a trivial destructor.
+// (4) const versions thereof.
+template <class T> struct has_trivial_destructor : is_pod<T> { };
+template <class T, class U> struct has_trivial_destructor<std::pair<T, U> >
+ : integral_constant<bool,
+ (has_trivial_destructor<T>::value &&
+ has_trivial_destructor<U>::value)> { };
+template <class A, int N> struct has_trivial_destructor<A[N]>
+ : has_trivial_destructor<A> { };
+template <class T> struct has_trivial_destructor<const T>
+ : has_trivial_destructor<T> { };
+
+// Specified by TR1 [4.7.1]
+template<typename T> struct remove_const { typedef T type; };
+template<typename T> struct remove_const<T const> { typedef T type; };
+template<typename T> struct remove_volatile { typedef T type; };
+template<typename T> struct remove_volatile<T volatile> { typedef T type; };
+template<typename T> struct remove_cv {
+ typedef typename remove_const<typename remove_volatile<T>::type>::type type;
+};
+
+
+// Specified by TR1 [4.7.2] Reference modifications.
+template<typename T> struct remove_reference { typedef T type; };
+template<typename T> struct remove_reference<T&> { typedef T type; };
+
+template <typename T> struct add_reference { typedef T& type; };
+template <typename T> struct add_reference<T&> { typedef T& type; };
+
+// Specified by TR1 [4.7.4] Pointer modifications.
+template<typename T> struct remove_pointer { typedef T type; };
+template<typename T> struct remove_pointer<T*> { typedef T type; };
+template<typename T> struct remove_pointer<T* const> { typedef T type; };
+template<typename T> struct remove_pointer<T* volatile> { typedef T type; };
+template<typename T> struct remove_pointer<T* const volatile> {
+ typedef T type; };
+
+// Specified by TR1 [4.6] Relationships between types
+template<typename T, typename U> struct is_same : public false_type { };
+template<typename T> struct is_same<T, T> : public true_type { };
+
+// Specified by TR1 [4.6] Relationships between types
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+namespace internal {
+
+// This class is an implementation detail for is_convertible, and you
+// don't need to know how it works to use is_convertible. For those
+// who care: we declare two different functions, one whose argument is
+// of type To and one with a variadic argument list. We give them
+// return types of different size, so we can use sizeof to trick the
+// compiler into telling us which function it would have chosen if we
+// had called it with an argument of type From. See Alexandrescu's
+// _Modern C++ Design_ for more details on this sort of trick.
+
+template <typename From, typename To>
+struct ConvertHelper {
+ static small_ Test(To);
+ static big_ Test(...);
+ static From Create();
+};
+} // namespace internal
+
+// Inherits from true_type if From is convertible to To, false_type otherwise.
+template <typename From, typename To>
+struct is_convertible
+ : integral_constant<bool,
+ sizeof(internal::ConvertHelper<From, To>::Test(
+ internal::ConvertHelper<From, To>::Create()))
+ == sizeof(small_)> {
+};
+#endif
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_TYPE_TRAITS_H_
diff --git a/src/google/protobuf/stubs/type_traits_unittest.cc b/src/google/protobuf/stubs/type_traits_unittest.cc
new file mode 100644
index 0000000..7a8cbfb
--- /dev/null
+++ b/src/google/protobuf/stubs/type_traits_unittest.cc
@@ -0,0 +1,628 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// 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: Matt Austern
+
+#include <google/protobuf/stubs/type_traits.h>
+
+#include <stdlib.h> // for exit()
+#include <stdio.h>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+typedef int int32;
+typedef long int64;
+
+using std::string;
+using std::vector;
+using std::pair;
+
+
+// This assertion produces errors like "error: invalid use of
+// incomplete type 'struct <unnamed>::AssertTypesEq<const int, int>'"
+// when it fails.
+template<typename T, typename U> struct AssertTypesEq;
+template<typename T> struct AssertTypesEq<T, T> {};
+#define COMPILE_ASSERT_TYPES_EQ(T, U) static_cast<void>(AssertTypesEq<T, U>())
+
+// A user-defined POD type.
+struct A {
+ int n_;
+};
+
+// A user-defined non-POD type with a trivial copy constructor.
+class B {
+ public:
+ explicit B(int n) : n_(n) { }
+ private:
+ int n_;
+};
+
+// Another user-defined non-POD type with a trivial copy constructor.
+// We will explicitly declare C to have a trivial copy constructor
+// by specializing has_trivial_copy.
+class C {
+ public:
+ explicit C(int n) : n_(n) { }
+ private:
+ int n_;
+};
+
+namespace google {
+namespace protobuf {
+namespace internal {
+template<> struct has_trivial_copy<C> : true_type { };
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+// Another user-defined non-POD type with a trivial assignment operator.
+// We will explicitly declare C to have a trivial assignment operator
+// by specializing has_trivial_assign.
+class D {
+ public:
+ explicit D(int n) : n_(n) { }
+ private:
+ int n_;
+};
+
+namespace google {
+namespace protobuf {
+namespace internal {
+template<> struct has_trivial_assign<D> : true_type { };
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+// Another user-defined non-POD type with a trivial constructor.
+// We will explicitly declare E to have a trivial constructor
+// by specializing has_trivial_constructor.
+class E {
+ public:
+ int n_;
+};
+
+namespace google {
+namespace protobuf {
+namespace internal {
+template<> struct has_trivial_constructor<E> : true_type { };
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+// Another user-defined non-POD type with a trivial destructor.
+// We will explicitly declare E to have a trivial destructor
+// by specializing has_trivial_destructor.
+class F {
+ public:
+ explicit F(int n) : n_(n) { }
+ private:
+ int n_;
+};
+
+namespace google {
+namespace protobuf {
+namespace internal {
+template<> struct has_trivial_destructor<F> : true_type { };
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+enum G {};
+
+union H {};
+
+class I {
+ public:
+ operator int() const;
+};
+
+class J {
+ private:
+ operator int() const;
+};
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+// A base class and a derived class that inherits from it, used for
+// testing conversion type traits.
+class Base {
+ public:
+ virtual ~Base() { }
+};
+
+class Derived : public Base {
+};
+
+TEST(TypeTraitsTest, TestIsInteger) {
+ // Verify that is_integral is true for all integer types.
+ EXPECT_TRUE(is_integral<bool>::value);
+ EXPECT_TRUE(is_integral<char>::value);
+ EXPECT_TRUE(is_integral<unsigned char>::value);
+ EXPECT_TRUE(is_integral<signed char>::value);
+ EXPECT_TRUE(is_integral<wchar_t>::value);
+ EXPECT_TRUE(is_integral<int>::value);
+ EXPECT_TRUE(is_integral<unsigned int>::value);
+ EXPECT_TRUE(is_integral<short>::value);
+ EXPECT_TRUE(is_integral<unsigned short>::value);
+ EXPECT_TRUE(is_integral<long>::value);
+ EXPECT_TRUE(is_integral<unsigned long>::value);
+
+ // Verify that is_integral is false for a few non-integer types.
+ EXPECT_FALSE(is_integral<void>::value);
+ EXPECT_FALSE(is_integral<float>::value);
+ EXPECT_FALSE(is_integral<string>::value);
+ EXPECT_FALSE(is_integral<int*>::value);
+ EXPECT_FALSE(is_integral<A>::value);
+ EXPECT_FALSE((is_integral<pair<int, int> >::value));
+
+ // Verify that cv-qualified integral types are still integral, and
+ // cv-qualified non-integral types are still non-integral.
+ EXPECT_TRUE(is_integral<const char>::value);
+ EXPECT_TRUE(is_integral<volatile bool>::value);
+ EXPECT_TRUE(is_integral<const volatile unsigned int>::value);
+ EXPECT_FALSE(is_integral<const float>::value);
+ EXPECT_FALSE(is_integral<int* volatile>::value);
+ EXPECT_FALSE(is_integral<const volatile string>::value);
+}
+
+TEST(TypeTraitsTest, TestIsFloating) {
+ // Verify that is_floating_point is true for all floating-point types.
+ EXPECT_TRUE(is_floating_point<float>::value);
+ EXPECT_TRUE(is_floating_point<double>::value);
+ EXPECT_TRUE(is_floating_point<long double>::value);
+
+ // Verify that is_floating_point is false for a few non-float types.
+ EXPECT_FALSE(is_floating_point<void>::value);
+ EXPECT_FALSE(is_floating_point<long>::value);
+ EXPECT_FALSE(is_floating_point<string>::value);
+ EXPECT_FALSE(is_floating_point<float*>::value);
+ EXPECT_FALSE(is_floating_point<A>::value);
+ EXPECT_FALSE((is_floating_point<pair<int, int> >::value));
+
+ // Verify that cv-qualified floating point types are still floating, and
+ // cv-qualified non-floating types are still non-floating.
+ EXPECT_TRUE(is_floating_point<const float>::value);
+ EXPECT_TRUE(is_floating_point<volatile double>::value);
+ EXPECT_TRUE(is_floating_point<const volatile long double>::value);
+ EXPECT_FALSE(is_floating_point<const int>::value);
+ EXPECT_FALSE(is_floating_point<volatile string>::value);
+ EXPECT_FALSE(is_floating_point<const volatile char>::value);
+}
+
+TEST(TypeTraitsTest, TestIsPointer) {
+ // Verify that is_pointer is true for some pointer types.
+ EXPECT_TRUE(is_pointer<int*>::value);
+ EXPECT_TRUE(is_pointer<void*>::value);
+ EXPECT_TRUE(is_pointer<string*>::value);
+ EXPECT_TRUE(is_pointer<const void*>::value);
+ EXPECT_TRUE(is_pointer<volatile float* const*>::value);
+
+ // Verify that is_pointer is false for some non-pointer types.
+ EXPECT_FALSE(is_pointer<void>::value);
+ EXPECT_FALSE(is_pointer<float&>::value);
+ EXPECT_FALSE(is_pointer<long>::value);
+ EXPECT_FALSE(is_pointer<vector<int*> >::value);
+ EXPECT_FALSE(is_pointer<int[5]>::value);
+
+ // A function pointer is a pointer, but a function type, or a function
+ // reference type, is not.
+ EXPECT_TRUE(is_pointer<int (*)(int x)>::value);
+ EXPECT_FALSE(is_pointer<void(char x)>::value);
+ EXPECT_FALSE(is_pointer<double (&)(string x)>::value);
+
+ // Verify that is_pointer<T> is true for some cv-qualified pointer types,
+ // and false for some cv-qualified non-pointer types.
+ EXPECT_TRUE(is_pointer<int* const>::value);
+ EXPECT_TRUE(is_pointer<const void* volatile>::value);
+ EXPECT_TRUE(is_pointer<char** const volatile>::value);
+ EXPECT_FALSE(is_pointer<const int>::value);
+ EXPECT_FALSE(is_pointer<volatile vector<int*> >::value);
+ EXPECT_FALSE(is_pointer<const volatile double>::value);
+}
+
+TEST(TypeTraitsTest, TestIsEnum) {
+// is_enum isn't supported on MSVC or gcc 3.x
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+ // Verify that is_enum is true for enum types.
+ EXPECT_TRUE(is_enum<G>::value);
+ EXPECT_TRUE(is_enum<const G>::value);
+ EXPECT_TRUE(is_enum<volatile G>::value);
+ EXPECT_TRUE(is_enum<const volatile G>::value);
+
+ // Verify that is_enum is false for a few non-enum types.
+ EXPECT_FALSE(is_enum<void>::value);
+ EXPECT_FALSE(is_enum<G&>::value);
+ EXPECT_FALSE(is_enum<G[1]>::value);
+ EXPECT_FALSE(is_enum<const G[1]>::value);
+ EXPECT_FALSE(is_enum<G[]>::value);
+ EXPECT_FALSE(is_enum<int>::value);
+ EXPECT_FALSE(is_enum<float>::value);
+ EXPECT_FALSE(is_enum<A>::value);
+ EXPECT_FALSE(is_enum<A*>::value);
+ EXPECT_FALSE(is_enum<const A>::value);
+ EXPECT_FALSE(is_enum<H>::value);
+ EXPECT_FALSE(is_enum<I>::value);
+ EXPECT_FALSE(is_enum<J>::value);
+ EXPECT_FALSE(is_enum<void()>::value);
+ EXPECT_FALSE(is_enum<void(*)()>::value);
+ EXPECT_FALSE(is_enum<int A::*>::value);
+ EXPECT_FALSE(is_enum<void (A::*)()>::value);
+#endif
+}
+
+TEST(TypeTraitsTest, TestIsReference) {
+ // Verifies that is_reference is true for all reference types.
+ typedef float& RefFloat;
+ EXPECT_TRUE(is_reference<float&>::value);
+ EXPECT_TRUE(is_reference<const int&>::value);
+ EXPECT_TRUE(is_reference<const int*&>::value);
+ EXPECT_TRUE(is_reference<int (&)(bool)>::value);
+ EXPECT_TRUE(is_reference<RefFloat>::value);
+ EXPECT_TRUE(is_reference<const RefFloat>::value);
+ EXPECT_TRUE(is_reference<volatile RefFloat>::value);
+ EXPECT_TRUE(is_reference<const volatile RefFloat>::value);
+
+
+ // Verifies that is_reference is false for all non-reference types.
+ EXPECT_FALSE(is_reference<float>::value);
+ EXPECT_FALSE(is_reference<const float>::value);
+ EXPECT_FALSE(is_reference<volatile float>::value);
+ EXPECT_FALSE(is_reference<const volatile float>::value);
+ EXPECT_FALSE(is_reference<const int*>::value);
+ EXPECT_FALSE(is_reference<int()>::value);
+ EXPECT_FALSE(is_reference<void(*)(const char&)>::value);
+}
+
+TEST(TypeTraitsTest, TestAddReference) {
+ COMPILE_ASSERT_TYPES_EQ(int&, add_reference<int>::type);
+ COMPILE_ASSERT_TYPES_EQ(const int&, add_reference<const int>::type);
+ COMPILE_ASSERT_TYPES_EQ(volatile int&,
+ add_reference<volatile int>::type);
+ COMPILE_ASSERT_TYPES_EQ(const volatile int&,
+ add_reference<const volatile int>::type);
+ COMPILE_ASSERT_TYPES_EQ(int&, add_reference<int&>::type);
+ COMPILE_ASSERT_TYPES_EQ(const int&, add_reference<const int&>::type);
+ COMPILE_ASSERT_TYPES_EQ(volatile int&,
+ add_reference<volatile int&>::type);
+ COMPILE_ASSERT_TYPES_EQ(const volatile int&,
+ add_reference<const volatile int&>::type);
+}
+
+TEST(TypeTraitsTest, TestIsPod) {
+ // Verify that arithmetic types and pointers are marked as PODs.
+ EXPECT_TRUE(is_pod<bool>::value);
+ EXPECT_TRUE(is_pod<char>::value);
+ EXPECT_TRUE(is_pod<unsigned char>::value);
+ EXPECT_TRUE(is_pod<signed char>::value);
+ EXPECT_TRUE(is_pod<wchar_t>::value);
+ EXPECT_TRUE(is_pod<int>::value);
+ EXPECT_TRUE(is_pod<unsigned int>::value);
+ EXPECT_TRUE(is_pod<short>::value);
+ EXPECT_TRUE(is_pod<unsigned short>::value);
+ EXPECT_TRUE(is_pod<long>::value);
+ EXPECT_TRUE(is_pod<unsigned long>::value);
+ EXPECT_TRUE(is_pod<float>::value);
+ EXPECT_TRUE(is_pod<double>::value);
+ EXPECT_TRUE(is_pod<long double>::value);
+ EXPECT_TRUE(is_pod<string*>::value);
+ EXPECT_TRUE(is_pod<A*>::value);
+ EXPECT_TRUE(is_pod<const B*>::value);
+ EXPECT_TRUE(is_pod<C**>::value);
+ EXPECT_TRUE(is_pod<const int>::value);
+ EXPECT_TRUE(is_pod<char* volatile>::value);
+ EXPECT_TRUE(is_pod<const volatile double>::value);
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+ EXPECT_TRUE(is_pod<G>::value);
+ EXPECT_TRUE(is_pod<const G>::value);
+ EXPECT_TRUE(is_pod<volatile G>::value);
+ EXPECT_TRUE(is_pod<const volatile G>::value);
+#endif
+
+ // Verify that some non-POD types are not marked as PODs.
+ EXPECT_FALSE(is_pod<void>::value);
+ EXPECT_FALSE(is_pod<string>::value);
+ EXPECT_FALSE((is_pod<pair<int, int> >::value));
+ EXPECT_FALSE(is_pod<A>::value);
+ EXPECT_FALSE(is_pod<B>::value);
+ EXPECT_FALSE(is_pod<C>::value);
+ EXPECT_FALSE(is_pod<const string>::value);
+ EXPECT_FALSE(is_pod<volatile A>::value);
+ EXPECT_FALSE(is_pod<const volatile B>::value);
+}
+
+TEST(TypeTraitsTest, TestHasTrivialConstructor) {
+ // Verify that arithmetic types and pointers have trivial constructors.
+ EXPECT_TRUE(has_trivial_constructor<bool>::value);
+ EXPECT_TRUE(has_trivial_constructor<char>::value);
+ EXPECT_TRUE(has_trivial_constructor<unsigned char>::value);
+ EXPECT_TRUE(has_trivial_constructor<signed char>::value);
+ EXPECT_TRUE(has_trivial_constructor<wchar_t>::value);
+ EXPECT_TRUE(has_trivial_constructor<int>::value);
+ EXPECT_TRUE(has_trivial_constructor<unsigned int>::value);
+ EXPECT_TRUE(has_trivial_constructor<short>::value);
+ EXPECT_TRUE(has_trivial_constructor<unsigned short>::value);
+ EXPECT_TRUE(has_trivial_constructor<long>::value);
+ EXPECT_TRUE(has_trivial_constructor<unsigned long>::value);
+ EXPECT_TRUE(has_trivial_constructor<float>::value);
+ EXPECT_TRUE(has_trivial_constructor<double>::value);
+ EXPECT_TRUE(has_trivial_constructor<long double>::value);
+ EXPECT_TRUE(has_trivial_constructor<string*>::value);
+ EXPECT_TRUE(has_trivial_constructor<A*>::value);
+ EXPECT_TRUE(has_trivial_constructor<const B*>::value);
+ EXPECT_TRUE(has_trivial_constructor<C**>::value);
+
+ // Verify that pairs and arrays of such types have trivial
+ // constructors.
+ typedef int int10[10];
+ EXPECT_TRUE((has_trivial_constructor<pair<int, char*> >::value));
+ EXPECT_TRUE(has_trivial_constructor<int10>::value);
+
+ // Verify that pairs of types without trivial constructors
+ // are not marked as trivial.
+ EXPECT_FALSE((has_trivial_constructor<pair<int, string> >::value));
+ EXPECT_FALSE((has_trivial_constructor<pair<string, int> >::value));
+
+ // Verify that types without trivial constructors are
+ // correctly marked as such.
+ EXPECT_FALSE(has_trivial_constructor<string>::value);
+ EXPECT_FALSE(has_trivial_constructor<vector<int> >::value);
+
+ // Verify that E, which we have declared to have a trivial
+ // constructor, is correctly marked as such.
+ EXPECT_TRUE(has_trivial_constructor<E>::value);
+}
+
+TEST(TypeTraitsTest, TestHasTrivialCopy) {
+ // Verify that arithmetic types and pointers have trivial copy
+ // constructors.
+ EXPECT_TRUE(has_trivial_copy<bool>::value);
+ EXPECT_TRUE(has_trivial_copy<char>::value);
+ EXPECT_TRUE(has_trivial_copy<unsigned char>::value);
+ EXPECT_TRUE(has_trivial_copy<signed char>::value);
+ EXPECT_TRUE(has_trivial_copy<wchar_t>::value);
+ EXPECT_TRUE(has_trivial_copy<int>::value);
+ EXPECT_TRUE(has_trivial_copy<unsigned int>::value);
+ EXPECT_TRUE(has_trivial_copy<short>::value);
+ EXPECT_TRUE(has_trivial_copy<unsigned short>::value);
+ EXPECT_TRUE(has_trivial_copy<long>::value);
+ EXPECT_TRUE(has_trivial_copy<unsigned long>::value);
+ EXPECT_TRUE(has_trivial_copy<float>::value);
+ EXPECT_TRUE(has_trivial_copy<double>::value);
+ EXPECT_TRUE(has_trivial_copy<long double>::value);
+ EXPECT_TRUE(has_trivial_copy<string*>::value);
+ EXPECT_TRUE(has_trivial_copy<A*>::value);
+ EXPECT_TRUE(has_trivial_copy<const B*>::value);
+ EXPECT_TRUE(has_trivial_copy<C**>::value);
+
+ // Verify that pairs and arrays of such types have trivial
+ // copy constructors.
+ typedef int int10[10];
+ EXPECT_TRUE((has_trivial_copy<pair<int, char*> >::value));
+ EXPECT_TRUE(has_trivial_copy<int10>::value);
+
+ // Verify that pairs of types without trivial copy constructors
+ // are not marked as trivial.
+ EXPECT_FALSE((has_trivial_copy<pair<int, string> >::value));
+ EXPECT_FALSE((has_trivial_copy<pair<string, int> >::value));
+
+ // Verify that types without trivial copy constructors are
+ // correctly marked as such.
+ EXPECT_FALSE(has_trivial_copy<string>::value);
+ EXPECT_FALSE(has_trivial_copy<vector<int> >::value);
+
+ // Verify that C, which we have declared to have a trivial
+ // copy constructor, is correctly marked as such.
+ EXPECT_TRUE(has_trivial_copy<C>::value);
+}
+
+TEST(TypeTraitsTest, TestHasTrivialAssign) {
+ // Verify that arithmetic types and pointers have trivial assignment
+ // operators.
+ EXPECT_TRUE(has_trivial_assign<bool>::value);
+ EXPECT_TRUE(has_trivial_assign<char>::value);
+ EXPECT_TRUE(has_trivial_assign<unsigned char>::value);
+ EXPECT_TRUE(has_trivial_assign<signed char>::value);
+ EXPECT_TRUE(has_trivial_assign<wchar_t>::value);
+ EXPECT_TRUE(has_trivial_assign<int>::value);
+ EXPECT_TRUE(has_trivial_assign<unsigned int>::value);
+ EXPECT_TRUE(has_trivial_assign<short>::value);
+ EXPECT_TRUE(has_trivial_assign<unsigned short>::value);
+ EXPECT_TRUE(has_trivial_assign<long>::value);
+ EXPECT_TRUE(has_trivial_assign<unsigned long>::value);
+ EXPECT_TRUE(has_trivial_assign<float>::value);
+ EXPECT_TRUE(has_trivial_assign<double>::value);
+ EXPECT_TRUE(has_trivial_assign<long double>::value);
+ EXPECT_TRUE(has_trivial_assign<string*>::value);
+ EXPECT_TRUE(has_trivial_assign<A*>::value);
+ EXPECT_TRUE(has_trivial_assign<const B*>::value);
+ EXPECT_TRUE(has_trivial_assign<C**>::value);
+
+ // Verify that pairs and arrays of such types have trivial
+ // assignment operators.
+ typedef int int10[10];
+ EXPECT_TRUE((has_trivial_assign<pair<int, char*> >::value));
+ EXPECT_TRUE(has_trivial_assign<int10>::value);
+
+ // Verify that pairs of types without trivial assignment operators
+ // are not marked as trivial.
+ EXPECT_FALSE((has_trivial_assign<pair<int, string> >::value));
+ EXPECT_FALSE((has_trivial_assign<pair<string, int> >::value));
+
+ // Verify that types without trivial assignment operators are
+ // correctly marked as such.
+ EXPECT_FALSE(has_trivial_assign<string>::value);
+ EXPECT_FALSE(has_trivial_assign<vector<int> >::value);
+
+ // Verify that D, which we have declared to have a trivial
+ // assignment operator, is correctly marked as such.
+ EXPECT_TRUE(has_trivial_assign<D>::value);
+}
+
+TEST(TypeTraitsTest, TestHasTrivialDestructor) {
+ // Verify that arithmetic types and pointers have trivial destructors.
+ EXPECT_TRUE(has_trivial_destructor<bool>::value);
+ EXPECT_TRUE(has_trivial_destructor<char>::value);
+ EXPECT_TRUE(has_trivial_destructor<unsigned char>::value);
+ EXPECT_TRUE(has_trivial_destructor<signed char>::value);
+ EXPECT_TRUE(has_trivial_destructor<wchar_t>::value);
+ EXPECT_TRUE(has_trivial_destructor<int>::value);
+ EXPECT_TRUE(has_trivial_destructor<unsigned int>::value);
+ EXPECT_TRUE(has_trivial_destructor<short>::value);
+ EXPECT_TRUE(has_trivial_destructor<unsigned short>::value);
+ EXPECT_TRUE(has_trivial_destructor<long>::value);
+ EXPECT_TRUE(has_trivial_destructor<unsigned long>::value);
+ EXPECT_TRUE(has_trivial_destructor<float>::value);
+ EXPECT_TRUE(has_trivial_destructor<double>::value);
+ EXPECT_TRUE(has_trivial_destructor<long double>::value);
+ EXPECT_TRUE(has_trivial_destructor<string*>::value);
+ EXPECT_TRUE(has_trivial_destructor<A*>::value);
+ EXPECT_TRUE(has_trivial_destructor<const B*>::value);
+ EXPECT_TRUE(has_trivial_destructor<C**>::value);
+
+ // Verify that pairs and arrays of such types have trivial
+ // destructors.
+ typedef int int10[10];
+ EXPECT_TRUE((has_trivial_destructor<pair<int, char*> >::value));
+ EXPECT_TRUE(has_trivial_destructor<int10>::value);
+
+ // Verify that pairs of types without trivial destructors
+ // are not marked as trivial.
+ EXPECT_FALSE((has_trivial_destructor<pair<int, string> >::value));
+ EXPECT_FALSE((has_trivial_destructor<pair<string, int> >::value));
+
+ // Verify that types without trivial destructors are
+ // correctly marked as such.
+ EXPECT_FALSE(has_trivial_destructor<string>::value);
+ EXPECT_FALSE(has_trivial_destructor<vector<int> >::value);
+
+ // Verify that F, which we have declared to have a trivial
+ // destructor, is correctly marked as such.
+ EXPECT_TRUE(has_trivial_destructor<F>::value);
+}
+
+// Tests remove_pointer.
+TEST(TypeTraitsTest, TestRemovePointer) {
+ COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int>::type);
+ COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int*>::type);
+ COMPILE_ASSERT_TYPES_EQ(const int, remove_pointer<const int*>::type);
+ COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int* const>::type);
+ COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int* volatile>::type);
+}
+
+TEST(TypeTraitsTest, TestRemoveConst) {
+ COMPILE_ASSERT_TYPES_EQ(int, remove_const<int>::type);
+ COMPILE_ASSERT_TYPES_EQ(int, remove_const<const int>::type);
+ COMPILE_ASSERT_TYPES_EQ(int *, remove_const<int * const>::type);
+ // TR1 examples.
+ COMPILE_ASSERT_TYPES_EQ(const int *, remove_const<const int *>::type);
+ COMPILE_ASSERT_TYPES_EQ(volatile int,
+ remove_const<const volatile int>::type);
+}
+
+TEST(TypeTraitsTest, TestRemoveVolatile) {
+ COMPILE_ASSERT_TYPES_EQ(int, remove_volatile<int>::type);
+ COMPILE_ASSERT_TYPES_EQ(int, remove_volatile<volatile int>::type);
+ COMPILE_ASSERT_TYPES_EQ(int *, remove_volatile<int * volatile>::type);
+ // TR1 examples.
+ COMPILE_ASSERT_TYPES_EQ(volatile int *,
+ remove_volatile<volatile int *>::type);
+ COMPILE_ASSERT_TYPES_EQ(const int,
+ remove_volatile<const volatile int>::type);
+}
+
+TEST(TypeTraitsTest, TestRemoveCV) {
+ COMPILE_ASSERT_TYPES_EQ(int, remove_cv<int>::type);
+ COMPILE_ASSERT_TYPES_EQ(int, remove_cv<volatile int>::type);
+ COMPILE_ASSERT_TYPES_EQ(int, remove_cv<const int>::type);
+ COMPILE_ASSERT_TYPES_EQ(int *, remove_cv<int * const volatile>::type);
+ // TR1 examples.
+ COMPILE_ASSERT_TYPES_EQ(const volatile int *,
+ remove_cv<const volatile int *>::type);
+ COMPILE_ASSERT_TYPES_EQ(int,
+ remove_cv<const volatile int>::type);
+}
+
+TEST(TypeTraitsTest, TestRemoveReference) {
+ COMPILE_ASSERT_TYPES_EQ(int, remove_reference<int>::type);
+ COMPILE_ASSERT_TYPES_EQ(int, remove_reference<int&>::type);
+ COMPILE_ASSERT_TYPES_EQ(const int, remove_reference<const int&>::type);
+ COMPILE_ASSERT_TYPES_EQ(int*, remove_reference<int * &>::type);
+}
+
+TEST(TypeTraitsTest, TestIsSame) {
+ EXPECT_TRUE((is_same<int32, int32>::value));
+ EXPECT_FALSE((is_same<int32, int64>::value));
+ EXPECT_FALSE((is_same<int64, int32>::value));
+ EXPECT_FALSE((is_same<int, const int>::value));
+
+ EXPECT_TRUE((is_same<void, void>::value));
+ EXPECT_FALSE((is_same<void, int>::value));
+ EXPECT_FALSE((is_same<int, void>::value));
+
+ EXPECT_TRUE((is_same<int*, int*>::value));
+ EXPECT_TRUE((is_same<void*, void*>::value));
+ EXPECT_FALSE((is_same<int*, void*>::value));
+ EXPECT_FALSE((is_same<void*, int*>::value));
+ EXPECT_FALSE((is_same<void*, const void*>::value));
+ EXPECT_FALSE((is_same<void*, void* const>::value));
+
+ EXPECT_TRUE((is_same<Base*, Base*>::value));
+ EXPECT_TRUE((is_same<Derived*, Derived*>::value));
+ EXPECT_FALSE((is_same<Base*, Derived*>::value));
+ EXPECT_FALSE((is_same<Derived*, Base*>::value));
+}
+
+TEST(TypeTraitsTest, TestConvertible) {
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+ EXPECT_TRUE((is_convertible<int, int>::value));
+ EXPECT_TRUE((is_convertible<int, long>::value));
+ EXPECT_TRUE((is_convertible<long, int>::value));
+
+ EXPECT_TRUE((is_convertible<int*, void*>::value));
+ EXPECT_FALSE((is_convertible<void*, int*>::value));
+
+ EXPECT_TRUE((is_convertible<Derived*, Base*>::value));
+ EXPECT_FALSE((is_convertible<Base*, Derived*>::value));
+ EXPECT_TRUE((is_convertible<Derived*, const Base*>::value));
+ EXPECT_FALSE((is_convertible<const Derived*, Base*>::value));
+#endif
+}
+
+} // anonymous namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/test_util.cc b/src/google/protobuf/test_util.cc
index af8b390..be1c90e 100644
--- a/src/google/protobuf/test_util.cc
+++ b/src/google/protobuf/test_util.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -50,6 +50,14 @@ namespace google {
namespace protobuf {
void TestUtil::SetAllFields(unittest::TestAllTypes* message) {
+ SetOptionalFields(message);
+ AddRepeatedFields1(message);
+ AddRepeatedFields2(message);
+ SetDefaultFields(message);
+ SetOneofFields(message);
+}
+
+void TestUtil::SetOptionalFields(unittest::TestAllTypes* message) {
message->set_optional_int32 (101);
message->set_optional_int64 (102);
message->set_optional_uint32 (103);
@@ -66,10 +74,12 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) {
message->set_optional_string ("115");
message->set_optional_bytes ("116");
- message->mutable_optionalgroup ()->set_a(117);
- message->mutable_optional_nested_message ()->set_bb(118);
- message->mutable_optional_foreign_message()->set_c(119);
- message->mutable_optional_import_message ()->set_d(120);
+ message->mutable_optionalgroup ()->set_a(117);
+ message->mutable_optional_nested_message ()->set_bb(118);
+ message->mutable_optional_foreign_message ()->set_c(119);
+ message->mutable_optional_import_message ()->set_d(120);
+ message->mutable_optional_public_import_message()->set_e(126);
+ message->mutable_optional_lazy_message ()->set_bb(127);
message->set_optional_nested_enum (unittest::TestAllTypes::BAZ);
message->set_optional_foreign_enum(unittest::FOREIGN_BAZ );
@@ -87,9 +97,11 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) {
message->GetDescriptor()->FindFieldByName("optional_cord"),
"125");
#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
- // -----------------------------------------------------------------
+// -------------------------------------------------------------------
+void TestUtil::AddRepeatedFields1(unittest::TestAllTypes* message) {
message->add_repeated_int32 (201);
message->add_repeated_int64 (202);
message->add_repeated_uint32 (203);
@@ -110,6 +122,7 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) {
message->add_repeated_nested_message ()->set_bb(218);
message->add_repeated_foreign_message()->set_c(219);
message->add_repeated_import_message ()->set_d(220);
+ message->add_repeated_lazy_message ()->set_bb(227);
message->add_repeated_nested_enum (unittest::TestAllTypes::BAR);
message->add_repeated_foreign_enum(unittest::FOREIGN_BAR );
@@ -125,7 +138,9 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) {
message->GetDescriptor()->FindFieldByName("repeated_cord"),
"225");
#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
+void TestUtil::AddRepeatedFields2(unittest::TestAllTypes* message) {
// Add a second one of each field.
message->add_repeated_int32 (301);
message->add_repeated_int64 (302);
@@ -147,6 +162,7 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) {
message->add_repeated_nested_message ()->set_bb(318);
message->add_repeated_foreign_message()->set_c(319);
message->add_repeated_import_message ()->set_d(320);
+ message->add_repeated_lazy_message ()->set_bb(327);
message->add_repeated_nested_enum (unittest::TestAllTypes::BAZ);
message->add_repeated_foreign_enum(unittest::FOREIGN_BAZ );
@@ -162,9 +178,11 @@ void TestUtil::SetAllFields(unittest::TestAllTypes* message) {
message->GetDescriptor()->FindFieldByName("repeated_cord"),
"325");
#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
- // -----------------------------------------------------------------
+// -------------------------------------------------------------------
+void TestUtil::SetDefaultFields(unittest::TestAllTypes* message) {
message->set_default_int32 (401);
message->set_default_int64 (402);
message->set_default_uint32 (403);
@@ -220,6 +238,7 @@ void TestUtil::ModifyRepeatedFields(unittest::TestAllTypes* message) {
message->mutable_repeated_nested_message (1)->set_bb(518);
message->mutable_repeated_foreign_message(1)->set_c(519);
message->mutable_repeated_import_message (1)->set_d(520);
+ message->mutable_repeated_lazy_message (1)->set_bb(527);
message->set_repeated_nested_enum (1, unittest::TestAllTypes::FOO);
message->set_repeated_foreign_enum(1, unittest::FOREIGN_FOO );
@@ -237,6 +256,14 @@ void TestUtil::ModifyRepeatedFields(unittest::TestAllTypes* message) {
#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
}
+// ------------------------------------------------------------------
+void TestUtil::SetOneofFields(unittest::TestAllTypes* message) {
+ message->set_oneof_uint32(601);
+ message->mutable_oneof_nested_message()->set_bb(602);
+ message->set_oneof_string("603");
+ message->set_oneof_bytes("604");
+}
+
// -------------------------------------------------------------------
void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) {
@@ -256,15 +283,19 @@ void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) {
EXPECT_TRUE(message.has_optional_string ());
EXPECT_TRUE(message.has_optional_bytes ());
- EXPECT_TRUE(message.has_optionalgroup ());
- EXPECT_TRUE(message.has_optional_nested_message ());
- EXPECT_TRUE(message.has_optional_foreign_message());
- EXPECT_TRUE(message.has_optional_import_message ());
+ EXPECT_TRUE(message.has_optionalgroup ());
+ EXPECT_TRUE(message.has_optional_nested_message ());
+ EXPECT_TRUE(message.has_optional_foreign_message ());
+ EXPECT_TRUE(message.has_optional_import_message ());
+ EXPECT_TRUE(message.has_optional_public_import_message());
+ EXPECT_TRUE(message.has_optional_lazy_message ());
- EXPECT_TRUE(message.optionalgroup ().has_a());
- EXPECT_TRUE(message.optional_nested_message ().has_bb());
- EXPECT_TRUE(message.optional_foreign_message().has_c());
- EXPECT_TRUE(message.optional_import_message ().has_d());
+ EXPECT_TRUE(message.optionalgroup ().has_a());
+ EXPECT_TRUE(message.optional_nested_message ().has_bb());
+ EXPECT_TRUE(message.optional_foreign_message ().has_c());
+ EXPECT_TRUE(message.optional_import_message ().has_d());
+ EXPECT_TRUE(message.optional_public_import_message().has_e());
+ EXPECT_TRUE(message.optional_lazy_message ().has_bb());
EXPECT_TRUE(message.has_optional_nested_enum ());
EXPECT_TRUE(message.has_optional_foreign_enum());
@@ -287,14 +318,16 @@ void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) {
EXPECT_EQ(110 , message.optional_sfixed64());
EXPECT_EQ(111 , message.optional_float ());
EXPECT_EQ(112 , message.optional_double ());
- EXPECT_EQ(true , message.optional_bool ());
+ EXPECT_TRUE( message.optional_bool ());
EXPECT_EQ("115", message.optional_string ());
EXPECT_EQ("116", message.optional_bytes ());
- EXPECT_EQ(117, message.optionalgroup ().a());
- EXPECT_EQ(118, message.optional_nested_message ().bb());
- EXPECT_EQ(119, message.optional_foreign_message().c());
- EXPECT_EQ(120, message.optional_import_message ().d());
+ EXPECT_EQ(117, message.optionalgroup ().a());
+ EXPECT_EQ(118, message.optional_nested_message ().bb());
+ EXPECT_EQ(119, message.optional_foreign_message ().c());
+ EXPECT_EQ(120, message.optional_import_message ().d());
+ EXPECT_EQ(126, message.optional_public_import_message ().e());
+ EXPECT_EQ(127, message.optional_lazy_message ().bb());
EXPECT_EQ(unittest::TestAllTypes::BAZ, message.optional_nested_enum ());
EXPECT_EQ(unittest::FOREIGN_BAZ , message.optional_foreign_enum());
@@ -323,6 +356,7 @@ void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) {
ASSERT_EQ(2, message.repeated_nested_message_size ());
ASSERT_EQ(2, message.repeated_foreign_message_size());
ASSERT_EQ(2, message.repeated_import_message_size ());
+ ASSERT_EQ(2, message.repeated_lazy_message_size ());
ASSERT_EQ(2, message.repeated_nested_enum_size ());
ASSERT_EQ(2, message.repeated_foreign_enum_size ());
ASSERT_EQ(2, message.repeated_import_enum_size ());
@@ -344,7 +378,7 @@ void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) {
EXPECT_EQ(210 , message.repeated_sfixed64(0));
EXPECT_EQ(211 , message.repeated_float (0));
EXPECT_EQ(212 , message.repeated_double (0));
- EXPECT_EQ(true , message.repeated_bool (0));
+ EXPECT_TRUE( message.repeated_bool (0));
EXPECT_EQ("215", message.repeated_string (0));
EXPECT_EQ("216", message.repeated_bytes (0));
@@ -352,6 +386,7 @@ void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) {
EXPECT_EQ(218, message.repeated_nested_message (0).bb());
EXPECT_EQ(219, message.repeated_foreign_message(0).c());
EXPECT_EQ(220, message.repeated_import_message (0).d());
+ EXPECT_EQ(227, message.repeated_lazy_message (0).bb());
EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0));
@@ -370,7 +405,7 @@ void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) {
EXPECT_EQ(310 , message.repeated_sfixed64(1));
EXPECT_EQ(311 , message.repeated_float (1));
EXPECT_EQ(312 , message.repeated_double (1));
- EXPECT_EQ(false, message.repeated_bool (1));
+ EXPECT_FALSE( message.repeated_bool (1));
EXPECT_EQ("315", message.repeated_string (1));
EXPECT_EQ("316", message.repeated_bytes (1));
@@ -378,6 +413,7 @@ void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) {
EXPECT_EQ(318, message.repeated_nested_message (1).bb());
EXPECT_EQ(319, message.repeated_foreign_message(1).c());
EXPECT_EQ(320, message.repeated_import_message (1).d());
+ EXPECT_EQ(327, message.repeated_lazy_message (1).bb());
EXPECT_EQ(unittest::TestAllTypes::BAZ, message.repeated_nested_enum (1));
EXPECT_EQ(unittest::FOREIGN_BAZ , message.repeated_foreign_enum(1));
@@ -419,7 +455,7 @@ void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) {
EXPECT_EQ(410 , message.default_sfixed64());
EXPECT_EQ(411 , message.default_float ());
EXPECT_EQ(412 , message.default_double ());
- EXPECT_EQ(false, message.default_bool ());
+ EXPECT_FALSE( message.default_bool ());
EXPECT_EQ("415", message.default_string ());
EXPECT_EQ("416", message.default_bytes ());
@@ -427,6 +463,13 @@ void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) {
EXPECT_EQ(unittest::FOREIGN_FOO , message.default_foreign_enum());
EXPECT_EQ(unittest_import::IMPORT_FOO, message.default_import_enum ());
+
+ EXPECT_FALSE(message.has_oneof_uint32 ());
+ EXPECT_FALSE(message.has_oneof_nested_message());
+ EXPECT_FALSE(message.has_oneof_string ());
+ EXPECT_TRUE(message.has_oneof_bytes ());
+
+ EXPECT_EQ("604", message.oneof_bytes());
}
// -------------------------------------------------------------------
@@ -449,10 +492,12 @@ void TestUtil::ExpectClear(const unittest::TestAllTypes& message) {
EXPECT_FALSE(message.has_optional_string ());
EXPECT_FALSE(message.has_optional_bytes ());
- EXPECT_FALSE(message.has_optionalgroup ());
- EXPECT_FALSE(message.has_optional_nested_message ());
- EXPECT_FALSE(message.has_optional_foreign_message());
- EXPECT_FALSE(message.has_optional_import_message ());
+ EXPECT_FALSE(message.has_optionalgroup ());
+ EXPECT_FALSE(message.has_optional_nested_message ());
+ EXPECT_FALSE(message.has_optional_foreign_message ());
+ EXPECT_FALSE(message.has_optional_import_message ());
+ EXPECT_FALSE(message.has_optional_public_import_message());
+ EXPECT_FALSE(message.has_optional_lazy_message ());
EXPECT_FALSE(message.has_optional_nested_enum ());
EXPECT_FALSE(message.has_optional_foreign_enum());
@@ -474,20 +519,24 @@ void TestUtil::ExpectClear(const unittest::TestAllTypes& message) {
EXPECT_EQ(0 , message.optional_sfixed64());
EXPECT_EQ(0 , message.optional_float ());
EXPECT_EQ(0 , message.optional_double ());
- EXPECT_EQ(false, message.optional_bool ());
+ EXPECT_FALSE( message.optional_bool ());
EXPECT_EQ("" , message.optional_string ());
EXPECT_EQ("" , message.optional_bytes ());
// Embedded messages should also be clear.
- EXPECT_FALSE(message.optionalgroup ().has_a());
- EXPECT_FALSE(message.optional_nested_message ().has_bb());
- EXPECT_FALSE(message.optional_foreign_message().has_c());
- EXPECT_FALSE(message.optional_import_message ().has_d());
-
- EXPECT_EQ(0, message.optionalgroup ().a());
- EXPECT_EQ(0, message.optional_nested_message ().bb());
- EXPECT_EQ(0, message.optional_foreign_message().c());
- EXPECT_EQ(0, message.optional_import_message ().d());
+ EXPECT_FALSE(message.optionalgroup ().has_a());
+ EXPECT_FALSE(message.optional_nested_message ().has_bb());
+ EXPECT_FALSE(message.optional_foreign_message ().has_c());
+ EXPECT_FALSE(message.optional_import_message ().has_d());
+ EXPECT_FALSE(message.optional_public_import_message().has_e());
+ EXPECT_FALSE(message.optional_lazy_message ().has_bb());
+
+ EXPECT_EQ(0, message.optionalgroup ().a());
+ EXPECT_EQ(0, message.optional_nested_message ().bb());
+ EXPECT_EQ(0, message.optional_foreign_message ().c());
+ EXPECT_EQ(0, message.optional_import_message ().d());
+ EXPECT_EQ(0, message.optional_public_import_message().e());
+ EXPECT_EQ(0, message.optional_lazy_message ().bb());
// Enums without defaults are set to the first value in the enum.
EXPECT_EQ(unittest::TestAllTypes::FOO, message.optional_nested_enum ());
@@ -516,6 +565,7 @@ void TestUtil::ExpectClear(const unittest::TestAllTypes& message) {
EXPECT_EQ(0, message.repeated_nested_message_size ());
EXPECT_EQ(0, message.repeated_foreign_message_size());
EXPECT_EQ(0, message.repeated_import_message_size ());
+ EXPECT_EQ(0, message.repeated_lazy_message_size ());
EXPECT_EQ(0, message.repeated_nested_enum_size ());
EXPECT_EQ(0, message.repeated_foreign_enum_size ());
EXPECT_EQ(0, message.repeated_import_enum_size ());
@@ -558,7 +608,7 @@ void TestUtil::ExpectClear(const unittest::TestAllTypes& message) {
EXPECT_EQ(-50 , message.default_sfixed64());
EXPECT_EQ( 51.5 , message.default_float ());
EXPECT_EQ( 52e3 , message.default_double ());
- EXPECT_EQ(true , message.default_bool ());
+ EXPECT_TRUE( message.default_bool ());
EXPECT_EQ("hello", message.default_string ());
EXPECT_EQ("world", message.default_bytes ());
@@ -566,6 +616,11 @@ void TestUtil::ExpectClear(const unittest::TestAllTypes& message) {
EXPECT_EQ(unittest::FOREIGN_BAR , message.default_foreign_enum());
EXPECT_EQ(unittest_import::IMPORT_BAR, message.default_import_enum ());
+
+ EXPECT_FALSE(message.has_oneof_uint32 ());
+ EXPECT_FALSE(message.has_oneof_nested_message());
+ EXPECT_FALSE(message.has_oneof_string ());
+ EXPECT_FALSE(message.has_oneof_bytes ());
}
// -------------------------------------------------------------------
@@ -595,6 +650,7 @@ void TestUtil::ExpectRepeatedFieldsModified(
ASSERT_EQ(2, message.repeated_nested_message_size ());
ASSERT_EQ(2, message.repeated_foreign_message_size());
ASSERT_EQ(2, message.repeated_import_message_size ());
+ ASSERT_EQ(2, message.repeated_lazy_message_size ());
ASSERT_EQ(2, message.repeated_nested_enum_size ());
ASSERT_EQ(2, message.repeated_foreign_enum_size ());
ASSERT_EQ(2, message.repeated_import_enum_size ());
@@ -616,7 +672,7 @@ void TestUtil::ExpectRepeatedFieldsModified(
EXPECT_EQ(210 , message.repeated_sfixed64(0));
EXPECT_EQ(211 , message.repeated_float (0));
EXPECT_EQ(212 , message.repeated_double (0));
- EXPECT_EQ(true , message.repeated_bool (0));
+ EXPECT_TRUE( message.repeated_bool (0));
EXPECT_EQ("215", message.repeated_string (0));
EXPECT_EQ("216", message.repeated_bytes (0));
@@ -624,6 +680,7 @@ void TestUtil::ExpectRepeatedFieldsModified(
EXPECT_EQ(218, message.repeated_nested_message (0).bb());
EXPECT_EQ(219, message.repeated_foreign_message(0).c());
EXPECT_EQ(220, message.repeated_import_message (0).d());
+ EXPECT_EQ(227, message.repeated_lazy_message (0).bb());
EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0));
EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(0));
@@ -643,7 +700,7 @@ void TestUtil::ExpectRepeatedFieldsModified(
EXPECT_EQ(510 , message.repeated_sfixed64(1));
EXPECT_EQ(511 , message.repeated_float (1));
EXPECT_EQ(512 , message.repeated_double (1));
- EXPECT_EQ(true , message.repeated_bool (1));
+ EXPECT_TRUE( message.repeated_bool (1));
EXPECT_EQ("515", message.repeated_string (1));
EXPECT_EQ("516", message.repeated_bytes (1));
@@ -651,6 +708,7 @@ void TestUtil::ExpectRepeatedFieldsModified(
EXPECT_EQ(518, message.repeated_nested_message (1).bb());
EXPECT_EQ(519, message.repeated_foreign_message(1).c());
EXPECT_EQ(520, message.repeated_import_message (1).d());
+ EXPECT_EQ(527, message.repeated_lazy_message (1).bb());
EXPECT_EQ(unittest::TestAllTypes::FOO, message.repeated_nested_enum (1));
EXPECT_EQ(unittest::FOREIGN_FOO , message.repeated_foreign_enum(1));
@@ -775,7 +833,7 @@ void TestUtil::ExpectPackedFieldsSet(const unittest::TestPackedTypes& message) {
EXPECT_EQ(610 , message.packed_sfixed64(0));
EXPECT_EQ(611 , message.packed_float (0));
EXPECT_EQ(612 , message.packed_double (0));
- EXPECT_EQ(true , message.packed_bool (0));
+ EXPECT_TRUE( message.packed_bool (0));
EXPECT_EQ(unittest::FOREIGN_BAR, message.packed_enum(0));
EXPECT_EQ(701 , message.packed_int32 (1));
@@ -790,7 +848,7 @@ void TestUtil::ExpectPackedFieldsSet(const unittest::TestPackedTypes& message) {
EXPECT_EQ(710 , message.packed_sfixed64(1));
EXPECT_EQ(711 , message.packed_float (1));
EXPECT_EQ(712 , message.packed_double (1));
- EXPECT_EQ(false, message.packed_bool (1));
+ EXPECT_FALSE( message.packed_bool (1));
EXPECT_EQ(unittest::FOREIGN_BAZ, message.packed_enum(1));
}
@@ -825,7 +883,7 @@ void TestUtil::ExpectUnpackedFieldsSet(
EXPECT_EQ(610 , message.unpacked_sfixed64(0));
EXPECT_EQ(611 , message.unpacked_float (0));
EXPECT_EQ(612 , message.unpacked_double (0));
- EXPECT_EQ(true , message.unpacked_bool (0));
+ EXPECT_TRUE( message.unpacked_bool (0));
EXPECT_EQ(unittest::FOREIGN_BAR, message.unpacked_enum(0));
EXPECT_EQ(701 , message.unpacked_int32 (1));
@@ -840,7 +898,7 @@ void TestUtil::ExpectUnpackedFieldsSet(
EXPECT_EQ(710 , message.unpacked_sfixed64(1));
EXPECT_EQ(711 , message.unpacked_float (1));
EXPECT_EQ(712 , message.unpacked_double (1));
- EXPECT_EQ(false, message.unpacked_bool (1));
+ EXPECT_FALSE( message.unpacked_bool (1));
EXPECT_EQ(unittest::FOREIGN_BAZ, message.unpacked_enum(1));
}
@@ -897,7 +955,7 @@ void TestUtil::ExpectPackedFieldsModified(
EXPECT_EQ(610 , message.packed_sfixed64(0));
EXPECT_EQ(611 , message.packed_float (0));
EXPECT_EQ(612 , message.packed_double (0));
- EXPECT_EQ(true , message.packed_bool (0));
+ EXPECT_TRUE( message.packed_bool (0));
EXPECT_EQ(unittest::FOREIGN_BAR, message.packed_enum(0));
// Actually verify the second (modified) elements now.
EXPECT_EQ(801 , message.packed_int32 (1));
@@ -912,7 +970,7 @@ void TestUtil::ExpectPackedFieldsModified(
EXPECT_EQ(810 , message.packed_sfixed64(1));
EXPECT_EQ(811 , message.packed_float (1));
EXPECT_EQ(812 , message.packed_double (1));
- EXPECT_EQ(true , message.packed_bool (1));
+ EXPECT_TRUE( message.packed_bool (1));
EXPECT_EQ(unittest::FOREIGN_FOO, message.packed_enum(1));
}
@@ -953,6 +1011,9 @@ void TestUtil::SetAllExtensions(unittest::TestAllExtensions* message) {
message->SetExtension(unittest::optional_string_piece_extension, "124");
message->SetExtension(unittest::optional_cord_extension, "125");
+ message->MutableExtension(unittest::optional_public_import_message_extension)->set_e(126);
+ message->MutableExtension(unittest::optional_lazy_message_extension)->set_bb(127);
+
// -----------------------------------------------------------------
message->AddExtension(unittest::repeated_int32_extension , 201);
@@ -975,6 +1036,7 @@ void TestUtil::SetAllExtensions(unittest::TestAllExtensions* message) {
message->AddExtension(unittest::repeated_nested_message_extension )->set_bb(218);
message->AddExtension(unittest::repeated_foreign_message_extension)->set_c(219);
message->AddExtension(unittest::repeated_import_message_extension )->set_d(220);
+ message->AddExtension(unittest::repeated_lazy_message_extension )->set_bb(227);
message->AddExtension(unittest::repeated_nested_enum_extension , unittest::TestAllTypes::BAR);
message->AddExtension(unittest::repeated_foreign_enum_extension, unittest::FOREIGN_BAR );
@@ -1004,6 +1066,7 @@ void TestUtil::SetAllExtensions(unittest::TestAllExtensions* message) {
message->AddExtension(unittest::repeated_nested_message_extension )->set_bb(318);
message->AddExtension(unittest::repeated_foreign_message_extension)->set_c(319);
message->AddExtension(unittest::repeated_import_message_extension )->set_d(320);
+ message->AddExtension(unittest::repeated_lazy_message_extension )->set_bb(327);
message->AddExtension(unittest::repeated_nested_enum_extension , unittest::TestAllTypes::BAZ);
message->AddExtension(unittest::repeated_foreign_enum_extension, unittest::FOREIGN_BAZ );
@@ -1036,6 +1099,15 @@ void TestUtil::SetAllExtensions(unittest::TestAllExtensions* message) {
message->SetExtension(unittest::default_string_piece_extension, "424");
message->SetExtension(unittest::default_cord_extension, "425");
+
+ SetOneofFields(message);
+}
+
+void TestUtil::SetOneofFields(unittest::TestAllExtensions* message) {
+ message->SetExtension(unittest::oneof_uint32_extension, 601);
+ message->MutableExtension(unittest::oneof_nested_message_extension)->set_bb(602);
+ message->SetExtension(unittest::oneof_string_extension, "603");
+ message->SetExtension(unittest::oneof_bytes_extension, "604");
}
// -------------------------------------------------------------------
@@ -1073,6 +1145,7 @@ void TestUtil::ModifyRepeatedExtensions(unittest::TestAllExtensions* message) {
message->MutableExtension(unittest::repeated_nested_message_extension , 1)->set_bb(518);
message->MutableExtension(unittest::repeated_foreign_message_extension, 1)->set_c(519);
message->MutableExtension(unittest::repeated_import_message_extension , 1)->set_d(520);
+ message->MutableExtension(unittest::repeated_lazy_message_extension , 1)->set_bb(527);
message->SetExtension(unittest::repeated_nested_enum_extension , 1, unittest::TestAllTypes::FOO);
message->SetExtension(unittest::repeated_foreign_enum_extension, 1, unittest::FOREIGN_FOO );
@@ -1102,15 +1175,19 @@ void TestUtil::ExpectAllExtensionsSet(
EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension ));
EXPECT_TRUE(message.HasExtension(unittest::optional_bytes_extension ));
- EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension ));
- EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension ));
- EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension));
- EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_public_import_message_extension));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_lazy_message_extension ));
- EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension ).has_a());
- EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb());
- EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension).has_c());
- EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension ).has_d());
+ EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension ).has_a());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension ).has_c());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension ).has_d());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_public_import_message_extension).has_e());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_lazy_message_extension ).has_bb());
EXPECT_TRUE(message.HasExtension(unittest::optional_nested_enum_extension ));
EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_enum_extension));
@@ -1131,7 +1208,7 @@ void TestUtil::ExpectAllExtensionsSet(
EXPECT_EQ(110 , message.GetExtension(unittest::optional_sfixed64_extension));
EXPECT_EQ(111 , message.GetExtension(unittest::optional_float_extension ));
EXPECT_EQ(112 , message.GetExtension(unittest::optional_double_extension ));
- EXPECT_EQ(true , message.GetExtension(unittest::optional_bool_extension ));
+ EXPECT_TRUE( message.GetExtension(unittest::optional_bool_extension ));
EXPECT_EQ("115", message.GetExtension(unittest::optional_string_extension ));
EXPECT_EQ("116", message.GetExtension(unittest::optional_bytes_extension ));
@@ -1146,6 +1223,8 @@ void TestUtil::ExpectAllExtensionsSet(
EXPECT_EQ("124", message.GetExtension(unittest::optional_string_piece_extension));
EXPECT_EQ("125", message.GetExtension(unittest::optional_cord_extension));
+ EXPECT_EQ(126, message.GetExtension(unittest::optional_public_import_message_extension ).e());
+ EXPECT_EQ(127, message.GetExtension(unittest::optional_lazy_message_extension).bb());
// -----------------------------------------------------------------
@@ -1169,6 +1248,7 @@ void TestUtil::ExpectAllExtensionsSet(
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_lazy_message_extension ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension ));
@@ -1188,7 +1268,7 @@ void TestUtil::ExpectAllExtensionsSet(
EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0));
EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0));
EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0));
- EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 0));
+ EXPECT_TRUE( message.GetExtension(unittest::repeated_bool_extension , 0));
EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0));
EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0));
@@ -1196,6 +1276,7 @@ void TestUtil::ExpectAllExtensionsSet(
EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb());
EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c());
EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d());
+ EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension , 0).bb());
EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0));
EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0));
@@ -1216,7 +1297,7 @@ void TestUtil::ExpectAllExtensionsSet(
EXPECT_EQ(310 , message.GetExtension(unittest::repeated_sfixed64_extension, 1));
EXPECT_EQ(311 , message.GetExtension(unittest::repeated_float_extension , 1));
EXPECT_EQ(312 , message.GetExtension(unittest::repeated_double_extension , 1));
- EXPECT_EQ(false, message.GetExtension(unittest::repeated_bool_extension , 1));
+ EXPECT_FALSE( message.GetExtension(unittest::repeated_bool_extension , 1));
EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension , 1));
EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension , 1));
@@ -1224,6 +1305,7 @@ void TestUtil::ExpectAllExtensionsSet(
EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb());
EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c());
EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension , 1).d());
+ EXPECT_EQ(327, message.GetExtension(unittest::repeated_lazy_message_extension , 1).bb());
EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::repeated_nested_enum_extension , 1));
EXPECT_EQ(unittest::FOREIGN_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension, 1));
@@ -1269,7 +1351,7 @@ void TestUtil::ExpectAllExtensionsSet(
EXPECT_EQ(410 , message.GetExtension(unittest::default_sfixed64_extension));
EXPECT_EQ(411 , message.GetExtension(unittest::default_float_extension ));
EXPECT_EQ(412 , message.GetExtension(unittest::default_double_extension ));
- EXPECT_EQ(false, message.GetExtension(unittest::default_bool_extension ));
+ EXPECT_FALSE( message.GetExtension(unittest::default_bool_extension ));
EXPECT_EQ("415", message.GetExtension(unittest::default_string_extension ));
EXPECT_EQ("416", message.GetExtension(unittest::default_bytes_extension ));
@@ -1279,6 +1361,16 @@ void TestUtil::ExpectAllExtensionsSet(
EXPECT_EQ("424", message.GetExtension(unittest::default_string_piece_extension));
EXPECT_EQ("425", message.GetExtension(unittest::default_cord_extension));
+
+ EXPECT_TRUE(message.HasExtension(unittest::oneof_uint32_extension));
+ EXPECT_TRUE(message.GetExtension(unittest::oneof_nested_message_extension).has_bb());
+ EXPECT_TRUE(message.HasExtension(unittest::oneof_string_extension));
+ EXPECT_TRUE(message.HasExtension(unittest::oneof_bytes_extension));
+
+ EXPECT_EQ(601, message.GetExtension(unittest::oneof_uint32_extension));
+ EXPECT_EQ(602, message.GetExtension(unittest::oneof_nested_message_extension).bb());
+ EXPECT_EQ("603", message.GetExtension(unittest::oneof_string_extension));
+ EXPECT_EQ("604", message.GetExtension(unittest::oneof_bytes_extension));
}
// -------------------------------------------------------------------
@@ -1307,10 +1399,12 @@ void TestUtil::ExpectExtensionsClear(
EXPECT_FALSE(message.HasExtension(unittest::optional_string_extension ));
EXPECT_FALSE(message.HasExtension(unittest::optional_bytes_extension ));
- EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension ));
- EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension ));
- EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension));
- EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_public_import_message_extension));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_lazy_message_extension ));
EXPECT_FALSE(message.HasExtension(unittest::optional_nested_enum_extension ));
EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_enum_extension));
@@ -1332,20 +1426,24 @@ void TestUtil::ExpectExtensionsClear(
EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed64_extension));
EXPECT_EQ(0 , message.GetExtension(unittest::optional_float_extension ));
EXPECT_EQ(0 , message.GetExtension(unittest::optional_double_extension ));
- EXPECT_EQ(false, message.GetExtension(unittest::optional_bool_extension ));
+ EXPECT_FALSE( message.GetExtension(unittest::optional_bool_extension ));
EXPECT_EQ("" , message.GetExtension(unittest::optional_string_extension ));
EXPECT_EQ("" , message.GetExtension(unittest::optional_bytes_extension ));
// Embedded messages should also be clear.
- EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension ).has_a());
- EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb());
- EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension).has_c());
- EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension ).has_d());
-
- EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension ).a());
- EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension ).bb());
- EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension).c());
- EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension ).d());
+ EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension ).has_a());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension ).has_c());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension ).has_d());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_public_import_message_extension).has_e());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_lazy_message_extension ).has_bb());
+
+ EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension ).a());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension ).bb());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension ).c());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension ).d());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_public_import_message_extension).e());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_lazy_message_extension ).bb());
// Enums without defaults are set to the first value in the enum.
EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::optional_nested_enum_extension ));
@@ -1376,6 +1474,7 @@ void TestUtil::ExpectExtensionsClear(
EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_message_extension ));
EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_message_extension));
EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_message_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_lazy_message_extension ));
EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_enum_extension ));
EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_enum_extension ));
EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_enum_extension ));
@@ -1420,7 +1519,7 @@ void TestUtil::ExpectExtensionsClear(
EXPECT_EQ(-50 , message.GetExtension(unittest::default_sfixed64_extension));
EXPECT_EQ( 51.5 , message.GetExtension(unittest::default_float_extension ));
EXPECT_EQ( 52e3 , message.GetExtension(unittest::default_double_extension ));
- EXPECT_EQ(true , message.GetExtension(unittest::default_bool_extension ));
+ EXPECT_TRUE( message.GetExtension(unittest::default_bool_extension ));
EXPECT_EQ("hello", message.GetExtension(unittest::default_string_extension ));
EXPECT_EQ("world", message.GetExtension(unittest::default_bytes_extension ));
@@ -1430,6 +1529,11 @@ void TestUtil::ExpectExtensionsClear(
EXPECT_EQ("abc", message.GetExtension(unittest::default_string_piece_extension));
EXPECT_EQ("123", message.GetExtension(unittest::default_cord_extension));
+
+ EXPECT_FALSE(message.HasExtension(unittest::oneof_uint32_extension));
+ EXPECT_FALSE(message.GetExtension(unittest::oneof_nested_message_extension).has_bb());
+ EXPECT_FALSE(message.HasExtension(unittest::oneof_string_extension));
+ EXPECT_FALSE(message.HasExtension(unittest::oneof_bytes_extension));
}
// -------------------------------------------------------------------
@@ -1459,6 +1563,7 @@ void TestUtil::ExpectRepeatedExtensionsModified(
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_lazy_message_extension ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension ));
@@ -1478,7 +1583,7 @@ void TestUtil::ExpectRepeatedExtensionsModified(
EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0));
EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0));
EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0));
- EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 0));
+ EXPECT_TRUE( message.GetExtension(unittest::repeated_bool_extension , 0));
EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0));
EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0));
@@ -1486,6 +1591,7 @@ void TestUtil::ExpectRepeatedExtensionsModified(
EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb());
EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c());
EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d());
+ EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension , 0).bb());
EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0));
EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0));
@@ -1507,7 +1613,7 @@ void TestUtil::ExpectRepeatedExtensionsModified(
EXPECT_EQ(510 , message.GetExtension(unittest::repeated_sfixed64_extension, 1));
EXPECT_EQ(511 , message.GetExtension(unittest::repeated_float_extension , 1));
EXPECT_EQ(512 , message.GetExtension(unittest::repeated_double_extension , 1));
- EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 1));
+ EXPECT_TRUE( message.GetExtension(unittest::repeated_bool_extension , 1));
EXPECT_EQ("515", message.GetExtension(unittest::repeated_string_extension , 1));
EXPECT_EQ("516", message.GetExtension(unittest::repeated_bytes_extension , 1));
@@ -1515,6 +1621,7 @@ void TestUtil::ExpectRepeatedExtensionsModified(
EXPECT_EQ(518, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb());
EXPECT_EQ(519, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c());
EXPECT_EQ(520, message.GetExtension(unittest::repeated_import_message_extension , 1).d());
+ EXPECT_EQ(527, message.GetExtension(unittest::repeated_lazy_message_extension , 1).bb());
EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::repeated_nested_enum_extension , 1));
EXPECT_EQ(unittest::FOREIGN_FOO , message.GetExtension(unittest::repeated_foreign_enum_extension, 1));
@@ -1609,7 +1716,7 @@ void TestUtil::ExpectPackedExtensionsSet(
EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension, 0));
EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension , 0));
EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension , 0));
- EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension , 0));
+ EXPECT_TRUE( message.GetExtension(unittest::packed_bool_extension , 0));
EXPECT_EQ(unittest::FOREIGN_BAR,
message.GetExtension(unittest::packed_enum_extension, 0));
EXPECT_EQ(701 , message.GetExtension(unittest::packed_int32_extension , 1));
@@ -1624,7 +1731,7 @@ void TestUtil::ExpectPackedExtensionsSet(
EXPECT_EQ(710 , message.GetExtension(unittest::packed_sfixed64_extension, 1));
EXPECT_EQ(711 , message.GetExtension(unittest::packed_float_extension , 1));
EXPECT_EQ(712 , message.GetExtension(unittest::packed_double_extension , 1));
- EXPECT_EQ(false, message.GetExtension(unittest::packed_bool_extension , 1));
+ EXPECT_FALSE( message.GetExtension(unittest::packed_bool_extension , 1));
EXPECT_EQ(unittest::FOREIGN_BAZ,
message.GetExtension(unittest::packed_enum_extension, 1));
}
@@ -1679,7 +1786,7 @@ void TestUtil::ExpectPackedExtensionsModified(
EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension, 0));
EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension , 0));
EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension , 0));
- EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension , 0));
+ EXPECT_TRUE( message.GetExtension(unittest::packed_bool_extension , 0));
EXPECT_EQ(unittest::FOREIGN_BAR,
message.GetExtension(unittest::packed_enum_extension, 0));
@@ -1696,13 +1803,64 @@ void TestUtil::ExpectPackedExtensionsModified(
EXPECT_EQ(810 , message.GetExtension(unittest::packed_sfixed64_extension, 1));
EXPECT_EQ(811 , message.GetExtension(unittest::packed_float_extension , 1));
EXPECT_EQ(812 , message.GetExtension(unittest::packed_double_extension , 1));
- EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension , 1));
+ EXPECT_TRUE( message.GetExtension(unittest::packed_bool_extension , 1));
EXPECT_EQ(unittest::FOREIGN_FOO,
message.GetExtension(unittest::packed_enum_extension, 1));
}
// -------------------------------------------------------------------
+void TestUtil::ExpectUnpackedExtensionsSet(
+ const unittest::TestUnpackedExtensions& message) {
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_int32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_int64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_uint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_uint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_sint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_sint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_fixed32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_fixed64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_sfixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_sfixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_float_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_double_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_bool_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_enum_extension ));
+
+ EXPECT_EQ(601 , message.GetExtension(unittest::unpacked_int32_extension , 0));
+ EXPECT_EQ(602 , message.GetExtension(unittest::unpacked_int64_extension , 0));
+ EXPECT_EQ(603 , message.GetExtension(unittest::unpacked_uint32_extension , 0));
+ EXPECT_EQ(604 , message.GetExtension(unittest::unpacked_uint64_extension , 0));
+ EXPECT_EQ(605 , message.GetExtension(unittest::unpacked_sint32_extension , 0));
+ EXPECT_EQ(606 , message.GetExtension(unittest::unpacked_sint64_extension , 0));
+ EXPECT_EQ(607 , message.GetExtension(unittest::unpacked_fixed32_extension , 0));
+ EXPECT_EQ(608 , message.GetExtension(unittest::unpacked_fixed64_extension , 0));
+ EXPECT_EQ(609 , message.GetExtension(unittest::unpacked_sfixed32_extension, 0));
+ EXPECT_EQ(610 , message.GetExtension(unittest::unpacked_sfixed64_extension, 0));
+ EXPECT_EQ(611 , message.GetExtension(unittest::unpacked_float_extension , 0));
+ EXPECT_EQ(612 , message.GetExtension(unittest::unpacked_double_extension , 0));
+ EXPECT_EQ(true , message.GetExtension(unittest::unpacked_bool_extension , 0));
+ EXPECT_EQ(unittest::FOREIGN_BAR,
+ message.GetExtension(unittest::unpacked_enum_extension, 0));
+ EXPECT_EQ(701 , message.GetExtension(unittest::unpacked_int32_extension , 1));
+ EXPECT_EQ(702 , message.GetExtension(unittest::unpacked_int64_extension , 1));
+ EXPECT_EQ(703 , message.GetExtension(unittest::unpacked_uint32_extension , 1));
+ EXPECT_EQ(704 , message.GetExtension(unittest::unpacked_uint64_extension , 1));
+ EXPECT_EQ(705 , message.GetExtension(unittest::unpacked_sint32_extension , 1));
+ EXPECT_EQ(706 , message.GetExtension(unittest::unpacked_sint64_extension , 1));
+ EXPECT_EQ(707 , message.GetExtension(unittest::unpacked_fixed32_extension , 1));
+ EXPECT_EQ(708 , message.GetExtension(unittest::unpacked_fixed64_extension , 1));
+ EXPECT_EQ(709 , message.GetExtension(unittest::unpacked_sfixed32_extension, 1));
+ EXPECT_EQ(710 , message.GetExtension(unittest::unpacked_sfixed64_extension, 1));
+ EXPECT_EQ(711 , message.GetExtension(unittest::unpacked_float_extension , 1));
+ EXPECT_EQ(712 , message.GetExtension(unittest::unpacked_double_extension , 1));
+ EXPECT_EQ(false, message.GetExtension(unittest::unpacked_bool_extension , 1));
+ EXPECT_EQ(unittest::FOREIGN_BAZ,
+ message.GetExtension(unittest::unpacked_enum_extension, 1));
+}
+
+// -------------------------------------------------------------------
+
void TestUtil::ExpectAllFieldsAndExtensionsInOrder(const string& serialized) {
// We set each field individually, serialize separately, and concatenate all
// the strings in canonical order to determine the expected serialization.
@@ -1750,6 +1908,7 @@ void TestUtil::ExpectLastRepeatedsRemoved(
ASSERT_EQ(1, message.repeated_nested_message_size ());
ASSERT_EQ(1, message.repeated_foreign_message_size());
ASSERT_EQ(1, message.repeated_import_message_size ());
+ ASSERT_EQ(1, message.repeated_import_message_size ());
ASSERT_EQ(1, message.repeated_nested_enum_size ());
ASSERT_EQ(1, message.repeated_foreign_enum_size ());
ASSERT_EQ(1, message.repeated_import_enum_size ());
@@ -1772,7 +1931,7 @@ void TestUtil::ExpectLastRepeatedsRemoved(
EXPECT_EQ(210 , message.repeated_sfixed64(0));
EXPECT_EQ(211 , message.repeated_float (0));
EXPECT_EQ(212 , message.repeated_double (0));
- EXPECT_EQ(true , message.repeated_bool (0));
+ EXPECT_TRUE( message.repeated_bool (0));
EXPECT_EQ("215", message.repeated_string (0));
EXPECT_EQ("216", message.repeated_bytes (0));
@@ -1780,6 +1939,7 @@ void TestUtil::ExpectLastRepeatedsRemoved(
EXPECT_EQ(218, message.repeated_nested_message (0).bb());
EXPECT_EQ(219, message.repeated_foreign_message(0).c());
EXPECT_EQ(220, message.repeated_import_message (0).d());
+ EXPECT_EQ(220, message.repeated_import_message (0).d());
EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0));
EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(0));
@@ -1810,6 +1970,7 @@ void TestUtil::ExpectLastRepeatedExtensionsRemoved(
ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_nested_message_extension ));
ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_foreign_message_extension));
ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_import_message_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_lazy_message_extension ));
ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_nested_enum_extension ));
ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_foreign_enum_extension ));
ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_import_enum_extension ));
@@ -1830,7 +1991,7 @@ void TestUtil::ExpectLastRepeatedExtensionsRemoved(
EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0));
EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0));
EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0));
- EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 0));
+ EXPECT_TRUE( message.GetExtension(unittest::repeated_bool_extension , 0));
EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0));
EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0));
@@ -1838,6 +1999,7 @@ void TestUtil::ExpectLastRepeatedExtensionsRemoved(
EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb());
EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c());
EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d());
+ EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension , 0).bb());
EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0));
EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0));
@@ -1847,6 +2009,36 @@ void TestUtil::ExpectLastRepeatedExtensionsRemoved(
EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0));
}
+void TestUtil::ExpectLastRepeatedsReleased(
+ const unittest::TestAllTypes& message) {
+ ASSERT_EQ(1, message.repeatedgroup_size ());
+ ASSERT_EQ(1, message.repeated_nested_message_size ());
+ ASSERT_EQ(1, message.repeated_foreign_message_size());
+ ASSERT_EQ(1, message.repeated_import_message_size ());
+ ASSERT_EQ(1, message.repeated_import_message_size ());
+
+ EXPECT_EQ(217, message.repeatedgroup (0).a());
+ EXPECT_EQ(218, message.repeated_nested_message (0).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(220, message.repeated_import_message (0).d());
+ EXPECT_EQ(220, message.repeated_import_message (0).d());
+}
+
+void TestUtil::ExpectLastRepeatedExtensionsReleased(
+ const unittest::TestAllExtensions& message) {
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeatedgroup_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_nested_message_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_foreign_message_extension));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_import_message_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_lazy_message_extension ));
+
+ EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 0).a());
+ EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb());
+ EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c());
+ EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d());
+ EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension , 0).bb());
+}
+
void TestUtil::ExpectRepeatedsSwapped(
const unittest::TestAllTypes& message) {
ASSERT_EQ(2, message.repeated_int32_size ());
@@ -1869,6 +2061,7 @@ void TestUtil::ExpectRepeatedsSwapped(
ASSERT_EQ(2, message.repeated_nested_message_size ());
ASSERT_EQ(2, message.repeated_foreign_message_size());
ASSERT_EQ(2, message.repeated_import_message_size ());
+ ASSERT_EQ(2, message.repeated_import_message_size ());
ASSERT_EQ(2, message.repeated_nested_enum_size ());
ASSERT_EQ(2, message.repeated_foreign_enum_size ());
ASSERT_EQ(2, message.repeated_import_enum_size ());
@@ -1891,7 +2084,7 @@ void TestUtil::ExpectRepeatedsSwapped(
EXPECT_EQ(210 , message.repeated_sfixed64(1));
EXPECT_EQ(211 , message.repeated_float (1));
EXPECT_EQ(212 , message.repeated_double (1));
- EXPECT_EQ(true , message.repeated_bool (1));
+ EXPECT_TRUE( message.repeated_bool (1));
EXPECT_EQ("215", message.repeated_string (1));
EXPECT_EQ("216", message.repeated_bytes (1));
@@ -1899,6 +2092,7 @@ void TestUtil::ExpectRepeatedsSwapped(
EXPECT_EQ(218, message.repeated_nested_message (1).bb());
EXPECT_EQ(219, message.repeated_foreign_message(1).c());
EXPECT_EQ(220, message.repeated_import_message (1).d());
+ EXPECT_EQ(220, message.repeated_import_message (1).d());
EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (1));
EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(1));
@@ -1916,7 +2110,7 @@ void TestUtil::ExpectRepeatedsSwapped(
EXPECT_EQ(310 , message.repeated_sfixed64(0));
EXPECT_EQ(311 , message.repeated_float (0));
EXPECT_EQ(312 , message.repeated_double (0));
- EXPECT_EQ(false, message.repeated_bool (0));
+ EXPECT_FALSE( message.repeated_bool (0));
EXPECT_EQ("315", message.repeated_string (0));
EXPECT_EQ("316", message.repeated_bytes (0));
@@ -1924,6 +2118,7 @@ void TestUtil::ExpectRepeatedsSwapped(
EXPECT_EQ(318, message.repeated_nested_message (0).bb());
EXPECT_EQ(319, message.repeated_foreign_message(0).c());
EXPECT_EQ(320, message.repeated_import_message (0).d());
+ EXPECT_EQ(320, message.repeated_import_message (0).d());
EXPECT_EQ(unittest::TestAllTypes::BAZ, message.repeated_nested_enum (0));
EXPECT_EQ(unittest::FOREIGN_BAZ , message.repeated_foreign_enum(0));
@@ -1953,6 +2148,7 @@ void TestUtil::ExpectRepeatedExtensionsSwapped(
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_lazy_message_extension ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension ));
@@ -1972,7 +2168,7 @@ void TestUtil::ExpectRepeatedExtensionsSwapped(
EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 1));
EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 1));
EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 1));
- EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 1));
+ EXPECT_TRUE( message.GetExtension(unittest::repeated_bool_extension , 1));
EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 1));
EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 1));
@@ -1980,6 +2176,7 @@ void TestUtil::ExpectRepeatedExtensionsSwapped(
EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb());
EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c());
EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 1).d());
+ EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension , 1).bb());
EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 1));
EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 1));
@@ -2000,7 +2197,7 @@ void TestUtil::ExpectRepeatedExtensionsSwapped(
EXPECT_EQ(310 , message.GetExtension(unittest::repeated_sfixed64_extension, 0));
EXPECT_EQ(311 , message.GetExtension(unittest::repeated_float_extension , 0));
EXPECT_EQ(312 , message.GetExtension(unittest::repeated_double_extension , 0));
- EXPECT_EQ(false, message.GetExtension(unittest::repeated_bool_extension , 0));
+ EXPECT_FALSE( message.GetExtension(unittest::repeated_bool_extension , 0));
EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension , 0));
EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension , 0));
@@ -2008,6 +2205,7 @@ void TestUtil::ExpectRepeatedExtensionsSwapped(
EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb());
EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c());
EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension , 0).d());
+ EXPECT_EQ(327, message.GetExtension(unittest::repeated_lazy_message_extension , 0).bb());
EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::repeated_nested_enum_extension , 0));
EXPECT_EQ(unittest::FOREIGN_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension, 0));
@@ -2017,6 +2215,92 @@ void TestUtil::ExpectRepeatedExtensionsSwapped(
EXPECT_EQ("325", message.GetExtension(unittest::repeated_cord_extension, 0));
}
+void TestUtil::SetOneof1(unittest::TestOneof2* message) {
+ message->mutable_foo_lazy_message()->set_qux_int(100);
+ message->set_bar_string("101");
+ message->set_baz_int(102);
+ message->set_baz_string("103");
+}
+
+void TestUtil::SetOneof2(unittest::TestOneof2* message) {
+ message->set_foo_int(200);
+ message->set_bar_enum(unittest::TestOneof2::BAZ);
+ message->set_baz_int(202);
+ message->set_baz_string("203");
+}
+
+void TestUtil::ExpectOneofSet1(const unittest::TestOneof2& message) {
+ ExpectAtMostOneFieldSetInOneof(message);
+
+ EXPECT_TRUE(message.has_foo_lazy_message ());
+ EXPECT_TRUE(message.foo_lazy_message().has_qux_int());
+
+ EXPECT_TRUE(message.has_bar_string());
+ EXPECT_TRUE(message.has_baz_int ());
+ EXPECT_TRUE(message.has_baz_string());
+
+ ASSERT_EQ(0, message.foo_lazy_message().corge_int_size());
+
+ EXPECT_EQ(100 , message.foo_lazy_message().qux_int());
+ EXPECT_EQ("101", message.bar_string ());
+ EXPECT_EQ(102 , message.baz_int ());
+ EXPECT_EQ("103", message.baz_string ());
+}
+
+void TestUtil::ExpectOneofSet2(const unittest::TestOneof2& message) {
+ ExpectAtMostOneFieldSetInOneof(message);
+
+ EXPECT_TRUE(message.has_foo_int ());
+ EXPECT_TRUE(message.has_bar_enum ());
+ EXPECT_TRUE(message.has_baz_int ());
+ EXPECT_TRUE(message.has_baz_string());
+
+ EXPECT_EQ(200 , message.foo_int ());
+ EXPECT_EQ(unittest::TestOneof2::BAZ, message.bar_enum ());
+ EXPECT_EQ(202 , message.baz_int ());
+ EXPECT_EQ("203" , message.baz_string());
+}
+
+void TestUtil::ExpectOneofClear(const unittest::TestOneof2& message) {
+ EXPECT_FALSE(message.has_foo_int());
+ EXPECT_FALSE(message.has_foo_string());
+ EXPECT_FALSE(message.has_foo_bytes());
+ EXPECT_FALSE(message.has_foo_enum());
+ EXPECT_FALSE(message.has_foo_message());
+ EXPECT_FALSE(message.has_foogroup());
+ EXPECT_FALSE(message.has_foo_lazy_message());
+
+ EXPECT_FALSE(message.has_bar_int());
+ EXPECT_FALSE(message.has_bar_string());
+ EXPECT_FALSE(message.has_bar_bytes());
+ EXPECT_FALSE(message.has_bar_enum());
+
+ EXPECT_FALSE(message.has_baz_int());
+ EXPECT_FALSE(message.has_baz_string());
+
+ EXPECT_EQ(unittest::TestOneof2::FOO_NOT_SET, message.foo_case());
+ EXPECT_EQ(unittest::TestOneof2::BAR_NOT_SET, message.bar_case());
+}
+
+void TestUtil::ExpectAtMostOneFieldSetInOneof(
+ const unittest::TestOneof2& message) {
+ int count = 0;
+ if (message.has_foo_int()) count++;
+ if (message.has_foo_string()) count++;
+ if (message.has_foo_bytes()) count++;
+ if (message.has_foo_enum()) count++;
+ if (message.has_foo_message()) count++;
+ if (message.has_foogroup()) count++;
+ if (message.has_foo_lazy_message()) count++;
+ EXPECT_LE(count, 1);
+ count = 0;
+ if (message.has_bar_int()) count++;
+ if (message.has_bar_string()) count++;
+ if (message.has_bar_bytes()) count++;
+ if (message.has_bar_enum()) count++;
+ EXPECT_TRUE(count == 0 || count == 1);
+}
+
// ===================================================================
TestUtil::ReflectionTester::ReflectionTester(
@@ -2031,6 +2315,8 @@ TestUtil::ReflectionTester::ReflectionTester(
pool->FindFieldByName("protobuf_unittest.ForeignMessage.c");
import_d_ =
pool->FindFieldByName("protobuf_unittest_import.ImportMessage.d");
+ import_e_ =
+ pool->FindFieldByName("protobuf_unittest_import.PublicImportMessage.e");
nested_foo_ =
pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.FOO");
nested_bar_ =
@@ -2067,6 +2353,7 @@ TestUtil::ReflectionTester::ReflectionTester(
EXPECT_TRUE(nested_b_ != NULL);
EXPECT_TRUE(foreign_c_ != NULL);
EXPECT_TRUE(import_d_ != NULL);
+ EXPECT_TRUE(import_e_ != NULL);
EXPECT_TRUE(nested_foo_ != NULL);
EXPECT_TRUE(nested_bar_ != NULL);
EXPECT_TRUE(nested_baz_ != NULL);
@@ -2129,6 +2416,12 @@ void TestUtil::ReflectionTester::SetAllFieldsViaReflection(Message* message) {
reflection->SetString(message, F("optional_string_piece"), "124");
reflection->SetString(message, F("optional_cord"), "125");
+ sub_message = reflection->MutableMessage(message, F("optional_public_import_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, import_e_, 126);
+
+ sub_message = reflection->MutableMessage(message, F("optional_lazy_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 127);
+
// -----------------------------------------------------------------
reflection->AddInt32 (message, F("repeated_int32" ), 201);
@@ -2155,6 +2448,8 @@ void TestUtil::ReflectionTester::SetAllFieldsViaReflection(Message* message) {
sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 219);
sub_message = reflection->AddMessage(message, F("repeated_import_message"));
sub_message->GetReflection()->SetInt32(sub_message, import_d_, 220);
+ sub_message = reflection->AddMessage(message, F("repeated_lazy_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 227);
reflection->AddEnum(message, F("repeated_nested_enum" ), nested_bar_);
reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_bar_);
@@ -2188,6 +2483,8 @@ void TestUtil::ReflectionTester::SetAllFieldsViaReflection(Message* message) {
sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 319);
sub_message = reflection->AddMessage(message, F("repeated_import_message"));
sub_message->GetReflection()->SetInt32(sub_message, import_d_, 320);
+ sub_message = reflection->AddMessage(message, F("repeated_lazy_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 327);
reflection->AddEnum(message, F("repeated_nested_enum" ), nested_baz_);
reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_baz_);
@@ -2220,6 +2517,69 @@ void TestUtil::ReflectionTester::SetAllFieldsViaReflection(Message* message) {
reflection->SetString(message, F("default_string_piece"), "424");
reflection->SetString(message, F("default_cord"), "425");
+
+ reflection->SetUInt32(message, F("oneof_uint32" ), 601);
+ sub_message = reflection->MutableMessage(message, F("oneof_nested_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 602);
+ reflection->SetString(message, F("oneof_string"), "603");
+ reflection->SetString(message, F("oneof_bytes" ), "604");
+}
+
+void TestUtil::ReflectionTester::SetOneofViaReflection(Message* message) {
+ const Descriptor* descriptor = message->GetDescriptor();
+ const Reflection* reflection = message->GetReflection();
+ Message* sub_message = reflection->MutableMessage(
+ message, descriptor->FindFieldByName("foo_lazy_message"));
+ sub_message->GetReflection()->SetInt64(
+ sub_message,
+ descriptor->file()->pool()->FindFieldByName(
+ "protobuf_unittest.TestOneof2.NestedMessage.qux_int"),
+ 100);
+
+ reflection->SetString(message,
+ descriptor->FindFieldByName("bar_cord"),
+ "101");
+ reflection->SetInt32(message,
+ descriptor->FindFieldByName("baz_int"),
+ 102);
+ reflection->SetString(message,
+ descriptor->FindFieldByName("baz_string"),
+ "103");
+}
+
+void TestUtil::ReflectionTester::ExpectOneofSetViaReflection(
+ const Message& message) {
+ const Descriptor* descriptor = message.GetDescriptor();
+ const Reflection* reflection = message.GetReflection();
+ string scratch;
+ EXPECT_TRUE(reflection->HasField(
+ message, descriptor->FindFieldByName("foo_lazy_message")));
+ EXPECT_TRUE(reflection->HasField(
+ message, descriptor->FindFieldByName("bar_cord")));
+ EXPECT_TRUE(reflection->HasField(
+ message, descriptor->FindFieldByName("baz_int")));
+ EXPECT_TRUE(reflection->HasField(
+ message, descriptor->FindFieldByName("baz_string")));
+
+ const Message* sub_message = &reflection->GetMessage(
+ message, descriptor->FindFieldByName("foo_lazy_message"));
+ EXPECT_EQ(100, sub_message->GetReflection()->GetInt64(
+ *sub_message,
+ descriptor->file()->pool()->FindFieldByName(
+ "protobuf_unittest.TestOneof2.NestedMessage.qux_int")));
+
+ EXPECT_EQ("101", reflection->GetString(
+ message, descriptor->FindFieldByName("bar_cord")));
+ EXPECT_EQ("101", reflection->GetStringReference(
+ message, descriptor->FindFieldByName("bar_cord"), &scratch));
+
+ EXPECT_EQ(102, reflection->GetInt32(
+ message, descriptor->FindFieldByName("baz_int")));
+
+ EXPECT_EQ("103", reflection->GetString(
+ message, descriptor->FindFieldByName("baz_string")));
+ EXPECT_EQ("103", reflection->GetStringReference(
+ message, descriptor->FindFieldByName("baz_string"), &scratch));
}
void TestUtil::ReflectionTester::SetPackedFieldsViaReflection(
@@ -2289,10 +2649,12 @@ void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection1(
EXPECT_TRUE(reflection->HasField(message, F("optional_string" )));
EXPECT_TRUE(reflection->HasField(message, F("optional_bytes" )));
- EXPECT_TRUE(reflection->HasField(message, F("optionalgroup" )));
- EXPECT_TRUE(reflection->HasField(message, F("optional_nested_message" )));
- EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_message")));
- EXPECT_TRUE(reflection->HasField(message, F("optional_import_message" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optionalgroup" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_nested_message" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_message" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_import_message" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_public_import_message")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_lazy_message" )));
sub_message = &reflection->GetMessage(message, F("optionalgroup"));
EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, group_a_));
@@ -2302,6 +2664,10 @@ void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection1(
EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_));
sub_message = &reflection->GetMessage(message, F("optional_import_message"));
EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, import_d_));
+ sub_message = &reflection->GetMessage(message, F("optional_public_import_message"));
+ EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, import_e_));
+ sub_message = &reflection->GetMessage(message, F("optional_lazy_message"));
+ EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
EXPECT_TRUE(reflection->HasField(message, F("optional_nested_enum" )));
EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_enum")));
@@ -2322,7 +2688,7 @@ void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection1(
EXPECT_EQ(110 , reflection->GetInt64 (message, F("optional_sfixed64")));
EXPECT_EQ(111 , reflection->GetFloat (message, F("optional_float" )));
EXPECT_EQ(112 , reflection->GetDouble(message, F("optional_double" )));
- EXPECT_EQ(true , reflection->GetBool (message, F("optional_bool" )));
+ EXPECT_TRUE( reflection->GetBool (message, F("optional_bool" )));
EXPECT_EQ("115", reflection->GetString(message, F("optional_string" )));
EXPECT_EQ("116", reflection->GetString(message, F("optional_bytes" )));
@@ -2337,6 +2703,10 @@ void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection1(
EXPECT_EQ(119, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
sub_message = &reflection->GetMessage(message, F("optional_import_message"));
EXPECT_EQ(120, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+ sub_message = &reflection->GetMessage(message, F("optional_public_import_message"));
+ EXPECT_EQ(126, sub_message->GetReflection()->GetInt32(*sub_message, import_e_));
+ sub_message = &reflection->GetMessage(message, F("optional_lazy_message"));
+ EXPECT_EQ(127, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
EXPECT_EQ( nested_baz_, reflection->GetEnum(message, F("optional_nested_enum" )));
EXPECT_EQ(foreign_baz_, reflection->GetEnum(message, F("optional_foreign_enum")));
@@ -2347,6 +2717,21 @@ void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection1(
EXPECT_EQ("125", reflection->GetString(message, F("optional_cord")));
EXPECT_EQ("125", reflection->GetStringReference(message, F("optional_cord"), &scratch));
+
+ EXPECT_TRUE(reflection->HasField(message, F("oneof_bytes" )));
+ EXPECT_EQ("604", reflection->GetString(message, F("oneof_bytes" )));
+
+ if (base_descriptor_->name() == "TestAllTypes") {
+ EXPECT_FALSE(reflection->HasField(message, F("oneof_uint32")));
+ EXPECT_FALSE(reflection->HasField(message, F("oneof_string")));
+ } else {
+ EXPECT_TRUE(reflection->HasField(message, F("oneof_uint32")));
+ EXPECT_TRUE(reflection->HasField(message, F("oneof_string")));
+ EXPECT_EQ(601 , reflection->GetUInt32(message, F("oneof_uint32")));
+ EXPECT_EQ("603", reflection->GetString(message, F("oneof_string")));
+ sub_message = &reflection->GetMessage(message, F("oneof_nested_message"));
+ EXPECT_EQ(602, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+ }
}
void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection2(
@@ -2377,6 +2762,7 @@ void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection2(
ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_message" )));
ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_message")));
ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_message" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_lazy_message" )));
ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_enum" )));
ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_enum" )));
ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_enum" )));
@@ -2396,7 +2782,7 @@ void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection2(
EXPECT_EQ(210 , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 0));
EXPECT_EQ(211 , reflection->GetRepeatedFloat (message, F("repeated_float" ), 0));
EXPECT_EQ(212 , reflection->GetRepeatedDouble(message, F("repeated_double" ), 0));
- EXPECT_EQ(true , reflection->GetRepeatedBool (message, F("repeated_bool" ), 0));
+ EXPECT_TRUE( reflection->GetRepeatedBool (message, F("repeated_bool" ), 0));
EXPECT_EQ("215", reflection->GetRepeatedString(message, F("repeated_string" ), 0));
EXPECT_EQ("216", reflection->GetRepeatedString(message, F("repeated_bytes" ), 0));
@@ -2411,6 +2797,8 @@ void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection2(
EXPECT_EQ(219, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 0);
EXPECT_EQ(220, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+ sub_message = &reflection->GetRepeatedMessage(message, F("repeated_lazy_message"), 0);
+ EXPECT_EQ(227, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
EXPECT_EQ( nested_bar_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),0));
EXPECT_EQ(foreign_bar_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),0));
@@ -2436,7 +2824,7 @@ void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection2(
EXPECT_EQ(310 , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 1));
EXPECT_EQ(311 , reflection->GetRepeatedFloat (message, F("repeated_float" ), 1));
EXPECT_EQ(312 , reflection->GetRepeatedDouble(message, F("repeated_double" ), 1));
- EXPECT_EQ(false, reflection->GetRepeatedBool (message, F("repeated_bool" ), 1));
+ EXPECT_FALSE( reflection->GetRepeatedBool (message, F("repeated_bool" ), 1));
EXPECT_EQ("315", reflection->GetRepeatedString(message, F("repeated_string" ), 1));
EXPECT_EQ("316", reflection->GetRepeatedString(message, F("repeated_bytes" ), 1));
@@ -2453,6 +2841,8 @@ void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection2(
EXPECT_EQ(319, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 1);
EXPECT_EQ(320, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+ sub_message = &reflection->GetRepeatedMessage(message, F("repeated_lazy_message"), 1);
+ EXPECT_EQ(327, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
EXPECT_EQ( nested_baz_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),1));
EXPECT_EQ(foreign_baz_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),1));
@@ -2509,7 +2899,7 @@ void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection3(
EXPECT_EQ(410 , reflection->GetInt64 (message, F("default_sfixed64")));
EXPECT_EQ(411 , reflection->GetFloat (message, F("default_float" )));
EXPECT_EQ(412 , reflection->GetDouble(message, F("default_double" )));
- EXPECT_EQ(false, reflection->GetBool (message, F("default_bool" )));
+ EXPECT_FALSE( reflection->GetBool (message, F("default_bool" )));
EXPECT_EQ("415", reflection->GetString(message, F("default_string" )));
EXPECT_EQ("416", reflection->GetString(message, F("default_bytes" )));
@@ -2559,7 +2949,7 @@ void TestUtil::ReflectionTester::ExpectPackedFieldsSetViaReflection(
EXPECT_EQ(610 , reflection->GetRepeatedInt64 (message, F("packed_sfixed64"), 0));
EXPECT_EQ(611 , reflection->GetRepeatedFloat (message, F("packed_float" ), 0));
EXPECT_EQ(612 , reflection->GetRepeatedDouble(message, F("packed_double" ), 0));
- EXPECT_EQ(true , reflection->GetRepeatedBool (message, F("packed_bool" ), 0));
+ EXPECT_TRUE( reflection->GetRepeatedBool (message, F("packed_bool" ), 0));
EXPECT_EQ(foreign_bar_,
reflection->GetRepeatedEnum(message, F("packed_enum"), 0));
@@ -2575,7 +2965,7 @@ void TestUtil::ReflectionTester::ExpectPackedFieldsSetViaReflection(
EXPECT_EQ(710 , reflection->GetRepeatedInt64 (message, F("packed_sfixed64"), 1));
EXPECT_EQ(711 , reflection->GetRepeatedFloat (message, F("packed_float" ), 1));
EXPECT_EQ(712 , reflection->GetRepeatedDouble(message, F("packed_double" ), 1));
- EXPECT_EQ(false, reflection->GetRepeatedBool (message, F("packed_bool" ), 1));
+ EXPECT_FALSE( reflection->GetRepeatedBool (message, F("packed_bool" ), 1));
EXPECT_EQ(foreign_baz_,
reflection->GetRepeatedEnum(message, F("packed_enum"), 1));
}
@@ -2609,6 +2999,8 @@ void TestUtil::ReflectionTester::ExpectClearViaReflection(
EXPECT_FALSE(reflection->HasField(message, F("optional_nested_message" )));
EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_message")));
EXPECT_FALSE(reflection->HasField(message, F("optional_import_message" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_public_import_message")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_lazy_message")));
EXPECT_FALSE(reflection->HasField(message, F("optional_nested_enum" )));
EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_enum")));
@@ -2630,7 +3022,7 @@ void TestUtil::ReflectionTester::ExpectClearViaReflection(
EXPECT_EQ(0 , reflection->GetInt64 (message, F("optional_sfixed64")));
EXPECT_EQ(0 , reflection->GetFloat (message, F("optional_float" )));
EXPECT_EQ(0 , reflection->GetDouble(message, F("optional_double" )));
- EXPECT_EQ(false, reflection->GetBool (message, F("optional_bool" )));
+ EXPECT_FALSE( reflection->GetBool (message, F("optional_bool" )));
EXPECT_EQ("" , reflection->GetString(message, F("optional_string" )));
EXPECT_EQ("" , reflection->GetString(message, F("optional_bytes" )));
@@ -2650,6 +3042,12 @@ void TestUtil::ReflectionTester::ExpectClearViaReflection(
sub_message = &reflection->GetMessage(message, F("optional_import_message"));
EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, import_d_));
EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+ sub_message = &reflection->GetMessage(message, F("optional_public_import_message"));
+ EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, import_e_));
+ EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, import_e_));
+ sub_message = &reflection->GetMessage(message, F("optional_lazy_message"));
+ EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
+ EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
// Enums without defaults are set to the first value in the enum.
EXPECT_EQ( nested_foo_, reflection->GetEnum(message, F("optional_nested_enum" )));
@@ -2683,6 +3081,7 @@ void TestUtil::ReflectionTester::ExpectClearViaReflection(
EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_message" )));
EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_message")));
EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_message" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_lazy_message" )));
EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_enum" )));
EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_enum" )));
EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_enum" )));
@@ -2727,7 +3126,7 @@ void TestUtil::ReflectionTester::ExpectClearViaReflection(
EXPECT_EQ(-50 , reflection->GetInt64 (message, F("default_sfixed64")));
EXPECT_EQ( 51.5 , reflection->GetFloat (message, F("default_float" )));
EXPECT_EQ( 52e3 , reflection->GetDouble(message, F("default_double" )));
- EXPECT_EQ(true , reflection->GetBool (message, F("default_bool" )));
+ EXPECT_TRUE( reflection->GetBool (message, F("default_bool" )));
EXPECT_EQ("hello", reflection->GetString(message, F("default_string" )));
EXPECT_EQ("world", reflection->GetString(message, F("default_bytes" )));
@@ -2796,6 +3195,8 @@ void TestUtil::ReflectionTester::ModifyRepeatedFieldsViaReflection(
sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 519);
sub_message = reflection->MutableRepeatedMessage(message, F("repeated_import_message"), 1);
sub_message->GetReflection()->SetInt32(sub_message, import_d_, 520);
+ sub_message = reflection->MutableRepeatedMessage(message, F("repeated_lazy_message"), 1);
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 527);
reflection->SetRepeatedEnum(message, F("repeated_nested_enum" ), 1, nested_foo_);
reflection->SetRepeatedEnum(message, F("repeated_foreign_enum"), 1, foreign_foo_);
@@ -2824,7 +3225,8 @@ void TestUtil::ReflectionTester::ModifyPackedFieldsViaReflection(
reflection->SetRepeatedEnum (message, F("packed_enum" ), 1, foreign_foo_);
}
-void TestUtil::ReflectionTester::RemoveLastRepeatedsViaReflection(Message* message) {
+void TestUtil::ReflectionTester::RemoveLastRepeatedsViaReflection(
+ Message* message) {
const Reflection* reflection = message->GetReflection();
vector<const FieldDescriptor*> output;
@@ -2837,6 +3239,26 @@ void TestUtil::ReflectionTester::RemoveLastRepeatedsViaReflection(Message* messa
}
}
+void TestUtil::ReflectionTester::ReleaseLastRepeatedsViaReflection(
+ Message* message, bool expect_extensions_notnull) {
+ const Reflection* reflection = message->GetReflection();
+
+ vector<const FieldDescriptor*> output;
+ reflection->ListFields(*message, &output);
+ for (int i=0; i<output.size(); ++i) {
+ const FieldDescriptor* field = output[i];
+ if (!field->is_repeated()) continue;
+ if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
+
+ Message* released = reflection->ReleaseLast(message, field);
+ if (!field->is_extension() || expect_extensions_notnull) {
+ ASSERT_TRUE(released != NULL) << "ReleaseLast returned NULL for: "
+ << field->name();
+ }
+ delete released;
+ }
+}
+
void TestUtil::ReflectionTester::SwapRepeatedsViaReflection(Message* message) {
const Reflection* reflection = message->GetReflection();
@@ -2850,5 +3272,74 @@ void TestUtil::ReflectionTester::SwapRepeatedsViaReflection(Message* message) {
}
}
+void TestUtil::ReflectionTester::
+SetAllocatedOptionalMessageFieldsToNullViaReflection(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+
+ vector<const FieldDescriptor*> fields;
+ reflection->ListFields(*message, &fields);
+
+ for (int i = 0; i < fields.size(); ++i) {
+ const FieldDescriptor* field = fields[i];
+ if (!field->is_optional() ||
+ field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
+
+ reflection->SetAllocatedMessage(message, NULL, field);
+ }
+}
+
+void TestUtil::ReflectionTester::
+SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ Message* from_message,
+ Message* to_message) {
+ EXPECT_EQ(from_message->GetDescriptor(), to_message->GetDescriptor());
+ const Reflection* from_reflection = from_message->GetReflection();
+ const Reflection* to_reflection = to_message->GetReflection();
+
+ vector<const FieldDescriptor*> fields;
+ from_reflection->ListFields(*from_message, &fields);
+
+ for (int i = 0; i < fields.size(); ++i) {
+ const FieldDescriptor* field = fields[i];
+ if (!field->is_optional() ||
+ field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
+
+ Message* sub_message =
+ from_reflection->ReleaseMessage(from_message, field);
+ to_reflection->SetAllocatedMessage(to_message, sub_message, field);
+ }
+}
+
+void TestUtil::ReflectionTester::ExpectMessagesReleasedViaReflection(
+ Message* message,
+ TestUtil::ReflectionTester::MessageReleaseState expected_release_state) {
+ const Reflection* reflection = message->GetReflection();
+
+ static const char* fields[] = {
+ "optionalgroup",
+ "optional_nested_message",
+ "optional_foreign_message",
+ "optional_import_message",
+ };
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(fields); i++) {
+ const Message& sub_message = reflection->GetMessage(*message, F(fields[i]));
+ Message* released = reflection->ReleaseMessage(message, F(fields[i]));
+ switch (expected_release_state) {
+ case IS_NULL:
+ EXPECT_TRUE(released == NULL);
+ break;
+ case NOT_NULL:
+ EXPECT_TRUE(released != NULL);
+ EXPECT_EQ(&sub_message, released);
+ break;
+ case CAN_BE_NULL:
+ break;
+ }
+ delete released;
+ EXPECT_FALSE(reflection->HasField(*message, F(fields[i])));
+ }
+}
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/test_util.h b/src/google/protobuf/test_util.h
index 25165f3..d449c00 100644
--- a/src/google/protobuf/test_util.h
+++ b/src/google/protobuf/test_util.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -43,18 +43,26 @@
namespace google {
namespace protobuf {
-namespace unittest = protobuf_unittest;
+namespace unittest = ::protobuf_unittest;
namespace unittest_import = protobuf_unittest_import;
class TestUtil {
public:
// Set every field in the message to a unique value.
static void SetAllFields(unittest::TestAllTypes* message);
+ static void SetOptionalFields(unittest::TestAllTypes* message);
+ static void AddRepeatedFields1(unittest::TestAllTypes* message);
+ static void AddRepeatedFields2(unittest::TestAllTypes* message);
+ static void SetDefaultFields(unittest::TestAllTypes* message);
+ static void SetOneofFields(unittest::TestAllTypes* message);
static void SetAllExtensions(unittest::TestAllExtensions* message);
+ static void SetOneofFields(unittest::TestAllExtensions* message);
static void SetAllFieldsAndExtensions(unittest::TestFieldOrderings* message);
static void SetPackedFields(unittest::TestPackedTypes* message);
static void SetPackedExtensions(unittest::TestPackedExtensions* message);
static void SetUnpackedFields(unittest::TestUnpackedTypes* message);
+ static void SetOneof1(unittest::TestOneof2* message);
+ static void SetOneof2(unittest::TestOneof2* message);
// Use the repeated versions of the set_*() accessors to modify all the
// repeated fields of the messsage (which should already have been
@@ -75,6 +83,10 @@ class TestUtil {
const unittest::TestPackedExtensions& message);
static void ExpectUnpackedFieldsSet(
const unittest::TestUnpackedTypes& message);
+ static void ExpectUnpackedExtensionsSet(
+ const unittest::TestUnpackedExtensions& message);
+ static void ExpectOneofSet1(const unittest::TestOneof2& message);
+ static void ExpectOneofSet2(const unittest::TestOneof2& message);
// Expect that the message is modified as would be expected from
// Modify*Fields().
@@ -93,6 +105,7 @@ class TestUtil {
static void ExpectPackedClear(const unittest::TestPackedTypes& message);
static void ExpectPackedExtensionsClear(
const unittest::TestPackedExtensions& message);
+ static void ExpectOneofClear(const unittest::TestOneof2& message);
// Check that the passed-in serialization is the canonical serialization we
// expect for a TestFieldOrderings message filled in by
@@ -104,6 +117,10 @@ class TestUtil {
const unittest::TestAllTypes& message);
static void ExpectLastRepeatedExtensionsRemoved(
const unittest::TestAllExtensions& message);
+ static void ExpectLastRepeatedsReleased(
+ const unittest::TestAllTypes& message);
+ static void ExpectLastRepeatedExtensionsReleased(
+ const unittest::TestAllExtensions& message);
// Check that all repeated fields have had their first and last elements
// swapped.
@@ -111,6 +128,9 @@ class TestUtil {
static void ExpectRepeatedExtensionsSwapped(
const unittest::TestAllExtensions& message);
+ static void ExpectAtMostOneFieldSetInOneof(
+ const unittest::TestOneof2 &message);
+
// Like above, but use the reflection interface.
class ReflectionTester {
public:
@@ -132,7 +152,27 @@ class TestUtil {
void ExpectPackedClearViaReflection(const Message& message);
void RemoveLastRepeatedsViaReflection(Message* message);
+ void ReleaseLastRepeatedsViaReflection(
+ Message* message, bool expect_extensions_notnull);
void SwapRepeatedsViaReflection(Message* message);
+ void SetAllocatedOptionalMessageFieldsToNullViaReflection(
+ Message* message);
+ static void SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ Message* from_message,
+ Message* to_message);
+
+ enum MessageReleaseState {
+ IS_NULL,
+ CAN_BE_NULL,
+ NOT_NULL,
+ };
+ void ExpectMessagesReleasedViaReflection(
+ Message* message, MessageReleaseState expected_release_state);
+
+ // Set and check functions for TestOneof2 messages. No need to construct
+ // the ReflectionTester by TestAllTypes nor TestAllExtensions.
+ static void SetOneofViaReflection(Message* message);
+ static void ExpectOneofSetViaReflection(const Message& message);
private:
const FieldDescriptor* F(const string& name);
@@ -144,6 +184,7 @@ class TestUtil {
const FieldDescriptor* nested_b_;
const FieldDescriptor* foreign_c_;
const FieldDescriptor* import_d_;
+ const FieldDescriptor* import_e_;
const EnumValueDescriptor* nested_foo_;
const EnumValueDescriptor* nested_bar_;
diff --git a/src/google/protobuf/test_util_lite.cc b/src/google/protobuf/test_util_lite.cc
index d7140e0..88eca0a 100644
--- a/src/google/protobuf/test_util_lite.cc
+++ b/src/google/protobuf/test_util_lite.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -62,10 +62,12 @@ void TestUtilLite::SetAllFields(unittest::TestAllTypesLite* message) {
message->set_optional_string ("115");
message->set_optional_bytes ("116");
- message->mutable_optionalgroup ()->set_a(117);
- message->mutable_optional_nested_message ()->set_bb(118);
- message->mutable_optional_foreign_message()->set_c(119);
- message->mutable_optional_import_message ()->set_d(120);
+ message->mutable_optionalgroup ()->set_a(117);
+ message->mutable_optional_nested_message ()->set_bb(118);
+ message->mutable_optional_foreign_message ()->set_c(119);
+ message->mutable_optional_import_message ()->set_d(120);
+ message->mutable_optional_public_import_message()->set_e(126);
+ message->mutable_optional_lazy_message ()->set_bb(127);
message->set_optional_nested_enum (unittest::TestAllTypesLite::BAZ );
message->set_optional_foreign_enum(unittest::FOREIGN_LITE_BAZ );
@@ -94,6 +96,7 @@ void TestUtilLite::SetAllFields(unittest::TestAllTypesLite* message) {
message->add_repeated_nested_message ()->set_bb(218);
message->add_repeated_foreign_message()->set_c(219);
message->add_repeated_import_message ()->set_d(220);
+ message->add_repeated_lazy_message ()->set_bb(227);
message->add_repeated_nested_enum (unittest::TestAllTypesLite::BAR );
message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAR );
@@ -121,6 +124,7 @@ void TestUtilLite::SetAllFields(unittest::TestAllTypesLite* message) {
message->add_repeated_nested_message ()->set_bb(318);
message->add_repeated_foreign_message()->set_c(319);
message->add_repeated_import_message ()->set_d(320);
+ message->add_repeated_lazy_message ()->set_bb(327);
message->add_repeated_nested_enum (unittest::TestAllTypesLite::BAZ );
message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAZ );
@@ -149,6 +153,11 @@ void TestUtilLite::SetAllFields(unittest::TestAllTypesLite* message) {
message->set_default_foreign_enum(unittest::FOREIGN_LITE_FOO );
message->set_default_import_enum (unittest_import::IMPORT_LITE_FOO);
+
+ message->set_oneof_uint32(601);
+ message->mutable_oneof_nested_message()->set_bb(602);
+ message->set_oneof_string("603");
+ message->set_oneof_bytes("604");
}
// -------------------------------------------------------------------
@@ -174,6 +183,7 @@ void TestUtilLite::ModifyRepeatedFields(unittest::TestAllTypesLite* message) {
message->mutable_repeated_nested_message (1)->set_bb(518);
message->mutable_repeated_foreign_message(1)->set_c(519);
message->mutable_repeated_import_message (1)->set_d(520);
+ message->mutable_repeated_lazy_message (1)->set_bb(527);
message->set_repeated_nested_enum (1, unittest::TestAllTypesLite::FOO );
message->set_repeated_foreign_enum(1, unittest::FOREIGN_LITE_FOO );
@@ -201,15 +211,19 @@ void TestUtilLite::ExpectAllFieldsSet(
EXPECT_TRUE(message.has_optional_string ());
EXPECT_TRUE(message.has_optional_bytes ());
- EXPECT_TRUE(message.has_optionalgroup ());
- EXPECT_TRUE(message.has_optional_nested_message ());
- EXPECT_TRUE(message.has_optional_foreign_message());
- EXPECT_TRUE(message.has_optional_import_message ());
+ EXPECT_TRUE(message.has_optionalgroup ());
+ EXPECT_TRUE(message.has_optional_nested_message ());
+ EXPECT_TRUE(message.has_optional_foreign_message ());
+ EXPECT_TRUE(message.has_optional_import_message ());
+ EXPECT_TRUE(message.has_optional_public_import_message());
+ EXPECT_TRUE(message.has_optional_lazy_message ());
- EXPECT_TRUE(message.optionalgroup ().has_a());
- EXPECT_TRUE(message.optional_nested_message ().has_bb());
- EXPECT_TRUE(message.optional_foreign_message().has_c());
- EXPECT_TRUE(message.optional_import_message ().has_d());
+ EXPECT_TRUE(message.optionalgroup ().has_a());
+ EXPECT_TRUE(message.optional_nested_message ().has_bb());
+ EXPECT_TRUE(message.optional_foreign_message ().has_c());
+ EXPECT_TRUE(message.optional_import_message ().has_d());
+ EXPECT_TRUE(message.optional_public_import_message().has_e());
+ EXPECT_TRUE(message.optional_lazy_message ().has_bb());
EXPECT_TRUE(message.has_optional_nested_enum ());
EXPECT_TRUE(message.has_optional_foreign_enum());
@@ -232,10 +246,12 @@ void TestUtilLite::ExpectAllFieldsSet(
EXPECT_EQ("115", message.optional_string ());
EXPECT_EQ("116", message.optional_bytes ());
- EXPECT_EQ(117, message.optionalgroup ().a());
- EXPECT_EQ(118, message.optional_nested_message ().bb());
- EXPECT_EQ(119, message.optional_foreign_message().c());
- EXPECT_EQ(120, message.optional_import_message ().d());
+ EXPECT_EQ(117, message.optionalgroup ().a());
+ EXPECT_EQ(118, message.optional_nested_message ().bb());
+ EXPECT_EQ(119, message.optional_foreign_message ().c());
+ EXPECT_EQ(120, message.optional_import_message ().d());
+ EXPECT_EQ(126, message.optional_public_import_message().e());
+ EXPECT_EQ(127, message.optional_lazy_message ().bb());
EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.optional_nested_enum ());
EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.optional_foreign_enum());
@@ -264,6 +280,7 @@ void TestUtilLite::ExpectAllFieldsSet(
ASSERT_EQ(2, message.repeated_nested_message_size ());
ASSERT_EQ(2, message.repeated_foreign_message_size());
ASSERT_EQ(2, message.repeated_import_message_size ());
+ ASSERT_EQ(2, message.repeated_lazy_message_size ());
ASSERT_EQ(2, message.repeated_nested_enum_size ());
ASSERT_EQ(2, message.repeated_foreign_enum_size ());
ASSERT_EQ(2, message.repeated_import_enum_size ());
@@ -289,6 +306,7 @@ void TestUtilLite::ExpectAllFieldsSet(
EXPECT_EQ(218, message.repeated_nested_message (0).bb());
EXPECT_EQ(219, message.repeated_foreign_message(0).c());
EXPECT_EQ(220, message.repeated_import_message (0).d());
+ EXPECT_EQ(227, message.repeated_lazy_message (0).bb());
EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.repeated_nested_enum (0));
@@ -315,6 +333,7 @@ void TestUtilLite::ExpectAllFieldsSet(
EXPECT_EQ(318, message.repeated_nested_message (1).bb());
EXPECT_EQ(319, message.repeated_foreign_message(1).c());
EXPECT_EQ(320, message.repeated_import_message (1).d());
+ EXPECT_EQ(327, message.repeated_lazy_message (1).bb());
EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.repeated_nested_enum (1));
EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.repeated_foreign_enum(1));
@@ -364,6 +383,13 @@ void TestUtilLite::ExpectAllFieldsSet(
EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.default_foreign_enum());
EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.default_import_enum ());
+
+ EXPECT_FALSE(message.has_oneof_uint32 ());
+ EXPECT_FALSE(message.has_oneof_nested_message());
+ EXPECT_FALSE(message.has_oneof_string ());
+ EXPECT_TRUE(message.has_oneof_bytes ());
+
+ EXPECT_EQ("604", message.oneof_bytes());
}
// -------------------------------------------------------------------
@@ -386,10 +412,12 @@ void TestUtilLite::ExpectClear(const unittest::TestAllTypesLite& message) {
EXPECT_FALSE(message.has_optional_string ());
EXPECT_FALSE(message.has_optional_bytes ());
- EXPECT_FALSE(message.has_optionalgroup ());
- EXPECT_FALSE(message.has_optional_nested_message ());
- EXPECT_FALSE(message.has_optional_foreign_message());
- EXPECT_FALSE(message.has_optional_import_message ());
+ EXPECT_FALSE(message.has_optionalgroup ());
+ EXPECT_FALSE(message.has_optional_nested_message ());
+ EXPECT_FALSE(message.has_optional_foreign_message ());
+ EXPECT_FALSE(message.has_optional_import_message ());
+ EXPECT_FALSE(message.has_optional_public_import_message());
+ EXPECT_FALSE(message.has_optional_lazy_message ());
EXPECT_FALSE(message.has_optional_nested_enum ());
EXPECT_FALSE(message.has_optional_foreign_enum());
@@ -414,10 +442,12 @@ void TestUtilLite::ExpectClear(const unittest::TestAllTypesLite& message) {
EXPECT_EQ("" , message.optional_bytes ());
// Embedded messages should also be clear.
- EXPECT_FALSE(message.optionalgroup ().has_a());
- EXPECT_FALSE(message.optional_nested_message ().has_bb());
- EXPECT_FALSE(message.optional_foreign_message().has_c());
- EXPECT_FALSE(message.optional_import_message ().has_d());
+ EXPECT_FALSE(message.optionalgroup ().has_a());
+ EXPECT_FALSE(message.optional_nested_message ().has_bb());
+ EXPECT_FALSE(message.optional_foreign_message ().has_c());
+ EXPECT_FALSE(message.optional_import_message ().has_d());
+ EXPECT_FALSE(message.optional_public_import_message().has_e());
+ EXPECT_FALSE(message.optional_lazy_message ().has_bb());
EXPECT_EQ(0, message.optionalgroup ().a());
EXPECT_EQ(0, message.optional_nested_message ().bb());
@@ -451,6 +481,7 @@ void TestUtilLite::ExpectClear(const unittest::TestAllTypesLite& message) {
EXPECT_EQ(0, message.repeated_nested_message_size ());
EXPECT_EQ(0, message.repeated_foreign_message_size());
EXPECT_EQ(0, message.repeated_import_message_size ());
+ EXPECT_EQ(0, message.repeated_lazy_message_size ());
EXPECT_EQ(0, message.repeated_nested_enum_size ());
EXPECT_EQ(0, message.repeated_foreign_enum_size ());
EXPECT_EQ(0, message.repeated_import_enum_size ());
@@ -499,6 +530,11 @@ void TestUtilLite::ExpectClear(const unittest::TestAllTypesLite& message) {
EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.default_foreign_enum());
EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.default_import_enum ());
+
+ EXPECT_FALSE(message.has_oneof_uint32 ());
+ EXPECT_FALSE(message.has_oneof_nested_message());
+ EXPECT_FALSE(message.has_oneof_string ());
+ EXPECT_FALSE(message.has_oneof_bytes ());
}
// -------------------------------------------------------------------
@@ -528,6 +564,7 @@ void TestUtilLite::ExpectRepeatedFieldsModified(
ASSERT_EQ(2, message.repeated_nested_message_size ());
ASSERT_EQ(2, message.repeated_foreign_message_size());
ASSERT_EQ(2, message.repeated_import_message_size ());
+ ASSERT_EQ(2, message.repeated_lazy_message_size ());
ASSERT_EQ(2, message.repeated_nested_enum_size ());
ASSERT_EQ(2, message.repeated_foreign_enum_size ());
ASSERT_EQ(2, message.repeated_import_enum_size ());
@@ -553,6 +590,7 @@ void TestUtilLite::ExpectRepeatedFieldsModified(
EXPECT_EQ(218, message.repeated_nested_message (0).bb());
EXPECT_EQ(219, message.repeated_foreign_message(0).c());
EXPECT_EQ(220, message.repeated_import_message (0).d());
+ EXPECT_EQ(227, message.repeated_lazy_message (0).bb());
EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.repeated_nested_enum (0));
EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.repeated_foreign_enum(0));
@@ -580,6 +618,7 @@ void TestUtilLite::ExpectRepeatedFieldsModified(
EXPECT_EQ(518, message.repeated_nested_message (1).bb());
EXPECT_EQ(519, message.repeated_foreign_message(1).c());
EXPECT_EQ(520, message.repeated_import_message (1).d());
+ EXPECT_EQ(527, message.repeated_lazy_message (1).bb());
EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.repeated_nested_enum (1));
EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.repeated_foreign_enum(1));
@@ -787,10 +826,12 @@ void TestUtilLite::SetAllExtensions(unittest::TestAllExtensionsLite* message) {
message->SetExtension(unittest::optional_string_extension_lite , "115");
message->SetExtension(unittest::optional_bytes_extension_lite , "116");
- message->MutableExtension(unittest::optionalgroup_extension_lite )->set_a(117);
- message->MutableExtension(unittest::optional_nested_message_extension_lite )->set_bb(118);
- message->MutableExtension(unittest::optional_foreign_message_extension_lite)->set_c(119);
- message->MutableExtension(unittest::optional_import_message_extension_lite )->set_d(120);
+ message->MutableExtension(unittest::optionalgroup_extension_lite )->set_a(117);
+ message->MutableExtension(unittest::optional_nested_message_extension_lite )->set_bb(118);
+ message->MutableExtension(unittest::optional_foreign_message_extension_lite )->set_c(119);
+ message->MutableExtension(unittest::optional_import_message_extension_lite )->set_d(120);
+ message->MutableExtension(unittest::optional_public_import_message_extension_lite)->set_e(126);
+ message->MutableExtension(unittest::optional_lazy_message_extension_lite )->set_bb(127);
message->SetExtension(unittest::optional_nested_enum_extension_lite , unittest::TestAllTypesLite::BAZ );
message->SetExtension(unittest::optional_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAZ );
@@ -819,6 +860,7 @@ void TestUtilLite::SetAllExtensions(unittest::TestAllExtensionsLite* message) {
message->AddExtension(unittest::repeated_nested_message_extension_lite )->set_bb(218);
message->AddExtension(unittest::repeated_foreign_message_extension_lite)->set_c(219);
message->AddExtension(unittest::repeated_import_message_extension_lite )->set_d(220);
+ message->AddExtension(unittest::repeated_lazy_message_extension_lite )->set_bb(227);
message->AddExtension(unittest::repeated_nested_enum_extension_lite , unittest::TestAllTypesLite::BAR );
message->AddExtension(unittest::repeated_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAR );
@@ -846,6 +888,7 @@ void TestUtilLite::SetAllExtensions(unittest::TestAllExtensionsLite* message) {
message->AddExtension(unittest::repeated_nested_message_extension_lite )->set_bb(318);
message->AddExtension(unittest::repeated_foreign_message_extension_lite)->set_c(319);
message->AddExtension(unittest::repeated_import_message_extension_lite )->set_d(320);
+ message->AddExtension(unittest::repeated_lazy_message_extension_lite )->set_bb(327);
message->AddExtension(unittest::repeated_nested_enum_extension_lite , unittest::TestAllTypesLite::BAZ );
message->AddExtension(unittest::repeated_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAZ );
@@ -874,6 +917,11 @@ void TestUtilLite::SetAllExtensions(unittest::TestAllExtensionsLite* message) {
message->SetExtension(unittest::default_foreign_enum_extension_lite, unittest::FOREIGN_LITE_FOO );
message->SetExtension(unittest::default_import_enum_extension_lite , unittest_import::IMPORT_LITE_FOO);
+
+ message->SetExtension(unittest::oneof_uint32_extension_lite, 601);
+ message->MutableExtension(unittest::oneof_nested_message_extension_lite)->set_bb(602);;
+ message->SetExtension(unittest::oneof_string_extension_lite, "603");
+ message->SetExtension(unittest::oneof_bytes_extension_lite, "604");
}
// -------------------------------------------------------------------
@@ -900,6 +948,7 @@ void TestUtilLite::ModifyRepeatedExtensions(
message->MutableExtension(unittest::repeated_nested_message_extension_lite , 1)->set_bb(518);
message->MutableExtension(unittest::repeated_foreign_message_extension_lite, 1)->set_c(519);
message->MutableExtension(unittest::repeated_import_message_extension_lite , 1)->set_d(520);
+ message->MutableExtension(unittest::repeated_lazy_message_extension_lite , 1)->set_bb(527);
message->SetExtension(unittest::repeated_nested_enum_extension_lite , 1, unittest::TestAllTypesLite::FOO );
message->SetExtension(unittest::repeated_foreign_enum_extension_lite, 1, unittest::FOREIGN_LITE_FOO );
@@ -927,15 +976,19 @@ void TestUtilLite::ExpectAllExtensionsSet(
EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension_lite ));
EXPECT_TRUE(message.HasExtension(unittest::optional_bytes_extension_lite ));
- EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension_lite ));
- EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension_lite ));
- EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension_lite));
- EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_public_import_message_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_lazy_message_extension_lite ));
- EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension_lite ).has_a());
- EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension_lite ).has_bb());
- EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension_lite).has_c());
- EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension_lite ).has_d());
+ EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension_lite ).has_a());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension_lite ).has_bb());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension_lite ).has_c());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension_lite ).has_d());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_public_import_message_extension_lite).has_e());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_lazy_message_extension_lite ).has_bb());
EXPECT_TRUE(message.HasExtension(unittest::optional_nested_enum_extension_lite ));
EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_enum_extension_lite));
@@ -958,10 +1011,12 @@ void TestUtilLite::ExpectAllExtensionsSet(
EXPECT_EQ("115", message.GetExtension(unittest::optional_string_extension_lite ));
EXPECT_EQ("116", message.GetExtension(unittest::optional_bytes_extension_lite ));
- EXPECT_EQ(117, message.GetExtension(unittest::optionalgroup_extension_lite ).a());
- EXPECT_EQ(118, message.GetExtension(unittest::optional_nested_message_extension_lite ).bb());
- EXPECT_EQ(119, message.GetExtension(unittest::optional_foreign_message_extension_lite).c());
- EXPECT_EQ(120, message.GetExtension(unittest::optional_import_message_extension_lite ).d());
+ EXPECT_EQ(117, message.GetExtension(unittest::optionalgroup_extension_lite ).a());
+ EXPECT_EQ(118, message.GetExtension(unittest::optional_nested_message_extension_lite ).bb());
+ EXPECT_EQ(119, message.GetExtension(unittest::optional_foreign_message_extension_lite ).c());
+ EXPECT_EQ(120, message.GetExtension(unittest::optional_import_message_extension_lite ).d());
+ EXPECT_EQ(126, message.GetExtension(unittest::optional_public_import_message_extension_lite).e());
+ EXPECT_EQ(127, message.GetExtension(unittest::optional_lazy_message_extension_lite ).bb());
EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.GetExtension(unittest::optional_nested_enum_extension_lite ));
EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.GetExtension(unittest::optional_foreign_enum_extension_lite));
@@ -990,6 +1045,7 @@ void TestUtilLite::ExpectAllExtensionsSet(
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension_lite ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_lazy_message_extension_lite ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite ));
@@ -1015,6 +1071,7 @@ void TestUtilLite::ExpectAllExtensionsSet(
EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension_lite , 0).bb());
EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0).c());
EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension_lite , 0).d());
+ EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension_lite , 0).bb());
EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 0));
EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0));
@@ -1041,6 +1098,7 @@ void TestUtilLite::ExpectAllExtensionsSet(
EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension_lite , 1).bb());
EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1).c());
EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension_lite , 1).d());
+ EXPECT_EQ(327, message.GetExtension(unittest::repeated_lazy_message_extension_lite , 1).bb());
EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 1));
EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1));
@@ -1090,6 +1148,16 @@ void TestUtilLite::ExpectAllExtensionsSet(
EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::default_foreign_enum_extension_lite));
EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::default_import_enum_extension_lite ));
+
+ EXPECT_TRUE(message.HasExtension(unittest::oneof_uint32_extension_lite));
+ EXPECT_TRUE(message.GetExtension(unittest::oneof_nested_message_extension_lite).has_bb());
+ EXPECT_TRUE(message.HasExtension(unittest::oneof_string_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::oneof_bytes_extension_lite));
+
+ EXPECT_EQ(601, message.GetExtension(unittest::oneof_uint32_extension_lite));
+ EXPECT_EQ(602, message.GetExtension(unittest::oneof_nested_message_extension_lite).bb());
+ EXPECT_EQ("603", message.GetExtension(unittest::oneof_string_extension_lite));
+ EXPECT_EQ("604", message.GetExtension(unittest::oneof_bytes_extension_lite));
}
// -------------------------------------------------------------------
@@ -1118,10 +1186,12 @@ void TestUtilLite::ExpectExtensionsClear(
EXPECT_FALSE(message.HasExtension(unittest::optional_string_extension_lite ));
EXPECT_FALSE(message.HasExtension(unittest::optional_bytes_extension_lite ));
- EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension_lite ));
- EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension_lite ));
- EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension_lite));
- EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_public_import_message_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_lazy_message_extension_lite ));
EXPECT_FALSE(message.HasExtension(unittest::optional_nested_enum_extension_lite ));
EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_enum_extension_lite));
@@ -1146,15 +1216,19 @@ void TestUtilLite::ExpectExtensionsClear(
EXPECT_EQ("" , message.GetExtension(unittest::optional_bytes_extension_lite ));
// Embedded messages should also be clear.
- EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension_lite ).has_a());
- EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension_lite ).has_bb());
- EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension_lite).has_c());
- EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension_lite ).has_d());
-
- EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension_lite ).a());
- EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension_lite ).bb());
- EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension_lite).c());
- EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension_lite ).d());
+ EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension_lite ).has_a());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension_lite ).has_bb());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension_lite ).has_c());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension_lite ).has_d());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_public_import_message_extension_lite).has_e());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_lazy_message_extension_lite ).has_bb());
+
+ EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension_lite ).a());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension_lite ).bb());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension_lite ).c());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension_lite ).d());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_public_import_message_extension_lite).e());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_lazy_message_extension_lite ).bb());
// Enums without defaults are set to the first value in the enum.
EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::optional_nested_enum_extension_lite ));
@@ -1183,6 +1257,7 @@ void TestUtilLite::ExpectExtensionsClear(
EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_message_extension_lite ));
EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite));
EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_message_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_lazy_message_extension_lite ));
EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite ));
EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite ));
EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_enum_extension_lite ));
@@ -1231,6 +1306,11 @@ void TestUtilLite::ExpectExtensionsClear(
EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::default_foreign_enum_extension_lite));
EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::default_import_enum_extension_lite ));
+
+ EXPECT_FALSE(message.HasExtension(unittest::oneof_uint32_extension_lite));
+ EXPECT_FALSE(message.GetExtension(unittest::oneof_nested_message_extension_lite).has_bb());
+ EXPECT_FALSE(message.HasExtension(unittest::oneof_string_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::oneof_bytes_extension_lite));
}
// -------------------------------------------------------------------
@@ -1260,6 +1340,7 @@ void TestUtilLite::ExpectRepeatedExtensionsModified(
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension_lite ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_lazy_message_extension_lite ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite ));
ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite ));
@@ -1285,6 +1366,7 @@ void TestUtilLite::ExpectRepeatedExtensionsModified(
EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension_lite , 0).bb());
EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0).c());
EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension_lite , 0).d());
+ EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension_lite , 0).bb());
EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 0));
EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0));
@@ -1312,6 +1394,7 @@ void TestUtilLite::ExpectRepeatedExtensionsModified(
EXPECT_EQ(518, message.GetExtension(unittest::repeated_nested_message_extension_lite , 1).bb());
EXPECT_EQ(519, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1).c());
EXPECT_EQ(520, message.GetExtension(unittest::repeated_import_message_extension_lite , 1).d());
+ EXPECT_EQ(527, message.GetExtension(unittest::repeated_lazy_message_extension_lite , 1).bb());
EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 1));
EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1));
diff --git a/src/google/protobuf/test_util_lite.h b/src/google/protobuf/test_util_lite.h
index ca35aaa..f250c93 100644
--- a/src/google/protobuf/test_util_lite.h
+++ b/src/google/protobuf/test_util_lite.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/testdata/bad_utf8_string b/src/google/protobuf/testdata/bad_utf8_string
new file mode 100644
index 0000000..a1337ec
--- /dev/null
+++ b/src/google/protobuf/testdata/bad_utf8_string
@@ -0,0 +1 @@
+r \ No newline at end of file
diff --git a/src/google/protobuf/testdata/golden_message b/src/google/protobuf/testdata/golden_message
index 94898e4..0b7e655 100644
--- a/src/google/protobuf/testdata/golden_message
+++ b/src/google/protobuf/testdata/golden_message
Binary files differ
diff --git a/src/google/protobuf/testdata/golden_message_oneof_implemented b/src/google/protobuf/testdata/golden_message_oneof_implemented
new file mode 100644
index 0000000..b48c898
--- /dev/null
+++ b/src/google/protobuf/testdata/golden_message_oneof_implemented
Binary files differ
diff --git a/src/google/protobuf/testdata/text_format_unittest_data.txt b/src/google/protobuf/testdata/text_format_unittest_data.txt
index feea8f7..7a874b5 100644
--- a/src/google/protobuf/testdata/text_format_unittest_data.txt
+++ b/src/google/protobuf/testdata/text_format_unittest_data.txt
@@ -30,6 +30,12 @@ optional_foreign_enum: FOREIGN_BAZ
optional_import_enum: IMPORT_BAZ
optional_string_piece: "124"
optional_cord: "125"
+optional_public_import_message {
+ e: 126
+}
+optional_lazy_message {
+ bb: 127
+}
repeated_int32: 201
repeated_int32: 301
repeated_int64: 202
@@ -94,6 +100,12 @@ repeated_string_piece: "224"
repeated_string_piece: "324"
repeated_cord: "225"
repeated_cord: "325"
+repeated_lazy_message {
+ bb: 227
+}
+repeated_lazy_message {
+ bb: 327
+}
default_int32: 401
default_int64: 402
default_uint32: 403
@@ -114,3 +126,9 @@ default_foreign_enum: FOREIGN_FOO
default_import_enum: IMPORT_FOO
default_string_piece: "424"
default_cord: "425"
+oneof_uint32: 601
+oneof_nested_message {
+ bb: 602
+}
+oneof_string: "603"
+oneof_bytes: "604"
diff --git a/src/google/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt b/src/google/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt
new file mode 100644
index 0000000..ec95e1e
--- /dev/null
+++ b/src/google/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt
@@ -0,0 +1,129 @@
+optional_int32: 101
+optional_int64: 102
+optional_uint32: 103
+optional_uint64: 104
+optional_sint32: 105
+optional_sint64: 106
+optional_fixed32: 107
+optional_fixed64: 108
+optional_sfixed32: 109
+optional_sfixed64: 110
+optional_float: 111
+optional_double: 112
+optional_bool: true
+optional_string: "115"
+optional_bytes: "116"
+OptionalGroup {
+ a: 117
+}
+optional_nested_message {
+ bb: 118
+}
+optional_foreign_message {
+ c: 119
+}
+optional_import_message {
+ d: 120
+}
+optional_nested_enum: BAZ
+optional_foreign_enum: FOREIGN_BAZ
+optional_import_enum: IMPORT_BAZ
+optional_string_piece: "124"
+optional_cord: "125"
+optional_public_import_message {
+ e: 126
+}
+optional_lazy_message {
+ bb: 127
+}
+repeated_int32: 201
+repeated_int32: 301
+repeated_int64: 202
+repeated_int64: 302
+repeated_uint32: 203
+repeated_uint32: 303
+repeated_uint64: 204
+repeated_uint64: 304
+repeated_sint32: 205
+repeated_sint32: 305
+repeated_sint64: 206
+repeated_sint64: 306
+repeated_fixed32: 207
+repeated_fixed32: 307
+repeated_fixed64: 208
+repeated_fixed64: 308
+repeated_sfixed32: 209
+repeated_sfixed32: 309
+repeated_sfixed64: 210
+repeated_sfixed64: 310
+repeated_float: 211
+repeated_float: 311
+repeated_double: 212
+repeated_double: 312
+repeated_bool: true
+repeated_bool: false
+repeated_string: "215"
+repeated_string: "315"
+repeated_bytes: "216"
+repeated_bytes: "316"
+RepeatedGroup {
+ a: 217
+}
+RepeatedGroup {
+ a: 317
+}
+repeated_nested_message {
+ bb: 218
+}
+repeated_nested_message {
+ bb: 318
+}
+repeated_foreign_message {
+ c: 219
+}
+repeated_foreign_message {
+ c: 319
+}
+repeated_import_message {
+ d: 220
+}
+repeated_import_message {
+ d: 320
+}
+repeated_nested_enum: BAR
+repeated_nested_enum: BAZ
+repeated_foreign_enum: FOREIGN_BAR
+repeated_foreign_enum: FOREIGN_BAZ
+repeated_import_enum: IMPORT_BAR
+repeated_import_enum: IMPORT_BAZ
+repeated_string_piece: "224"
+repeated_string_piece: "324"
+repeated_cord: "225"
+repeated_cord: "325"
+repeated_lazy_message {
+ bb: 227
+}
+repeated_lazy_message {
+ bb: 327
+}
+default_int32: 401
+default_int64: 402
+default_uint32: 403
+default_uint64: 404
+default_sint32: 405
+default_sint64: 406
+default_fixed32: 407
+default_fixed64: 408
+default_sfixed32: 409
+default_sfixed64: 410
+default_float: 411
+default_double: 412
+default_bool: false
+default_string: "415"
+default_bytes: "416"
+default_nested_enum: FOO
+default_foreign_enum: FOREIGN_FOO
+default_import_enum: IMPORT_FOO
+default_string_piece: "424"
+default_cord: "425"
+oneof_bytes: "604"
diff --git a/src/google/protobuf/testdata/text_format_unittest_data_pointy.txt b/src/google/protobuf/testdata/text_format_unittest_data_pointy.txt
new file mode 100644
index 0000000..e1011eb
--- /dev/null
+++ b/src/google/protobuf/testdata/text_format_unittest_data_pointy.txt
@@ -0,0 +1,134 @@
+optional_int32: 101
+optional_int64: 102
+optional_uint32: 103
+optional_uint64: 104
+optional_sint32: 105
+optional_sint64: 106
+optional_fixed32: 107
+optional_fixed64: 108
+optional_sfixed32: 109
+optional_sfixed64: 110
+optional_float: 111
+optional_double: 112
+optional_bool: true
+optional_string: "115"
+optional_bytes: "116"
+OptionalGroup <
+ a: 117
+>
+optional_nested_message <
+ bb: 118
+>
+optional_foreign_message <
+ c: 119
+>
+optional_import_message <
+ d: 120
+>
+optional_nested_enum: BAZ
+optional_foreign_enum: FOREIGN_BAZ
+optional_import_enum: IMPORT_BAZ
+optional_string_piece: "124"
+optional_cord: "125"
+optional_public_import_message <
+ e: 126
+>
+optional_lazy_message <
+ bb: 127
+>
+repeated_int32: 201
+repeated_int32: 301
+repeated_int64: 202
+repeated_int64: 302
+repeated_uint32: 203
+repeated_uint32: 303
+repeated_uint64: 204
+repeated_uint64: 304
+repeated_sint32: 205
+repeated_sint32: 305
+repeated_sint64: 206
+repeated_sint64: 306
+repeated_fixed32: 207
+repeated_fixed32: 307
+repeated_fixed64: 208
+repeated_fixed64: 308
+repeated_sfixed32: 209
+repeated_sfixed32: 309
+repeated_sfixed64: 210
+repeated_sfixed64: 310
+repeated_float: 211
+repeated_float: 311
+repeated_double: 212
+repeated_double: 312
+repeated_bool: true
+repeated_bool: false
+repeated_string: "215"
+repeated_string: "315"
+repeated_bytes: "216"
+repeated_bytes: "316"
+RepeatedGroup <
+ a: 217
+>
+RepeatedGroup <
+ a: 317
+>
+repeated_nested_message <
+ bb: 218
+>
+repeated_nested_message <
+ bb: 318
+>
+repeated_foreign_message <
+ c: 219
+>
+repeated_foreign_message <
+ c: 319
+>
+repeated_import_message <
+ d: 220
+>
+repeated_import_message <
+ d: 320
+>
+repeated_nested_enum: BAR
+repeated_nested_enum: BAZ
+repeated_foreign_enum: FOREIGN_BAR
+repeated_foreign_enum: FOREIGN_BAZ
+repeated_import_enum: IMPORT_BAR
+repeated_import_enum: IMPORT_BAZ
+repeated_string_piece: "224"
+repeated_string_piece: "324"
+repeated_cord: "225"
+repeated_cord: "325"
+repeated_lazy_message <
+ bb: 227
+>
+repeated_lazy_message <
+ bb: 327
+>
+default_int32: 401
+default_int64: 402
+default_uint32: 403
+default_uint64: 404
+default_sint32: 405
+default_sint64: 406
+default_fixed32: 407
+default_fixed64: 408
+default_sfixed32: 409
+default_sfixed64: 410
+default_float: 411
+default_double: 412
+default_bool: false
+default_string: "415"
+default_bytes: "416"
+default_nested_enum: FOO
+default_foreign_enum: FOREIGN_FOO
+default_import_enum: IMPORT_FOO
+default_string_piece: "424"
+default_cord: "425"
+oneof_uint32: 601
+oneof_nested_message <
+ bb: 602
+>
+oneof_string: "603"
+oneof_bytes: "604"
diff --git a/src/google/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt b/src/google/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt
new file mode 100644
index 0000000..95109f6
--- /dev/null
+++ b/src/google/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt
@@ -0,0 +1,129 @@
+optional_int32: 101
+optional_int64: 102
+optional_uint32: 103
+optional_uint64: 104
+optional_sint32: 105
+optional_sint64: 106
+optional_fixed32: 107
+optional_fixed64: 108
+optional_sfixed32: 109
+optional_sfixed64: 110
+optional_float: 111
+optional_double: 112
+optional_bool: true
+optional_string: "115"
+optional_bytes: "116"
+OptionalGroup <
+ a: 117
+>
+optional_nested_message <
+ bb: 118
+>
+optional_foreign_message <
+ c: 119
+>
+optional_import_message <
+ d: 120
+>
+optional_nested_enum: BAZ
+optional_foreign_enum: FOREIGN_BAZ
+optional_import_enum: IMPORT_BAZ
+optional_string_piece: "124"
+optional_cord: "125"
+optional_public_import_message <
+ e: 126
+>
+optional_lazy_message <
+ bb: 127
+>
+repeated_int32: 201
+repeated_int32: 301
+repeated_int64: 202
+repeated_int64: 302
+repeated_uint32: 203
+repeated_uint32: 303
+repeated_uint64: 204
+repeated_uint64: 304
+repeated_sint32: 205
+repeated_sint32: 305
+repeated_sint64: 206
+repeated_sint64: 306
+repeated_fixed32: 207
+repeated_fixed32: 307
+repeated_fixed64: 208
+repeated_fixed64: 308
+repeated_sfixed32: 209
+repeated_sfixed32: 309
+repeated_sfixed64: 210
+repeated_sfixed64: 310
+repeated_float: 211
+repeated_float: 311
+repeated_double: 212
+repeated_double: 312
+repeated_bool: true
+repeated_bool: false
+repeated_string: "215"
+repeated_string: "315"
+repeated_bytes: "216"
+repeated_bytes: "316"
+RepeatedGroup <
+ a: 217
+>
+RepeatedGroup <
+ a: 317
+>
+repeated_nested_message <
+ bb: 218
+>
+repeated_nested_message <
+ bb: 318
+>
+repeated_foreign_message <
+ c: 219
+>
+repeated_foreign_message <
+ c: 319
+>
+repeated_import_message <
+ d: 220
+>
+repeated_import_message <
+ d: 320
+>
+repeated_nested_enum: BAR
+repeated_nested_enum: BAZ
+repeated_foreign_enum: FOREIGN_BAR
+repeated_foreign_enum: FOREIGN_BAZ
+repeated_import_enum: IMPORT_BAR
+repeated_import_enum: IMPORT_BAZ
+repeated_string_piece: "224"
+repeated_string_piece: "324"
+repeated_cord: "225"
+repeated_cord: "325"
+repeated_lazy_message <
+ bb: 227
+>
+repeated_lazy_message <
+ bb: 327
+>
+default_int32: 401
+default_int64: 402
+default_uint32: 403
+default_uint64: 404
+default_sint32: 405
+default_sint64: 406
+default_fixed32: 407
+default_fixed64: 408
+default_sfixed32: 409
+default_sfixed64: 410
+default_float: 411
+default_double: 412
+default_bool: false
+default_string: "415"
+default_bytes: "416"
+default_nested_enum: FOO
+default_foreign_enum: FOREIGN_FOO
+default_import_enum: IMPORT_FOO
+default_string_piece: "424"
+default_cord: "425"
+oneof_bytes: "604"
diff --git a/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt b/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt
index 057beae..8c8b1eb 100644
--- a/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt
+++ b/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt
@@ -30,6 +30,12 @@
[protobuf_unittest.optional_import_enum_extension]: IMPORT_BAZ
[protobuf_unittest.optional_string_piece_extension]: "124"
[protobuf_unittest.optional_cord_extension]: "125"
+[protobuf_unittest.optional_public_import_message_extension] {
+ e: 126
+}
+[protobuf_unittest.optional_lazy_message_extension] {
+ bb: 127
+}
[protobuf_unittest.repeated_int32_extension]: 201
[protobuf_unittest.repeated_int32_extension]: 301
[protobuf_unittest.repeated_int64_extension]: 202
@@ -94,6 +100,12 @@
[protobuf_unittest.repeated_string_piece_extension]: "324"
[protobuf_unittest.repeated_cord_extension]: "225"
[protobuf_unittest.repeated_cord_extension]: "325"
+[protobuf_unittest.repeated_lazy_message_extension] {
+ bb: 227
+}
+[protobuf_unittest.repeated_lazy_message_extension] {
+ bb: 327
+}
[protobuf_unittest.default_int32_extension]: 401
[protobuf_unittest.default_int64_extension]: 402
[protobuf_unittest.default_uint32_extension]: 403
@@ -114,3 +126,9 @@
[protobuf_unittest.default_import_enum_extension]: IMPORT_FOO
[protobuf_unittest.default_string_piece_extension]: "424"
[protobuf_unittest.default_cord_extension]: "425"
+[protobuf_unittest.oneof_uint32_extension]: 601
+[protobuf_unittest.oneof_nested_message_extension] {
+ bb: 602
+}
+[protobuf_unittest.oneof_string_extension]: "603"
+[protobuf_unittest.oneof_bytes_extension]: "604"
diff --git a/src/google/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt b/src/google/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt
new file mode 100644
index 0000000..132f744
--- /dev/null
+++ b/src/google/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt
@@ -0,0 +1,134 @@
+[protobuf_unittest.optional_int32_extension]: 101
+[protobuf_unittest.optional_int64_extension]: 102
+[protobuf_unittest.optional_uint32_extension]: 103
+[protobuf_unittest.optional_uint64_extension]: 104
+[protobuf_unittest.optional_sint32_extension]: 105
+[protobuf_unittest.optional_sint64_extension]: 106
+[protobuf_unittest.optional_fixed32_extension]: 107
+[protobuf_unittest.optional_fixed64_extension]: 108
+[protobuf_unittest.optional_sfixed32_extension]: 109
+[protobuf_unittest.optional_sfixed64_extension]: 110
+[protobuf_unittest.optional_float_extension]: 111
+[protobuf_unittest.optional_double_extension]: 112
+[protobuf_unittest.optional_bool_extension]: true
+[protobuf_unittest.optional_string_extension]: "115"
+[protobuf_unittest.optional_bytes_extension]: "116"
+[protobuf_unittest.optionalgroup_extension] <
+ a: 117
+>
+[protobuf_unittest.optional_nested_message_extension] <
+ bb: 118
+>
+[protobuf_unittest.optional_foreign_message_extension] <
+ c: 119
+>
+[protobuf_unittest.optional_import_message_extension] <
+ d: 120
+>
+[protobuf_unittest.optional_nested_enum_extension]: BAZ
+[protobuf_unittest.optional_foreign_enum_extension]: FOREIGN_BAZ
+[protobuf_unittest.optional_import_enum_extension]: IMPORT_BAZ
+[protobuf_unittest.optional_string_piece_extension]: "124"
+[protobuf_unittest.optional_cord_extension]: "125"
+[protobuf_unittest.optional_public_import_message_extension] <
+ e: 126
+>
+[protobuf_unittest.optional_lazy_message_extension] <
+ bb: 127
+>
+[protobuf_unittest.repeated_int32_extension]: 201
+[protobuf_unittest.repeated_int32_extension]: 301
+[protobuf_unittest.repeated_int64_extension]: 202
+[protobuf_unittest.repeated_int64_extension]: 302
+[protobuf_unittest.repeated_uint32_extension]: 203
+[protobuf_unittest.repeated_uint32_extension]: 303
+[protobuf_unittest.repeated_uint64_extension]: 204
+[protobuf_unittest.repeated_uint64_extension]: 304
+[protobuf_unittest.repeated_sint32_extension]: 205
+[protobuf_unittest.repeated_sint32_extension]: 305
+[protobuf_unittest.repeated_sint64_extension]: 206
+[protobuf_unittest.repeated_sint64_extension]: 306
+[protobuf_unittest.repeated_fixed32_extension]: 207
+[protobuf_unittest.repeated_fixed32_extension]: 307
+[protobuf_unittest.repeated_fixed64_extension]: 208
+[protobuf_unittest.repeated_fixed64_extension]: 308
+[protobuf_unittest.repeated_sfixed32_extension]: 209
+[protobuf_unittest.repeated_sfixed32_extension]: 309
+[protobuf_unittest.repeated_sfixed64_extension]: 210
+[protobuf_unittest.repeated_sfixed64_extension]: 310
+[protobuf_unittest.repeated_float_extension]: 211
+[protobuf_unittest.repeated_float_extension]: 311
+[protobuf_unittest.repeated_double_extension]: 212
+[protobuf_unittest.repeated_double_extension]: 312
+[protobuf_unittest.repeated_bool_extension]: true
+[protobuf_unittest.repeated_bool_extension]: false
+[protobuf_unittest.repeated_string_extension]: "215"
+[protobuf_unittest.repeated_string_extension]: "315"
+[protobuf_unittest.repeated_bytes_extension]: "216"
+[protobuf_unittest.repeated_bytes_extension]: "316"
+[protobuf_unittest.repeatedgroup_extension] <
+ a: 217
+>
+[protobuf_unittest.repeatedgroup_extension] <
+ a: 317
+>
+[protobuf_unittest.repeated_nested_message_extension] <
+ bb: 218
+>
+[protobuf_unittest.repeated_nested_message_extension] <
+ bb: 318
+>
+[protobuf_unittest.repeated_foreign_message_extension] <
+ c: 219
+>
+[protobuf_unittest.repeated_foreign_message_extension] <
+ c: 319
+>
+[protobuf_unittest.repeated_import_message_extension] <
+ d: 220
+>
+[protobuf_unittest.repeated_import_message_extension] <
+ d: 320
+>
+[protobuf_unittest.repeated_nested_enum_extension]: BAR
+[protobuf_unittest.repeated_nested_enum_extension]: BAZ
+[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAR
+[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAZ
+[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAR
+[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAZ
+[protobuf_unittest.repeated_string_piece_extension]: "224"
+[protobuf_unittest.repeated_string_piece_extension]: "324"
+[protobuf_unittest.repeated_cord_extension]: "225"
+[protobuf_unittest.repeated_cord_extension]: "325"
+[protobuf_unittest.repeated_lazy_message_extension] <
+ bb: 227
+>
+[protobuf_unittest.repeated_lazy_message_extension] <
+ bb: 327
+>
+[protobuf_unittest.default_int32_extension]: 401
+[protobuf_unittest.default_int64_extension]: 402
+[protobuf_unittest.default_uint32_extension]: 403
+[protobuf_unittest.default_uint64_extension]: 404
+[protobuf_unittest.default_sint32_extension]: 405
+[protobuf_unittest.default_sint64_extension]: 406
+[protobuf_unittest.default_fixed32_extension]: 407
+[protobuf_unittest.default_fixed64_extension]: 408
+[protobuf_unittest.default_sfixed32_extension]: 409
+[protobuf_unittest.default_sfixed64_extension]: 410
+[protobuf_unittest.default_float_extension]: 411
+[protobuf_unittest.default_double_extension]: 412
+[protobuf_unittest.default_bool_extension]: false
+[protobuf_unittest.default_string_extension]: "415"
+[protobuf_unittest.default_bytes_extension]: "416"
+[protobuf_unittest.default_nested_enum_extension]: FOO
+[protobuf_unittest.default_foreign_enum_extension]: FOREIGN_FOO
+[protobuf_unittest.default_import_enum_extension]: IMPORT_FOO
+[protobuf_unittest.default_string_piece_extension]: "424"
+[protobuf_unittest.default_cord_extension]: "425"
+[protobuf_unittest.oneof_uint32_extension]: 601
+[protobuf_unittest.oneof_nested_message_extension] <
+ bb: 602
+>
+[protobuf_unittest.oneof_string_extension]: "603"
+[protobuf_unittest.oneof_bytes_extension]: "604"
diff --git a/src/google/protobuf/testing/file.cc b/src/google/protobuf/testing/file.cc
index e224781..20e01a1 100644
--- a/src/google/protobuf/testing/file.cc
+++ b/src/google/protobuf/testing/file.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -82,6 +82,24 @@ void File::ReadFileToStringOrDie(const string& name, string* output) {
GOOGLE_CHECK(ReadFileToString(name, output)) << "Could not read: " << name;
}
+bool File::WriteStringToFile(const string& contents, const string& name) {
+ FILE* file = fopen(name.c_str(), "wb");
+ if (file == NULL) {
+ GOOGLE_LOG(ERROR) << "fopen(" << name << ", \"wb\"): " << strerror(errno);
+ return false;
+ }
+
+ if (fwrite(contents.data(), 1, contents.size(), file) != contents.size()) {
+ GOOGLE_LOG(ERROR) << "fwrite(" << name << "): " << strerror(errno);
+ return false;
+ }
+
+ if (fclose(file) != 0) {
+ return false;
+ }
+ return true;
+}
+
void File::WriteStringToFileOrDie(const string& contents, const string& name) {
FILE* file = fopen(name.c_str(), "wb");
GOOGLE_CHECK(file != NULL)
diff --git a/src/google/protobuf/testing/file.h b/src/google/protobuf/testing/file.h
index a6b1c76..d2aeabf 100644
--- a/src/google/protobuf/testing/file.h
+++ b/src/google/protobuf/testing/file.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -56,6 +56,10 @@ class File {
static void ReadFileToStringOrDie(const string& name, string* output);
// Create a file and write a string to it.
+ static bool WriteStringToFile(const string& contents,
+ const string& name);
+
+ // Same as above, but crash on failure.
static void WriteStringToFileOrDie(const string& contents,
const string& name);
@@ -73,6 +77,16 @@ class File {
static void DeleteRecursively(const string& name,
void* dummy1, void* dummy2);
+ static bool GetContents(
+ const string& name, string* output, bool /*is_default*/) {
+ return ReadFileToString(name, output);
+ }
+
+ static bool SetContents(
+ const string& name, const string& contents, bool /*is_default*/) {
+ return WriteStringToFile(contents, name);
+ }
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(File);
};
diff --git a/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc
index cd094d0..d72fa5c 100644
--- a/src/google/protobuf/testing/googletest.cc
+++ b/src/google/protobuf/testing/googletest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -223,16 +223,17 @@ ScopedMemoryLog::~ScopedMemoryLog() {
active_log_ = NULL;
}
-const vector<string>& ScopedMemoryLog::GetMessages(LogLevel dummy) const {
- GOOGLE_CHECK_EQ(dummy, ERROR);
- return messages_;
+const vector<string>& ScopedMemoryLog::GetMessages(LogLevel level) {
+ GOOGLE_CHECK(level == ERROR ||
+ level == WARNING);
+ return messages_[level];
}
void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename,
int line, const string& message) {
GOOGLE_CHECK(active_log_ != NULL);
- if (level == ERROR) {
- active_log_->messages_.push_back(message);
+ if (level == ERROR || level == WARNING) {
+ active_log_->messages_[level].push_back(message);
}
}
diff --git a/src/google/protobuf/testing/googletest.h b/src/google/protobuf/testing/googletest.h
index 71444c9..c0d99e6 100644
--- a/src/google/protobuf/testing/googletest.h
+++ b/src/google/protobuf/testing/googletest.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -34,9 +34,15 @@
#ifndef GOOGLE_PROTOBUF_GOOGLETEST_H__
#define GOOGLE_PROTOBUF_GOOGLETEST_H__
+#include <map>
#include <vector>
#include <google/protobuf/stubs/common.h>
+// Disable death tests if we use exceptions in CHECK().
+#if !PROTOBUF_USE_EXCEPTIONS && defined(GTEST_HAS_DEATH_TEST)
+#define PROTOBUF_HAS_DEATH_TEST
+#endif
+
namespace google {
namespace protobuf {
@@ -60,6 +66,7 @@ string GetCapturedTestStderr();
// ScopedMemoryLog refers to LOGLEVEL_ERROR as just ERROR.
#undef ERROR // defend against promiscuous windows.h
static const LogLevel ERROR = LOGLEVEL_ERROR;
+static const LogLevel WARNING = LOGLEVEL_WARNING;
// Receives copies of all LOG(ERROR) messages while in scope. Sample usage:
// {
@@ -74,14 +81,11 @@ class ScopedMemoryLog {
ScopedMemoryLog();
virtual ~ScopedMemoryLog();
- // Fetches all messages logged. The internal version of this class
- // would only fetch messages at the given security level, but the protobuf
- // open source version ignores the argument since we always pass ERROR
- // anyway.
- const vector<string>& GetMessages(LogLevel dummy) const;
+ // Fetches all messages with the given severity level.
+ const vector<string>& GetMessages(LogLevel error);
private:
- vector<string> messages_;
+ map<LogLevel, vector<string> > messages_;
LogHandler* old_handler_;
static void HandleLog(LogLevel level, const char* filename, int line,
diff --git a/src/google/protobuf/testing/zcgunzip.cc b/src/google/protobuf/testing/zcgunzip.cc
index a619785..daf74ff 100644
--- a/src/google/protobuf/testing/zcgunzip.cc
+++ b/src/google/protobuf/testing/zcgunzip.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2009 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/testing/zcgzip.cc b/src/google/protobuf/testing/zcgzip.cc
index 9133275..a410199 100644
--- a/src/google/protobuf/testing/zcgzip.cc
+++ b/src/google/protobuf/testing/zcgzip.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2009 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
index 137cbce..84cdbb5 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,15 +32,18 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#include <algorithm>
#include <float.h>
#include <math.h>
#include <stdio.h>
#include <stack>
#include <limits>
+#include <vector>
#include <google/protobuf/text_format.h>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/wire_format_lite.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>
@@ -48,10 +51,26 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
+namespace {
+
+inline bool IsHexNumber(const string& str) {
+ return (str.length() >= 2 && str[0] == '0' &&
+ (str[1] == 'x' || str[1] == 'X'));
+}
+
+inline bool IsOctNumber(const string& str) {
+ return (str.length() >= 2 && str[0] == '0' &&
+ (str[1] >= '0' && str[1] < '8'));
+}
+
+} // namespace
+
string Message::DebugString() const {
string debug_string;
@@ -93,6 +112,73 @@ void Message::PrintDebugString() const {
// ===========================================================================
+// Implementation of the parse information tree class.
+TextFormat::ParseInfoTree::ParseInfoTree() { }
+
+TextFormat::ParseInfoTree::~ParseInfoTree() {
+ // Remove any nested information trees, as they are owned by this tree.
+ for (NestedMap::iterator it = nested_.begin(); it != nested_.end(); ++it) {
+ STLDeleteElements(&(it->second));
+ }
+}
+
+void TextFormat::ParseInfoTree::RecordLocation(
+ const FieldDescriptor* field,
+ TextFormat::ParseLocation location) {
+ locations_[field].push_back(location);
+}
+
+TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested(
+ const FieldDescriptor* field) {
+ // Owned by us in the map.
+ TextFormat::ParseInfoTree* instance = new TextFormat::ParseInfoTree();
+ vector<TextFormat::ParseInfoTree*>* trees = &nested_[field];
+ GOOGLE_CHECK(trees);
+ trees->push_back(instance);
+ return instance;
+}
+
+void CheckFieldIndex(const FieldDescriptor* field, int index) {
+ if (field == NULL) { return; }
+
+ if (field->is_repeated() && index == -1) {
+ GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. "
+ << "Field: " << field->name();
+ } else if (!field->is_repeated() && index != -1) {
+ GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields."
+ << "Field: " << field->name();
+ }
+}
+
+TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation(
+ const FieldDescriptor* field, int index) const {
+ CheckFieldIndex(field, index);
+ if (index == -1) { index = 0; }
+
+ const vector<TextFormat::ParseLocation>* locations =
+ FindOrNull(locations_, field);
+ if (locations == NULL || index >= locations->size()) {
+ return TextFormat::ParseLocation();
+ }
+
+ return (*locations)[index];
+}
+
+TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested(
+ const FieldDescriptor* field, int index) const {
+ CheckFieldIndex(field, index);
+ if (index == -1) { index = 0; }
+
+ const vector<TextFormat::ParseInfoTree*>* trees = FindOrNull(nested_, field);
+ if (trees == NULL || index >= trees->size()) {
+ return NULL;
+ }
+
+ return (*trees)[index];
+}
+
+
+// ===========================================================================
// Internal class for parsing an ASCII representation of a Protocol Message.
// This class makes use of the Protocol Message compiler's tokenizer found
// in //google/protobuf/io/tokenizer.h. Note that class's Parse
@@ -107,9 +193,10 @@ void Message::PrintDebugString() const {
class TextFormat::Parser::ParserImpl {
public:
- // 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".
+ // Determines if repeated values for non-repeated fields and
+ // oneofs are permitted, e.g., the string "foo: 1 foo: 2" for a
+ // required/optional field named "foo", or "baz: 1 qux: 2"
+ // where "baz" and "qux" are members of the same oneof.
enum SingularOverwritePolicy {
ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained
FORBID_SINGULAR_OVERWRITES = 1, // an error is issued
@@ -118,12 +205,25 @@ class TextFormat::Parser::ParserImpl {
ParserImpl(const Descriptor* root_message_type,
io::ZeroCopyInputStream* input_stream,
io::ErrorCollector* error_collector,
- SingularOverwritePolicy singular_overwrite_policy)
+ TextFormat::Finder* finder,
+ ParseInfoTree* parse_info_tree,
+ SingularOverwritePolicy singular_overwrite_policy,
+ bool allow_case_insensitive_field,
+ bool allow_unknown_field,
+ bool allow_unknown_enum,
+ bool allow_field_number,
+ bool allow_relaxed_whitespace)
: error_collector_(error_collector),
+ finder_(finder),
+ parse_info_tree_(parse_info_tree),
tokenizer_error_collector_(this),
tokenizer_(input_stream, &tokenizer_error_collector_),
root_message_type_(root_message_type),
singular_overwrite_policy_(singular_overwrite_policy),
+ allow_case_insensitive_field_(allow_case_insensitive_field),
+ allow_unknown_field_(allow_unknown_field),
+ allow_unknown_enum_(allow_unknown_enum),
+ allow_field_number_(allow_field_number),
had_errors_(false) {
// For backwards-compatibility with proto1, we need to allow the 'f' suffix
// for floats.
@@ -132,6 +232,11 @@ class TextFormat::Parser::ParserImpl {
// '#' starts a comment.
tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE);
+ if (allow_relaxed_whitespace) {
+ tokenizer_.set_require_space_after_number(false);
+ tokenizer_.set_allow_multiline_strings(true);
+ }
+
// Consume the starting token.
tokenizer_.Next();
}
@@ -143,7 +248,7 @@ class TextFormat::Parser::ParserImpl {
// GOOGLE_LOG(ERROR)).
bool Parse(Message* output) {
// Consume fields until we cannot do so anymore.
- while(true) {
+ while (true) {
if (LookingAtType(io::Tokenizer::TYPE_END)) {
return !had_errors_;
}
@@ -228,6 +333,7 @@ class TextFormat::Parser::ParserImpl {
return true;
}
+
// Consumes the current field (as returned by the tokenizer) on the
// passed in message.
bool ConsumeField(Message* message) {
@@ -237,6 +343,8 @@ class TextFormat::Parser::ParserImpl {
string field_name;
const FieldDescriptor* field = NULL;
+ int start_line = tokenizer_.current().line;
+ int start_column = tokenizer_.current().column;
if (TryConsume("[")) {
// Extension.
@@ -249,72 +357,200 @@ class TextFormat::Parser::ParserImpl {
}
DO(Consume("]"));
- field = reflection->FindKnownExtensionByName(field_name);
+ field = (finder_ != NULL
+ ? finder_->FindExtension(message, field_name)
+ : reflection->FindKnownExtensionByName(field_name));
if (field == NULL) {
- ReportError("Extension \"" + field_name + "\" is not defined or "
- "is not an extension of \"" +
- descriptor->full_name() + "\".");
- return false;
+ if (!allow_unknown_field_) {
+ ReportError("Extension \"" + field_name + "\" is not defined or "
+ "is not an extension of \"" +
+ descriptor->full_name() + "\".");
+ return false;
+ } else {
+ ReportWarning("Extension \"" + field_name + "\" is not defined or "
+ "is not an extension of \"" +
+ descriptor->full_name() + "\".");
+ }
}
} else {
DO(ConsumeIdentifier(&field_name));
- field = descriptor->FindFieldByName(field_name);
- // 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 (field == NULL) {
- string lower_field_name = field_name;
- LowerString(&lower_field_name);
- field = descriptor->FindFieldByName(lower_field_name);
- // If the case-insensitive match worked but the field is NOT a group,
- if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) {
+ int32 field_number;
+ if (allow_field_number_ && safe_strto32(field_name, &field_number)) {
+ if (descriptor->IsExtensionNumber(field_number)) {
+ field = reflection->FindKnownExtensionByNumber(field_number);
+ } else {
+ field = descriptor->FindFieldByNumber(field_number);
+ }
+ } else {
+ field = descriptor->FindFieldByName(field_name);
+ // 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 (field == NULL) {
+ string lower_field_name = field_name;
+ LowerString(&lower_field_name);
+ field = descriptor->FindFieldByName(lower_field_name);
+ // If the case-insensitive match worked but the field is NOT a group,
+ if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) {
+ field = NULL;
+ }
+ }
+ // Again, special-case group names as described above.
+ if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP
+ && field->message_type()->name() != field_name) {
field = NULL;
}
- }
- // Again, special-case group names as described above.
- if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP
- && field->message_type()->name() != field_name) {
- field = NULL;
+
+ if (field == NULL && allow_case_insensitive_field_) {
+ string lower_field_name = field_name;
+ LowerString(&lower_field_name);
+ field = descriptor->FindFieldByLowercaseName(lower_field_name);
+ }
}
if (field == NULL) {
- ReportError("Message type \"" + descriptor->full_name() +
- "\" has no field named \"" + field_name + "\".");
- return false;
+ if (!allow_unknown_field_) {
+ ReportError("Message type \"" + descriptor->full_name() +
+ "\" has no field named \"" + field_name + "\".");
+ return false;
+ } else {
+ ReportWarning("Message type \"" + descriptor->full_name() +
+ "\" has no field named \"" + field_name + "\".");
+ }
}
}
- // Fail if the field is not repeated and it has already been specified.
- if ((singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) &&
- !field->is_repeated() && reflection->HasField(*message, field)) {
- ReportError("Non-repeated field \"" + field_name +
- "\" is specified multiple times.");
- return false;
+ // Skips unknown field.
+ if (field == NULL) {
+ GOOGLE_CHECK(allow_unknown_field_);
+ // 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 begining 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 (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
+ return SkipFieldValue();
+ } else {
+ return SkipFieldMessage();
+ }
+ }
+
+ if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) {
+ // Fail if the field is not repeated and it has already been specified.
+ if (!field->is_repeated() && reflection->HasField(*message, field)) {
+ ReportError("Non-repeated field \"" + field_name +
+ "\" is specified multiple times.");
+ return false;
+ }
+ // Fail if the field is a member of a oneof and another member has already
+ // been specified.
+ const OneofDescriptor* oneof = field->containing_oneof();
+ if (oneof != NULL && reflection->HasOneof(*message, oneof)) {
+ const FieldDescriptor* other_field =
+ reflection->GetOneofFieldDescriptor(*message, oneof);
+ ReportError("Field \"" + field_name + "\" is specified along with "
+ "field \"" + other_field->name() + "\", another member "
+ "of oneof \"" + oneof->name() + "\".");
+ return false;
+ }
}
// Perform special handling for embedded message types.
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
// ':' is optional here.
TryConsume(":");
- DO(ConsumeFieldMessage(message, reflection, field));
} else {
+ // ':' is required here.
DO(Consume(":"));
+ }
+
+ if (field->is_repeated() && TryConsume("[")) {
+ // Short repeated format, e.g. "foo: [1, 2, 3]"
+ while (true) {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Perform special handling for embedded message types.
+ DO(ConsumeFieldMessage(message, reflection, field));
+ } else {
+ DO(ConsumeFieldValue(message, reflection, field));
+ }
+ if (TryConsume("]")) {
+ break;
+ }
+ DO(Consume(","));
+ }
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ DO(ConsumeFieldMessage(message, reflection, field));
+ } else {
DO(ConsumeFieldValue(message, reflection, field));
}
+ // For historical reasons, fields may optionally be separated by commas or
+ // semicolons.
+ TryConsume(";") || TryConsume(",");
+
if (field->options().deprecated()) {
ReportWarning("text format contains deprecated field \""
+ field_name + "\"");
}
+ // If a parse info tree exists, add the location for the parsed
+ // field.
+ if (parse_info_tree_ != NULL) {
+ RecordLocation(parse_info_tree_, field,
+ ParseLocation(start_line, start_column));
+ }
+
+ return true;
+ }
+
+ // Skips the next field including the field's name and value.
+ bool SkipField() {
+ string field_name;
+ if (TryConsume("[")) {
+ // Extension name.
+ DO(ConsumeIdentifier(&field_name));
+ while (TryConsume(".")) {
+ string part;
+ DO(ConsumeIdentifier(&part));
+ field_name += ".";
+ field_name += part;
+ }
+ DO(Consume("]"));
+ } else {
+ DO(ConsumeIdentifier(&field_name));
+ }
+
+ // 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 begining 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 (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
+ DO(SkipFieldValue());
+ } else {
+ DO(SkipFieldMessage());
+ }
+ // For historical reasons, fields may optionally be separated by commas or
+ // semicolons.
+ TryConsume(";") || TryConsume(",");
return true;
}
bool ConsumeFieldMessage(Message* message,
const Reflection* reflection,
const FieldDescriptor* field) {
+
+ // If the parse information tree is not NULL, create a nested one
+ // for the nested message.
+ ParseInfoTree* parent = parse_info_tree_;
+ if (parent != NULL) {
+ parse_info_tree_ = CreateNested(parent, field);
+ }
+
string delimeter;
if (TryConsume("<")) {
delimeter = ">";
@@ -329,6 +565,26 @@ class TextFormat::Parser::ParserImpl {
DO(ConsumeMessage(reflection->MutableMessage(message, field),
delimeter));
}
+
+ // Reset the parse information tree.
+ parse_info_tree_ = parent;
+ return true;
+ }
+
+ // Skips the whole body of a message including the begining delimeter and
+ // the ending delimeter.
+ bool SkipFieldMessage() {
+ string delimeter;
+ if (TryConsume("<")) {
+ delimeter = ">";
+ } else {
+ DO(Consume("{"));
+ delimeter = "}";
+ }
+ while (!LookingAt(">") && !LookingAt("}")) {
+ DO(SkipField());
+ }
+ DO(Consume(delimeter));
return true;
}
@@ -397,34 +653,57 @@ class TextFormat::Parser::ParserImpl {
}
case FieldDescriptor::CPPTYPE_BOOL: {
- string value;
- DO(ConsumeIdentifier(&value));
-
- if (value == "true") {
- SET_FIELD(Bool, true);
- } else if (value == "false") {
- SET_FIELD(Bool, false);
+ if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ uint64 value;
+ DO(ConsumeUnsignedInteger(&value, 1));
+ SET_FIELD(Bool, value);
} else {
- ReportError("Invalid value for boolean field \"" + field->name()
- + "\". Value: \"" + value + "\".");
- return false;
+ string value;
+ DO(ConsumeIdentifier(&value));
+ if (value == "true" || value == "True" || value == "t") {
+ SET_FIELD(Bool, true);
+ } else if (value == "false" || value == "False" || value == "f") {
+ SET_FIELD(Bool, false);
+ } else {
+ ReportError("Invalid value for boolean field \"" + field->name()
+ + "\". Value: \"" + value + "\".");
+ return false;
+ }
}
break;
}
case FieldDescriptor::CPPTYPE_ENUM: {
string value;
- DO(ConsumeIdentifier(&value));
-
- // Find the enumeration value.
const EnumDescriptor* enum_type = field->enum_type();
- const EnumValueDescriptor* enum_value
- = enum_type->FindValueByName(value);
+ const EnumValueDescriptor* enum_value = NULL;
+
+ if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ DO(ConsumeIdentifier(&value));
+ // Find the enumeration value.
+ enum_value = enum_type->FindValueByName(value);
+
+ } else if (LookingAt("-") ||
+ LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ int64 int_value;
+ DO(ConsumeSignedInteger(&int_value, kint32max));
+ value = SimpleItoa(int_value); // for error reporting
+ enum_value = enum_type->FindValueByNumber(int_value);
+ } else {
+ ReportError("Expected integer or identifier.");
+ return false;
+ }
if (enum_value == NULL) {
- ReportError("Unknown enumeration value of \"" + value + "\" for "
- "field \"" + field->name() + "\".");
- return false;
+ if (!allow_unknown_enum_) {
+ ReportError("Unknown enumeration value of \"" + value + "\" for "
+ "field \"" + field->name() + "\".");
+ return false;
+ } else {
+ ReportWarning("Unknown enumeration value of \"" + value + "\" for "
+ "field \"" + field->name() + "\".");
+ return true;
+ }
}
SET_FIELD(Enum, enum_value);
@@ -442,6 +721,60 @@ class TextFormat::Parser::ParserImpl {
return true;
}
+ bool SkipFieldValue() {
+ if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ tokenizer_.Next();
+ }
+ return true;
+ }
+ // Possible field values other than string:
+ // 12345 => TYPE_INTEGER
+ // -12345 => TYPE_SYMBOL + TYPE_INTEGER
+ // 1.2345 => TYPE_FLOAT
+ // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT
+ // inf => TYPE_IDENTIFIER
+ // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER
+ // TYPE_INTEGER => TYPE_IDENTIFIER
+ // Divides them into two group, one with TYPE_SYMBOL
+ // and the other without:
+ // Group one:
+ // 12345 => TYPE_INTEGER
+ // 1.2345 => TYPE_FLOAT
+ // inf => TYPE_IDENTIFIER
+ // TYPE_INTEGER => TYPE_IDENTIFIER
+ // Group two:
+ // -12345 => TYPE_SYMBOL + TYPE_INTEGER
+ // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT
+ // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER
+ // As we can see, the field value consists of an optional '-' and one of
+ // TYPE_INTEGER, TYPE_FLOAT and TYPE_IDENTIFIER.
+ bool has_minus = TryConsume("-");
+ if (!LookingAtType(io::Tokenizer::TYPE_INTEGER) &&
+ !LookingAtType(io::Tokenizer::TYPE_FLOAT) &&
+ !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ return false;
+ }
+ // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field
+ // value while other combinations all generate valid values.
+ // We check if the value of this combination is valid here.
+ // TYPE_IDENTIFIER after a '-' should be one of the float values listed
+ // below:
+ // inf, inff, infinity, nan
+ if (has_minus && LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ string text = tokenizer_.current().text;
+ LowerString(&text);
+ if (text != "inf" &&
+ text != "infinity" &&
+ text != "nan") {
+ ReportError("Invalid float number: " + text);
+ return false;
+ }
+ }
+ tokenizer_.Next();
+ return true;
+ }
+
// Returns true if the current token's text is equal to that specified.
bool LookingAt(const string& text) {
return tokenizer_.current().text == text;
@@ -455,15 +788,23 @@ class TextFormat::Parser::ParserImpl {
// Consumes an identifier and saves its value in the identifier parameter.
// Returns false if the token is not of type IDENTFIER.
bool ConsumeIdentifier(string* identifier) {
- if (!LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
- ReportError("Expected identifier.");
- return false;
+ if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ *identifier = tokenizer_.current().text;
+ tokenizer_.Next();
+ return true;
}
- *identifier = tokenizer_.current().text;
+ // If allow_field_numer_ or allow_unknown_field_ is true, we should able
+ // to parse integer identifiers.
+ if ((allow_field_number_ || allow_unknown_field_)
+ && LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ *identifier = tokenizer_.current().text;
+ tokenizer_.Next();
+ return true;
+ }
- tokenizer_.Next();
- return true;
+ ReportError("Expected identifier.");
+ return false;
}
// Consumes a string and saves its value in the text parameter.
@@ -530,6 +871,29 @@ class TextFormat::Parser::ParserImpl {
return true;
}
+ // Consumes a uint64 and saves its value in the value parameter.
+ // 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.");
+ return false;
+ }
+
+ const string& text = tokenizer_.current().text;
+ if (IsHexNumber(text) || IsOctNumber(text)) {
+ ReportError("Expect a decimal number.");
+ return false;
+ }
+
+ if (!io::Tokenizer::ParseInteger(text, max_value, value)) {
+ ReportError("Integer out of range.");
+ return false;
+ }
+
+ tokenizer_.Next();
+ return true;
+ }
+
// Consumes a double and saves its value in the value parameter.
// Note that since the tokenizer does not support negative numbers,
// we actually may consume an additional token (for the minus sign) in this
@@ -547,7 +911,7 @@ class TextFormat::Parser::ParserImpl {
if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
// We have found an integer value for the double.
uint64 integer_value;
- DO(ConsumeUnsignedInteger(&integer_value, kuint64max));
+ DO(ConsumeUnsignedDecimalInteger(&integer_value, kuint64max));
*value = static_cast<double>(integer_value);
} else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
@@ -559,7 +923,8 @@ class TextFormat::Parser::ParserImpl {
} else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
string text = tokenizer_.current().text;
LowerString(&text);
- if (text == "inf" || text == "infinity") {
+ if (text == "inf" ||
+ text == "infinity") {
*value = std::numeric_limits<double>::infinity();
tokenizer_.Next();
} else if (text == "nan") {
@@ -616,7 +981,7 @@ class TextFormat::Parser::ParserImpl {
explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) :
parser_(parser) { }
- virtual ~ParserErrorCollector() { };
+ virtual ~ParserErrorCollector() { }
virtual void AddError(int line, int column, const string& message) {
parser_->ReportError(line, column, message);
@@ -632,10 +997,16 @@ class TextFormat::Parser::ParserImpl {
};
io::ErrorCollector* error_collector_;
+ TextFormat::Finder* finder_;
+ ParseInfoTree* parse_info_tree_;
ParserErrorCollector tokenizer_error_collector_;
io::Tokenizer tokenizer_;
const Descriptor* root_message_type_;
SingularOverwritePolicy singular_overwrite_policy_;
+ const bool allow_case_insensitive_field_;
+ const bool allow_unknown_field_;
+ const bool allow_unknown_enum_;
+ const bool allow_field_number_;
bool had_errors_;
};
@@ -661,7 +1032,7 @@ class TextFormat::Printer::TextGenerator {
~TextGenerator() {
// Only BackUp() if we're sure we've successfully called Next() at least
// once.
- if (buffer_size_ > 0) {
+ if (!failed_ && buffer_size_ > 0) {
output_->BackUp(buffer_size_);
}
}
@@ -765,17 +1136,39 @@ class TextFormat::Printer::TextGenerator {
// ===========================================================================
+TextFormat::Finder::~Finder() {
+}
+
TextFormat::Parser::Parser()
: error_collector_(NULL),
- allow_partial_(false) {}
+ finder_(NULL),
+ parse_info_tree_(NULL),
+ allow_partial_(false),
+ allow_case_insensitive_field_(false),
+ allow_unknown_field_(false),
+ allow_unknown_enum_(false),
+ allow_field_number_(false),
+ allow_relaxed_whitespace_(false),
+ allow_singular_overwrites_(false) {
+}
TextFormat::Parser::~Parser() {}
bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
Message* output) {
output->Clear();
+
+ ParserImpl::SingularOverwritePolicy overwrites_policy =
+ allow_singular_overwrites_
+ ? ParserImpl::ALLOW_SINGULAR_OVERWRITES
+ : ParserImpl::FORBID_SINGULAR_OVERWRITES;
+
ParserImpl parser(output->GetDescriptor(), input, error_collector_,
- ParserImpl::FORBID_SINGULAR_OVERWRITES);
+ finder_, parse_info_tree_,
+ overwrites_policy,
+ allow_case_insensitive_field_, allow_unknown_field_,
+ allow_unknown_enum_, allow_field_number_,
+ allow_relaxed_whitespace_);
return MergeUsingImpl(input, output, &parser);
}
@@ -788,7 +1181,11 @@ bool TextFormat::Parser::ParseFromString(const string& input,
bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
Message* output) {
ParserImpl parser(output->GetDescriptor(), input, error_collector_,
- ParserImpl::ALLOW_SINGULAR_OVERWRITES);
+ finder_, parse_info_tree_,
+ ParserImpl::ALLOW_SINGULAR_OVERWRITES,
+ allow_case_insensitive_field_, allow_unknown_field_,
+ allow_unknown_enum_, allow_field_number_,
+ allow_relaxed_whitespace_);
return MergeUsingImpl(input, output, &parser);
}
@@ -798,7 +1195,7 @@ bool TextFormat::Parser::MergeFromString(const string& input,
return Merge(&input_stream, output);
}
-bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* input,
+bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */,
Message* output,
ParserImpl* parser_impl) {
if (!parser_impl->Parse(output)) return false;
@@ -806,7 +1203,7 @@ bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* input,
vector<string> missing_fields;
output->FindInitializationErrors(&missing_fields);
parser_impl->ReportError(-1, 0, "Message missing required fields: " +
- JoinStrings(missing_fields, ", "));
+ Join(missing_fields, ", "));
return false;
}
return true;
@@ -818,7 +1215,11 @@ bool TextFormat::Parser::ParseFieldValueFromString(
Message* output) {
io::ArrayInputStream input_stream(input.data(), input.size());
ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_,
- ParserImpl::ALLOW_SINGULAR_OVERWRITES);
+ finder_, parse_info_tree_,
+ ParserImpl::ALLOW_SINGULAR_OVERWRITES,
+ allow_case_insensitive_field_, allow_unknown_field_,
+ allow_unknown_enum_, allow_field_number_,
+ allow_relaxed_whitespace_);
return parser.ParseField(field, output);
}
@@ -844,29 +1245,138 @@ bool TextFormat::Parser::ParseFieldValueFromString(
// ===========================================================================
+// The default implementation for FieldValuePrinter. The base class just
+// does simple formatting. That way, deriving classes could decide to fallback
+// to that behavior.
+TextFormat::FieldValuePrinter::FieldValuePrinter() {}
+TextFormat::FieldValuePrinter::~FieldValuePrinter() {}
+string TextFormat::FieldValuePrinter::PrintBool(bool val) const {
+ return val ? "true" : "false";
+}
+string TextFormat::FieldValuePrinter::PrintInt32(int32 val) const {
+ return SimpleItoa(val);
+}
+string TextFormat::FieldValuePrinter::PrintUInt32(uint32 val) const {
+ return SimpleItoa(val);
+}
+string TextFormat::FieldValuePrinter::PrintInt64(int64 val) const {
+ return SimpleItoa(val);
+}
+string TextFormat::FieldValuePrinter::PrintUInt64(uint64 val) const {
+ return SimpleItoa(val);
+}
+string TextFormat::FieldValuePrinter::PrintFloat(float val) const {
+ return SimpleFtoa(val);
+}
+string TextFormat::FieldValuePrinter::PrintDouble(double val) const {
+ return SimpleDtoa(val);
+}
+string TextFormat::FieldValuePrinter::PrintString(const string& val) const {
+ return StrCat("\"", CEscape(val), "\"");
+}
+string TextFormat::FieldValuePrinter::PrintBytes(const string& val) const {
+ return PrintString(val);
+}
+string TextFormat::FieldValuePrinter::PrintEnum(int32 val,
+ const string& name) const {
+ return name;
+}
+string TextFormat::FieldValuePrinter::PrintFieldName(
+ const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field) const {
+ if (field->is_extension()) {
+ // We special-case MessageSet elements for compatibility with proto1.
+ if (field->containing_type()->options().message_set_wire_format()
+ && field->type() == FieldDescriptor::TYPE_MESSAGE
+ && field->is_optional()
+ && field->extension_scope() == field->message_type()) {
+ return StrCat("[", field->message_type()->full_name(), "]");
+ } else {
+ return StrCat("[", field->full_name(), "]");
+ }
+ } else if (field->type() == FieldDescriptor::TYPE_GROUP) {
+ // Groups must be serialized with their original capitalization.
+ return field->message_type()->name();
+ } else {
+ return field->name();
+ }
+}
+string TextFormat::FieldValuePrinter::PrintMessageStart(
+ const Message& message,
+ int field_index,
+ int field_count,
+ bool single_line_mode) const {
+ return single_line_mode ? " { " : " {\n";
+}
+string TextFormat::FieldValuePrinter::PrintMessageEnd(
+ const Message& message,
+ int field_index,
+ int field_count,
+ bool single_line_mode) const {
+ return single_line_mode ? "} " : "}\n";
+}
+
+namespace {
+// Our own specialization: for UTF8 escaped strings.
+class FieldValuePrinterUtf8Escaping : public TextFormat::FieldValuePrinter {
+ public:
+ virtual string PrintString(const string& val) const {
+ return StrCat("\"", strings::Utf8SafeCEscape(val), "\"");
+ }
+ virtual string PrintBytes(const string& val) const {
+ return TextFormat::FieldValuePrinter::PrintString(val);
+ }
+};
+
+} // namespace
+
TextFormat::Printer::Printer()
: initial_indent_level_(0),
single_line_mode_(false),
+ use_field_number_(false),
use_short_repeated_primitives_(false),
- utf8_string_escaping_(false) {}
+ hide_unknown_fields_(false),
+ print_message_fields_in_index_order_(false) {
+ SetUseUtf8StringEscaping(false);
+}
-TextFormat::Printer::~Printer() {}
+TextFormat::Printer::~Printer() {
+ STLDeleteValues(&custom_printers_);
+}
+
+void TextFormat::Printer::SetUseUtf8StringEscaping(bool as_utf8) {
+ SetDefaultFieldValuePrinter(as_utf8
+ ? new FieldValuePrinterUtf8Escaping()
+ : new FieldValuePrinter());
+}
+
+void TextFormat::Printer::SetDefaultFieldValuePrinter(
+ const FieldValuePrinter* printer) {
+ default_field_value_printer_.reset(printer);
+}
+
+bool TextFormat::Printer::RegisterFieldValuePrinter(
+ const FieldDescriptor* field,
+ const FieldValuePrinter* printer) {
+ return field != NULL
+ && printer != NULL
+ && custom_printers_.insert(make_pair(field, printer)).second;
+}
bool TextFormat::Printer::PrintToString(const Message& message,
- string* output) {
+ string* output) const {
GOOGLE_DCHECK(output) << "output specified is NULL";
output->clear();
io::StringOutputStream output_stream(output);
- bool result = Print(message, &output_stream);
-
- return result;
+ return Print(message, &output_stream);
}
bool TextFormat::Printer::PrintUnknownFieldsToString(
const UnknownFieldSet& unknown_fields,
- string* output) {
+ string* output) const {
GOOGLE_DCHECK(output) << "output specified is NULL";
output->clear();
@@ -875,7 +1385,7 @@ bool TextFormat::Printer::PrintUnknownFieldsToString(
}
bool TextFormat::Printer::Print(const Message& message,
- io::ZeroCopyOutputStream* output) {
+ io::ZeroCopyOutputStream* output) const {
TextGenerator generator(output, initial_indent_level_);
Print(message, generator);
@@ -886,7 +1396,7 @@ bool TextFormat::Printer::Print(const Message& message,
bool TextFormat::Printer::PrintUnknownFields(
const UnknownFieldSet& unknown_fields,
- io::ZeroCopyOutputStream* output) {
+ io::ZeroCopyOutputStream* output) const {
TextGenerator generator(output, initial_indent_level_);
PrintUnknownFields(unknown_fields, generator);
@@ -895,22 +1405,37 @@ bool TextFormat::Printer::PrintUnknownFields(
return !generator.failed();
}
+namespace {
+// Comparison functor for sorting FieldDescriptors by field index.
+struct FieldIndexSorter {
+ bool operator()(const FieldDescriptor* left,
+ const FieldDescriptor* right) const {
+ return left->index() < right->index();
+ }
+};
+} // namespace
+
void TextFormat::Printer::Print(const Message& message,
- TextGenerator& generator) {
+ TextGenerator& generator) const {
const Reflection* reflection = message.GetReflection();
vector<const FieldDescriptor*> fields;
reflection->ListFields(message, &fields);
+ if (print_message_fields_in_index_order_) {
+ sort(fields.begin(), fields.end(), FieldIndexSorter());
+ }
for (int i = 0; i < fields.size(); i++) {
PrintField(message, reflection, fields[i], generator);
}
- PrintUnknownFields(reflection->GetUnknownFields(message), generator);
+ if (!hide_unknown_fields_) {
+ PrintUnknownFields(reflection->GetUnknownFields(message), generator);
+ }
}
void TextFormat::Printer::PrintFieldValueToString(
const Message& message,
const FieldDescriptor* field,
int index,
- string* output) {
+ string* output) const {
GOOGLE_DCHECK(output) << "output specified is NULL";
@@ -924,7 +1449,7 @@ void TextFormat::Printer::PrintFieldValueToString(
void TextFormat::Printer::PrintField(const Message& message,
const Reflection* reflection,
const FieldDescriptor* field,
- TextGenerator& generator) {
+ TextGenerator& generator) const {
if (use_short_repeated_primitives_ &&
field->is_repeated() &&
field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
@@ -942,35 +1467,30 @@ void TextFormat::Printer::PrintField(const Message& message,
}
for (int j = 0; j < count; ++j) {
+ const int field_index = field->is_repeated() ? j : -1;
+
PrintFieldName(message, reflection, field, generator);
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- if (single_line_mode_) {
- generator.Print(" { ");
- } else {
- generator.Print(" {\n");
- generator.Indent();
- }
+ const FieldValuePrinter* printer = FindWithDefault(
+ custom_printers_, field, default_field_value_printer_.get());
+ const Message& sub_message =
+ field->is_repeated()
+ ? reflection->GetRepeatedMessage(message, field, j)
+ : reflection->GetMessage(message, field);
+ generator.Print(
+ printer->PrintMessageStart(
+ sub_message, field_index, count, single_line_mode_));
+ generator.Indent();
+ Print(sub_message, generator);
+ generator.Outdent();
+ generator.Print(
+ printer->PrintMessageEnd(
+ sub_message, field_index, count, single_line_mode_));
} else {
generator.Print(": ");
- }
-
- // Write the field value.
- int field_index = j;
- if (!field->is_repeated()) {
- field_index = -1;
- }
-
- PrintFieldValue(message, reflection, field, field_index, generator);
-
- if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- if (single_line_mode_) {
- generator.Print("} ");
- } else {
- generator.Outdent();
- generator.Print("}\n");
- }
- } else {
+ // Write the field value.
+ PrintFieldValue(message, reflection, field, field_index, generator);
if (single_line_mode_) {
generator.Print(" ");
} else {
@@ -980,10 +1500,11 @@ void TextFormat::Printer::PrintField(const Message& message,
}
}
-void TextFormat::Printer::PrintShortRepeatedField(const Message& message,
- const Reflection* reflection,
- const FieldDescriptor* field,
- TextGenerator& generator) {
+void TextFormat::Printer::PrintShortRepeatedField(
+ const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field,
+ TextGenerator& generator) const {
// Print primitive repeated field in short form.
PrintFieldName(message, reflection, field, generator);
@@ -1003,27 +1524,17 @@ void TextFormat::Printer::PrintShortRepeatedField(const Message& message,
void TextFormat::Printer::PrintFieldName(const Message& message,
const Reflection* reflection,
const FieldDescriptor* field,
- TextGenerator& generator) {
- if (field->is_extension()) {
- generator.Print("[");
- // We special-case MessageSet elements for compatibility with proto1.
- if (field->containing_type()->options().message_set_wire_format()
- && field->type() == FieldDescriptor::TYPE_MESSAGE
- && field->is_optional()
- && field->extension_scope() == field->message_type()) {
- generator.Print(field->message_type()->full_name());
- } else {
- generator.Print(field->full_name());
- }
- generator.Print("]");
- } else {
- if (field->type() == FieldDescriptor::TYPE_GROUP) {
- // Groups must be serialized with their original capitalization.
- generator.Print(field->message_type()->name());
- } else {
- generator.Print(field->name());
- }
+ TextGenerator& generator) const {
+ // if use_field_number_ is true, prints field number instead
+ // of field name.
+ if (use_field_number_) {
+ generator.Print(SimpleItoa(field->number()));
+ return;
}
+
+ const FieldValuePrinter* printer = FindWithDefault(
+ custom_printers_, field, default_field_value_printer_.get());
+ generator.Print(printer->PrintFieldName(message, reflection, field));
}
void TextFormat::Printer::PrintFieldValue(
@@ -1031,66 +1542,60 @@ void TextFormat::Printer::PrintFieldValue(
const Reflection* reflection,
const FieldDescriptor* field,
int index,
- TextGenerator& generator) {
+ TextGenerator& generator) const {
GOOGLE_DCHECK(field->is_repeated() || (index == -1))
<< "Index must be -1 for non-repeated fields";
+ const FieldValuePrinter* printer
+ = FindWithDefault(custom_printers_, field,
+ default_field_value_printer_.get());
+
switch (field->cpp_type()) {
-#define OUTPUT_FIELD(CPPTYPE, METHOD, TO_STRING) \
- case FieldDescriptor::CPPTYPE_##CPPTYPE: \
- generator.Print(TO_STRING(field->is_repeated() ? \
- reflection->GetRepeated##METHOD(message, field, index) : \
- reflection->Get##METHOD(message, field))); \
- break; \
-
- OUTPUT_FIELD( INT32, Int32, SimpleItoa);
- OUTPUT_FIELD( INT64, Int64, SimpleItoa);
- OUTPUT_FIELD(UINT32, UInt32, SimpleItoa);
- OUTPUT_FIELD(UINT64, UInt64, SimpleItoa);
- OUTPUT_FIELD( FLOAT, Float, SimpleFtoa);
- OUTPUT_FIELD(DOUBLE, Double, SimpleDtoa);
+#define OUTPUT_FIELD(CPPTYPE, METHOD) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ generator.Print(printer->Print##METHOD(field->is_repeated() \
+ ? reflection->GetRepeated##METHOD(message, field, index) \
+ : reflection->Get##METHOD(message, field))); \
+ break
+
+ OUTPUT_FIELD( INT32, Int32);
+ OUTPUT_FIELD( INT64, Int64);
+ OUTPUT_FIELD(UINT32, UInt32);
+ OUTPUT_FIELD(UINT64, UInt64);
+ OUTPUT_FIELD( FLOAT, Float);
+ OUTPUT_FIELD(DOUBLE, Double);
+ OUTPUT_FIELD( BOOL, Bool);
#undef OUTPUT_FIELD
- case FieldDescriptor::CPPTYPE_STRING: {
- string scratch;
- const string& value = field->is_repeated() ?
- reflection->GetRepeatedStringReference(
- message, field, index, &scratch) :
- reflection->GetStringReference(message, field, &scratch);
-
- generator.Print("\"");
- if (utf8_string_escaping_) {
- generator.Print(strings::Utf8SafeCEscape(value));
- } else {
- generator.Print(CEscape(value));
- }
- generator.Print("\"");
-
- break;
+ case FieldDescriptor::CPPTYPE_STRING: {
+ string scratch;
+ const string& value = field->is_repeated()
+ ? reflection->GetRepeatedStringReference(
+ message, field, index, &scratch)
+ : reflection->GetStringReference(message, field, &scratch);
+ if (field->type() == FieldDescriptor::TYPE_STRING) {
+ generator.Print(printer->PrintString(value));
+ } else {
+ GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES);
+ generator.Print(printer->PrintBytes(value));
}
+ break;
+ }
- case FieldDescriptor::CPPTYPE_BOOL:
- if (field->is_repeated()) {
- generator.Print(reflection->GetRepeatedBool(message, field, index)
- ? "true" : "false");
- } else {
- generator.Print(reflection->GetBool(message, field)
- ? "true" : "false");
- }
- break;
-
- case FieldDescriptor::CPPTYPE_ENUM:
- generator.Print(field->is_repeated() ?
- reflection->GetRepeatedEnum(message, field, index)->name() :
- reflection->GetEnum(message, field)->name());
- break;
+ case FieldDescriptor::CPPTYPE_ENUM: {
+ const EnumValueDescriptor *enum_val = field->is_repeated()
+ ? reflection->GetRepeatedEnum(message, field, index)
+ : reflection->GetEnum(message, field);
+ generator.Print(printer->PrintEnum(enum_val->number(), enum_val->name()));
+ break;
+ }
- case FieldDescriptor::CPPTYPE_MESSAGE:
- Print(field->is_repeated() ?
- reflection->GetRepeatedMessage(message, field, index) :
- reflection->GetMessage(message, field),
- generator);
- break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ Print(field->is_repeated()
+ ? reflection->GetRepeatedMessage(message, field, index)
+ : reflection->GetMessage(message, field),
+ generator);
+ break;
}
}
@@ -1143,7 +1648,7 @@ static string PaddedHex(IntType value) {
}
void TextFormat::Printer::PrintUnknownFields(
- const UnknownFieldSet& unknown_fields, TextGenerator& generator) {
+ const UnknownFieldSet& unknown_fields, TextGenerator& generator) const {
for (int i = 0; i < unknown_fields.field_count(); i++) {
const UnknownField& field = unknown_fields.field(i);
string field_number = SimpleItoa(field.number());
diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h
index e78e104..2954941 100644
--- a/src/google/protobuf/text_format.h
+++ b/src/google/protobuf/text_format.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -38,9 +38,14 @@
#ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__
#define GOOGLE_PROTOBUF_TEXT_FORMAT_H__
+#include <map>
+#include <memory>
#include <string>
-#include <google/protobuf/message.h>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/message.h>
namespace google {
namespace protobuf {
@@ -82,6 +87,41 @@ class LIBPROTOBUF_EXPORT TextFormat {
int index,
string* output);
+ // The default printer that converts scalar values from fields into
+ // their string representation.
+ // You can derive from this FieldValuePrinter if you want to have
+ // fields to be printed in a different way and register it at the
+ // Printer.
+ class LIBPROTOBUF_EXPORT FieldValuePrinter {
+ public:
+ FieldValuePrinter();
+ virtual ~FieldValuePrinter();
+ virtual string PrintBool(bool val) const;
+ virtual string PrintInt32(int32 val) const;
+ virtual string PrintUInt32(uint32 val) const;
+ virtual string PrintInt64(int64 val) const;
+ virtual string PrintUInt64(uint64 val) const;
+ virtual string PrintFloat(float val) const;
+ virtual string PrintDouble(double val) const;
+ virtual string PrintString(const string& val) const;
+ virtual string PrintBytes(const string& val) const;
+ virtual string PrintEnum(int32 val, const string& name) const;
+ virtual string PrintFieldName(const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field) const;
+ virtual string PrintMessageStart(const Message& message,
+ int field_index,
+ int field_count,
+ bool single_line_mode) const;
+ virtual string PrintMessageEnd(const Message& message,
+ int field_index,
+ int field_count,
+ bool single_line_mode) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldValuePrinter);
+ };
+
// Class for those users which require more fine-grained control over how
// a protobuffer message is printed out.
class LIBPROTOBUF_EXPORT Printer {
@@ -90,20 +130,20 @@ class LIBPROTOBUF_EXPORT TextFormat {
~Printer();
// Like TextFormat::Print
- bool Print(const Message& message, io::ZeroCopyOutputStream* output);
+ bool Print(const Message& message, io::ZeroCopyOutputStream* output) const;
// Like TextFormat::PrintUnknownFields
bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
- io::ZeroCopyOutputStream* output);
+ io::ZeroCopyOutputStream* output) const;
// Like TextFormat::PrintToString
- bool PrintToString(const Message& message, string* output);
+ bool PrintToString(const Message& message, string* output) const;
// Like TextFormat::PrintUnknownFieldsToString
bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
- string* output);
+ string* output) const;
// Like TextFormat::PrintFieldValueToString
void PrintFieldValueToString(const Message& message,
const FieldDescriptor* field,
int index,
- string* output);
+ string* output) const;
// Adjust the initial indent level of all output. Each indent level is
// equal to two spaces.
@@ -117,12 +157,20 @@ class LIBPROTOBUF_EXPORT TextFormat {
single_line_mode_ = single_line_mode;
}
+ bool IsInSingleLineMode() {
+ return single_line_mode_;
+ }
+
+ // If use_field_number is true, uses field number instead of field name.
+ void SetUseFieldNumber(bool use_field_number) {
+ use_field_number_ = use_field_number;
+ }
+
// Set true to print repeated primitives in a format like:
// field_name: [1, 2, 3, 4]
// instead of printing each value on its own line. Short format applies
// only to primitive values -- i.e. everything except strings and
- // sub-messages/groups. Note that at present this format is not recognized
- // by the parser.
+ // sub-messages/groups.
void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) {
use_short_repeated_primitives_ = use_short_repeated_primitives;
}
@@ -130,11 +178,41 @@ class LIBPROTOBUF_EXPORT TextFormat {
// Set true to output UTF-8 instead of ASCII. The only difference
// is that bytes >= 0x80 in string fields will not be escaped,
// because they are assumed to be part of UTF-8 multi-byte
- // sequences.
- void SetUseUtf8StringEscaping(bool as_utf8) {
- utf8_string_escaping_ = as_utf8;
+ // sequences. This will change the default FieldValuePrinter.
+ void SetUseUtf8StringEscaping(bool as_utf8);
+
+ // Set the default FieldValuePrinter that is used for all fields that
+ // don't have a field-specific printer registered.
+ // Takes ownership of the printer.
+ void SetDefaultFieldValuePrinter(const FieldValuePrinter* printer);
+
+ // Sets whether we want to hide unknown fields or not.
+ // Usually unknown fields are printed in a generic way that includes the
+ // tag number of the field instead of field name. However, sometimes it
+ // is useful to be able to print the message without unknown fields (e.g.
+ // for the python protobuf version to maintain consistency between its pure
+ // python and c++ implementations).
+ void SetHideUnknownFields(bool hide) {
+ hide_unknown_fields_ = hide;
+ }
+
+ // If print_message_fields_in_index_order is 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.
+ void SetPrintMessageFieldsInIndexOrder(
+ bool print_message_fields_in_index_order) {
+ print_message_fields_in_index_order_ =
+ print_message_fields_in_index_order;
}
+ // Register a custom field-specific FieldValuePrinter for fields
+ // with a particular FieldDescriptor.
+ // Returns "true" if the registration succeeded, or "false", if there is
+ // already a printer for that FieldDescriptor.
+ // Takes ownership of the printer on successful registration.
+ bool RegisterFieldValuePrinter(const FieldDescriptor* field,
+ const FieldValuePrinter* printer);
+
private:
// Forward declaration of an internal class used to print the text
// output to the OutputStream (see text_format.cc for implementation).
@@ -143,26 +221,26 @@ class LIBPROTOBUF_EXPORT TextFormat {
// Internal Print method, used for writing to the OutputStream via
// the TextGenerator class.
void Print(const Message& message,
- TextGenerator& generator);
+ TextGenerator& generator) const;
// Print a single field.
void PrintField(const Message& message,
const Reflection* reflection,
const FieldDescriptor* field,
- TextGenerator& generator);
+ TextGenerator& generator) const;
// Print a repeated primitive field in short form.
void PrintShortRepeatedField(const Message& message,
const Reflection* reflection,
const FieldDescriptor* field,
- TextGenerator& generator);
+ TextGenerator& generator) const;
// Print the name of a field -- i.e. everything that comes before the
// ':' for a single name/value pair.
void PrintFieldName(const Message& message,
const Reflection* reflection,
const FieldDescriptor* field,
- TextGenerator& generator);
+ TextGenerator& generator) const;
// Outputs a textual representation of the value of the field supplied on
// the message supplied or the default value if not set.
@@ -170,21 +248,30 @@ class LIBPROTOBUF_EXPORT TextFormat {
const Reflection* reflection,
const FieldDescriptor* field,
int index,
- TextGenerator& generator);
+ TextGenerator& generator) const;
// Print the fields in an UnknownFieldSet. They are printed by tag number
// only. Embedded messages are heuristically identified by attempting to
// parse them.
void PrintUnknownFields(const UnknownFieldSet& unknown_fields,
- TextGenerator& generator);
+ TextGenerator& generator) const;
int initial_indent_level_;
bool single_line_mode_;
+ bool use_field_number_;
+
bool use_short_repeated_primitives_;
- bool utf8_string_escaping_;
+ bool hide_unknown_fields_;
+
+ bool print_message_fields_in_index_order_;
+
+ scoped_ptr<const FieldValuePrinter> default_field_value_printer_;
+ typedef map<const FieldDescriptor*,
+ const FieldValuePrinter*> CustomPrinterMap;
+ CustomPrinterMap custom_printers_;
};
// Parses a text-format protocol message from the given input stream to
@@ -207,6 +294,71 @@ class LIBPROTOBUF_EXPORT TextFormat {
const FieldDescriptor* field,
Message* message);
+ // Interface that TextFormat::Parser can use to find extensions.
+ // This class may be extended in the future to find more information
+ // like fields, etc.
+ class LIBPROTOBUF_EXPORT Finder {
+ public:
+ virtual ~Finder();
+
+ // Try to find an extension of *message by fully-qualified field
+ // name. Returns NULL if no extension is known for this name or number.
+ virtual const FieldDescriptor* FindExtension(
+ Message* message,
+ const string& name) const = 0;
+ };
+
+ // A location in the parsed text.
+ struct ParseLocation {
+ int line;
+ int column;
+
+ ParseLocation() : line(-1), column(-1) {}
+ ParseLocation(int line_param, int column_param)
+ : line(line_param), column(column_param) {}
+ };
+
+ // Data structure which is populated with the locations of each field
+ // value parsed from the text.
+ class LIBPROTOBUF_EXPORT ParseInfoTree {
+ public:
+ ParseInfoTree();
+ ~ParseInfoTree();
+
+ // Returns the parse location for index-th value of the field in the parsed
+ // text. If none exists, returns a location with line = -1. Index should be
+ // -1 for not-repeated fields.
+ ParseLocation GetLocation(const FieldDescriptor* field, int index) const;
+
+ // Returns the parse info tree for the given field, which must be a message
+ // type. The nested information tree is owned by the root tree and will be
+ // deleted when it is deleted.
+ ParseInfoTree* GetTreeForNested(const FieldDescriptor* field,
+ int index) const;
+
+ private:
+ // Allow the text format parser to record information into the tree.
+ friend class TextFormat;
+
+ // Records the starting location of a single value for a field.
+ void RecordLocation(const FieldDescriptor* field, ParseLocation location);
+
+ // Create and records a nested tree for a nested message field.
+ ParseInfoTree* CreateNested(const FieldDescriptor* field);
+
+ // Defines the map from the index-th field descriptor to its parse location.
+ typedef map<const FieldDescriptor*, vector<ParseLocation> > LocationMap;
+
+ // Defines the map from the index-th field descriptor to the nested parse
+ // info tree.
+ typedef map<const FieldDescriptor*, vector<ParseInfoTree*> > NestedMap;
+
+ LocationMap locations_;
+ NestedMap nested_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParseInfoTree);
+ };
+
// For more control over parsing, use this class.
class LIBPROTOBUF_EXPORT Parser {
public:
@@ -228,17 +380,43 @@ class LIBPROTOBUF_EXPORT TextFormat {
error_collector_ = error_collector;
}
+ // Set how parser finds extensions. If NULL (the default), the
+ // parser will use the standard Reflection object associated with
+ // the message being parsed.
+ void SetFinder(Finder* finder) {
+ finder_ = finder;
+ }
+
+ // Sets where location information about the parse will be written. If NULL
+ // (the default), then no location will be written.
+ void WriteLocationsTo(ParseInfoTree* tree) {
+ parse_info_tree_ = tree;
+ }
+
// Normally parsing fails if, after parsing, output->IsInitialized()
// returns false. Call AllowPartialMessage(true) to skip this check.
void AllowPartialMessage(bool allow) {
allow_partial_ = allow;
}
+ // Allow field names to be matched case-insensitively.
+ // This is not advisable if there are fields that only differ in case, or
+ // if you want to enforce writing in the canonical form.
+ // This is 'false' by default.
+ void AllowCaseInsensitiveField(bool allow) {
+ allow_case_insensitive_field_ = allow;
+ }
+
// Like TextFormat::ParseFieldValueFromString
bool ParseFieldValueFromString(const string& input,
const FieldDescriptor* field,
Message* output);
+
+ void AllowFieldNumber(bool allow) {
+ allow_field_number_ = allow;
+ }
+
private:
// Forward declaration of an internal class used to parse text
// representations (see text_format.cc for implementation).
@@ -251,13 +429,44 @@ class LIBPROTOBUF_EXPORT TextFormat {
ParserImpl* parser_impl);
io::ErrorCollector* error_collector_;
+ Finder* finder_;
+ ParseInfoTree* parse_info_tree_;
bool allow_partial_;
+ bool allow_case_insensitive_field_;
+ bool allow_unknown_field_;
+ bool allow_unknown_enum_;
+ bool allow_field_number_;
+ bool allow_relaxed_whitespace_;
+ bool allow_singular_overwrites_;
};
+
private:
+ // Hack: ParseInfoTree declares TextFormat as a friend which should extend
+ // the friendship to TextFormat::Parser::ParserImpl, but unfortunately some
+ // old compilers (e.g. GCC 3.4.6) don't implement this correctly. We provide
+ // helpers for ParserImpl to call methods of ParseInfoTree.
+ static inline void RecordLocation(ParseInfoTree* info_tree,
+ const FieldDescriptor* field,
+ ParseLocation location);
+ static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree,
+ const FieldDescriptor* field);
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat);
};
+inline void TextFormat::RecordLocation(ParseInfoTree* info_tree,
+ const FieldDescriptor* field,
+ ParseLocation location) {
+ info_tree->RecordLocation(field, location);
+}
+
+
+inline TextFormat::ParseInfoTree* TextFormat::CreateNested(
+ ParseInfoTree* info_tree, const FieldDescriptor* field) {
+ return info_tree->CreateNested(field);
+}
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc
index ddf8ff7..5573268 100644
--- a/src/google/protobuf/text_format_unittest.cc
+++ b/src/google/protobuf/text_format_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -74,10 +74,11 @@ const string kEscapeTestStringEscaped =
class TextFormatTest : public testing::Test {
public:
static void SetUpTestCase() {
- File::ReadFileToStringOrDie(
- TestSourceDir()
- + "/google/protobuf/testdata/text_format_unittest_data.txt",
- &static_proto_debug_string_);
+ GOOGLE_CHECK_OK(File::GetContents(
+ TestSourceDir() +
+ "/google/protobuf/"
+ "testdata/text_format_unittest_data_oneof_implemented.txt",
+ &static_proto_debug_string_, true));
}
TextFormatTest() : proto_debug_string_(static_proto_debug_string_) {}
@@ -95,11 +96,10 @@ string TextFormatTest::static_proto_debug_string_;
class TextFormatExtensionsTest : public testing::Test {
public:
static void SetUpTestCase() {
- File::ReadFileToStringOrDie(
- TestSourceDir()
- + "/google/protobuf/testdata/"
- "text_format_unittest_extensions_data.txt",
- &static_proto_debug_string_);
+ GOOGLE_CHECK_OK(File::GetContents(TestSourceDir() +
+ "/google/protobuf/testdata/"
+ "text_format_unittest_extensions_data.txt",
+ &static_proto_debug_string_, true));
}
TextFormatExtensionsTest()
@@ -205,16 +205,25 @@ TEST_F(TextFormatTest, StringEscape) {
TEST_F(TextFormatTest, Utf8DebugString) {
// Set the string value to test.
proto_.set_optional_string("\350\260\267\346\255\214");
+ proto_.set_optional_bytes("\350\260\267\346\255\214");
// Get the DebugString from the proto.
string debug_string = proto_.DebugString();
string utf8_debug_string = proto_.Utf8DebugString();
// Hardcode a correct value to test against.
- string correct_utf8_string = "optional_string: "
+ string correct_utf8_string =
+ "optional_string: "
"\"\350\260\267\346\255\214\""
+ "\n"
+ "optional_bytes: "
+ "\"\\350\\260\\267\\346\\255\\214\""
"\n";
- string correct_string = "optional_string: "
+ string correct_string =
+ "optional_string: "
+ "\"\\350\\260\\267\\346\\255\\214\""
+ "\n"
+ "optional_bytes: "
"\"\\350\\260\\267\\346\\255\\214\""
"\n";
@@ -253,6 +262,31 @@ TEST_F(TextFormatTest, PrintUnknownFields) {
message.DebugString());
}
+TEST_F(TextFormatTest, PrintUnknownFieldsHidden) {
+ // Test printing of unknown fields in a message when supressed.
+
+ unittest::OneString message;
+ message.set_data("data");
+ UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
+
+ unknown_fields->AddVarint(5, 1);
+ unknown_fields->AddFixed32(5, 2);
+ unknown_fields->AddFixed64(5, 3);
+ unknown_fields->AddLengthDelimited(5, "4");
+ unknown_fields->AddGroup(5)->AddVarint(10, 5);
+
+ unknown_fields->AddVarint(8, 1);
+ unknown_fields->AddVarint(8, 2);
+ unknown_fields->AddVarint(8, 3);
+
+ TextFormat::Printer printer;
+ printer.SetHideUnknownFields(true);
+ string output;
+ printer.PrintToString(message, &output);
+
+ EXPECT_EQ("data: \"data\"\n", output);
+}
+
TEST_F(TextFormatTest, PrintUnknownMessage) {
// Test heuristic printing of messages in an UnknownFieldSet.
@@ -339,6 +373,161 @@ TEST_F(TextFormatTest, PrintMessageSingleLine) {
text);
}
+TEST_F(TextFormatTest, PrintBufferTooSmall) {
+ // Test printing a message to a buffer that is too small.
+
+ protobuf_unittest::TestAllTypes message;
+
+ message.add_repeated_string("abc");
+ message.add_repeated_string("def");
+
+ char buffer[1] = "";
+ io::ArrayOutputStream output_stream(buffer, 1);
+ EXPECT_FALSE(TextFormat::Print(message, &output_stream));
+ EXPECT_EQ(buffer[0], 'r');
+ EXPECT_EQ(output_stream.ByteCount(), 1);
+}
+
+// A printer that appends 'u' to all unsigned int32.
+class CustomUInt32FieldValuePrinter : public TextFormat::FieldValuePrinter {
+ public:
+ virtual string PrintUInt32(uint32 val) const {
+ return StrCat(FieldValuePrinter::PrintUInt32(val), "u");
+ }
+};
+
+TEST_F(TextFormatTest, DefaultCustomFieldPrinter) {
+ protobuf_unittest::TestAllTypes message;
+
+ message.set_optional_uint32(42);
+ message.add_repeated_uint32(1);
+ message.add_repeated_uint32(2);
+ message.add_repeated_uint32(3);
+
+ TextFormat::Printer printer;
+ printer.SetDefaultFieldValuePrinter(new CustomUInt32FieldValuePrinter());
+ // Let's see if that works well together with the repeated primitives:
+ printer.SetUseShortRepeatedPrimitives(true);
+ string text;
+ printer.PrintToString(message, &text);
+ EXPECT_EQ("optional_uint32: 42u\nrepeated_uint32: [1u, 2u, 3u]\n", text);
+}
+
+class CustomInt32FieldValuePrinter : public TextFormat::FieldValuePrinter {
+ public:
+ virtual string PrintInt32(int32 val) const {
+ return StrCat("value-is(", FieldValuePrinter::PrintInt32(val), ")");
+ }
+};
+
+TEST_F(TextFormatTest, FieldSpecificCustomPrinter) {
+ protobuf_unittest::TestAllTypes message;
+
+ message.set_optional_int32(42); // This will be handled by our Printer.
+ message.add_repeated_int32(42); // This will be printed as number.
+
+ TextFormat::Printer printer;
+ EXPECT_TRUE(printer.RegisterFieldValuePrinter(
+ message.GetDescriptor()->FindFieldByName("optional_int32"),
+ new CustomInt32FieldValuePrinter()));
+ string text;
+ printer.PrintToString(message, &text);
+ EXPECT_EQ("optional_int32: value-is(42)\nrepeated_int32: 42\n", text);
+}
+
+TEST_F(TextFormatTest, ErrorCasesRegisteringFieldValuePrinterShouldFail) {
+ protobuf_unittest::TestAllTypes message;
+ TextFormat::Printer printer;
+ // NULL printer.
+ EXPECT_FALSE(printer.RegisterFieldValuePrinter(
+ message.GetDescriptor()->FindFieldByName("optional_int32"),
+ NULL));
+ // Because registration fails, the ownership of this printer is never taken.
+ TextFormat::FieldValuePrinter my_field_printer;
+ // NULL field
+ EXPECT_FALSE(printer.RegisterFieldValuePrinter(NULL, &my_field_printer));
+}
+
+class CustomMessageFieldValuePrinter : public TextFormat::FieldValuePrinter {
+ public:
+ virtual string PrintInt32(int32 v) const {
+ return StrCat(FieldValuePrinter::PrintInt32(v), " # x", ToHex(v));
+ }
+
+ virtual string PrintMessageStart(const Message& message,
+ int field_index,
+ int field_count,
+ bool single_line_mode) const {
+ if (single_line_mode) {
+ return " { ";
+ }
+ return StrCat(
+ " { # ", message.GetDescriptor()->name(), ": ", field_index, "\n");
+ }
+};
+
+TEST_F(TextFormatTest, CustomPrinterForComments) {
+ protobuf_unittest::TestAllTypes message;
+ message.mutable_optional_nested_message();
+ message.mutable_optional_import_message()->set_d(42);
+ message.add_repeated_nested_message();
+ message.add_repeated_nested_message();
+ message.add_repeated_import_message()->set_d(43);
+ message.add_repeated_import_message()->set_d(44);
+ TextFormat::Printer printer;
+ CustomMessageFieldValuePrinter my_field_printer;
+ printer.SetDefaultFieldValuePrinter(new CustomMessageFieldValuePrinter());
+ string text;
+ printer.PrintToString(message, &text);
+ EXPECT_EQ(
+ "optional_nested_message { # NestedMessage: -1\n"
+ "}\n"
+ "optional_import_message { # ImportMessage: -1\n"
+ " d: 42 # x2a\n"
+ "}\n"
+ "repeated_nested_message { # NestedMessage: 0\n"
+ "}\n"
+ "repeated_nested_message { # NestedMessage: 1\n"
+ "}\n"
+ "repeated_import_message { # ImportMessage: 0\n"
+ " d: 43 # x2b\n"
+ "}\n"
+ "repeated_import_message { # ImportMessage: 1\n"
+ " d: 44 # x2c\n"
+ "}\n",
+ text);
+}
+
+class CustomMultilineCommentPrinter : public TextFormat::FieldValuePrinter {
+ public:
+ virtual string PrintMessageStart(const Message& message,
+ int field_index,
+ int field_count,
+ bool single_line_comment) const {
+ return StrCat(" { # 1\n", " # 2\n");
+ }
+};
+
+TEST_F(TextFormatTest, CustomPrinterForMultilineComments) {
+ protobuf_unittest::TestAllTypes message;
+ message.mutable_optional_nested_message();
+ message.mutable_optional_import_message()->set_d(42);
+ TextFormat::Printer printer;
+ CustomMessageFieldValuePrinter my_field_printer;
+ printer.SetDefaultFieldValuePrinter(new CustomMultilineCommentPrinter());
+ string text;
+ printer.PrintToString(message, &text);
+ EXPECT_EQ(
+ "optional_nested_message { # 1\n"
+ " # 2\n"
+ "}\n"
+ "optional_import_message { # 1\n"
+ " # 2\n"
+ " d: 42\n"
+ "}\n",
+ text);
+}
+
TEST_F(TextFormatTest, ParseBasic) {
io::ArrayInputStream input_stream(proto_debug_string_.data(),
proto_debug_string_.size());
@@ -353,6 +542,25 @@ TEST_F(TextFormatExtensionsTest, ParseExtensions) {
TestUtil::ExpectAllExtensionsSet(proto_);
}
+TEST_F(TextFormatTest, ParseEnumFieldFromNumber) {
+ // Create a parse string with a numerical value for an enum field.
+ string parse_string = strings::Substitute("optional_nested_enum: $0",
+ unittest::TestAllTypes::BAZ);
+ EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
+ EXPECT_TRUE(proto_.has_optional_nested_enum());
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.optional_nested_enum());
+}
+
+TEST_F(TextFormatTest, ParseEnumFieldFromNegativeNumber) {
+ ASSERT_LT(unittest::SPARSE_E, 0);
+ string parse_string = strings::Substitute("sparse_enum: $0",
+ unittest::SPARSE_E);
+ unittest::SparseEnumMessage proto;
+ EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
+ EXPECT_TRUE(proto.has_sparse_enum());
+ EXPECT_EQ(unittest::SPARSE_E, proto.sparse_enum());
+}
+
TEST_F(TextFormatTest, ParseStringEscape) {
// Create a parse string with escpaed characters in it.
string parse_string = "optional_string: "
@@ -406,6 +614,47 @@ TEST_F(TextFormatTest, ParseFloatWithSuffix) {
EXPECT_EQ(1.0, proto_.optional_float());
}
+TEST_F(TextFormatTest, ParseShortRepeatedForm) {
+ string parse_string =
+ // Mixed short-form and long-form are simply concatenated.
+ "repeated_int32: 1\n"
+ "repeated_int32: [456, 789]\n"
+ "repeated_nested_enum: [ FOO ,BAR, # comment\n"
+ " 3]\n"
+ // Note that while the printer won't print repeated strings in short-form,
+ // the parser will accept them.
+ "repeated_string: [ \"foo\", 'bar' ]\n"
+ // Repeated message
+ "repeated_nested_message: [ { bb: 1 }, { bb : 2 }]\n"
+ // Repeated group
+ "RepeatedGroup [{ a: 3 },{ a: 4 }]\n";
+
+ ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
+
+ ASSERT_EQ(3, proto_.repeated_int32_size());
+ EXPECT_EQ(1, proto_.repeated_int32(0));
+ EXPECT_EQ(456, proto_.repeated_int32(1));
+ EXPECT_EQ(789, proto_.repeated_int32(2));
+
+ ASSERT_EQ(3, proto_.repeated_nested_enum_size());
+ EXPECT_EQ(unittest::TestAllTypes::FOO, proto_.repeated_nested_enum(0));
+ EXPECT_EQ(unittest::TestAllTypes::BAR, proto_.repeated_nested_enum(1));
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.repeated_nested_enum(2));
+
+ ASSERT_EQ(2, proto_.repeated_string_size());
+ EXPECT_EQ("foo", proto_.repeated_string(0));
+ EXPECT_EQ("bar", proto_.repeated_string(1));
+
+ ASSERT_EQ(2, proto_.repeated_nested_message_size());
+ EXPECT_EQ(1, proto_.repeated_nested_message(0).bb());
+ EXPECT_EQ(2, proto_.repeated_nested_message(1).bb());
+
+ ASSERT_EQ(2, proto_.repeatedgroup_size());
+ EXPECT_EQ(3, proto_.repeatedgroup(0).a());
+ EXPECT_EQ(4, proto_.repeatedgroup(1).a());
+}
+
+
TEST_F(TextFormatTest, Comments) {
// Test that comments are ignored.
@@ -658,6 +907,27 @@ TEST_F(TextFormatTest, ParseExotic) {
message.repeated_string(0));
}
+TEST_F(TextFormatTest, PrintFieldsInIndexOrder) {
+ protobuf_unittest::TestFieldOrderings message;
+ // Fields are listed in index order instead of field number.
+ message.set_my_string("Test String"); // Field number 11
+ message.set_my_int(12345); // Field number 1
+ message.set_my_float(0.999); // Field number 101
+ TextFormat::Printer printer;
+ string text;
+
+ // By default, print in field number order.
+ printer.PrintToString(message, &text);
+ EXPECT_EQ("my_int: 12345\nmy_string: \"Test String\"\nmy_float: 0.999\n",
+ text);
+
+ // Print in index order.
+ printer.SetPrintMessageFieldsInIndexOrder(true);
+ printer.PrintToString(message, &text);
+ EXPECT_EQ("my_string: \"Test String\"\nmy_int: 12345\nmy_float: 0.999\n",
+ text);
+}
+
class TextFormatParserTest : public testing::Test {
protected:
void ExpectFailure(const string& input, const string& message, int line,
@@ -676,11 +946,31 @@ class TextFormatParserTest : public testing::Test {
TextFormat::Parser parser;
MockErrorCollector error_collector;
parser.RecordErrorsTo(&error_collector);
- EXPECT_EQ(parser.ParseFromString(input, proto), expected_result);
+ EXPECT_EQ(expected_result, parser.ParseFromString(input, proto))
+ << input << " -> " << proto->DebugString();
EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) + ": " + message + "\n",
error_collector.text_);
}
+ void ExpectSuccessAndTree(const string& input, Message* proto,
+ TextFormat::ParseInfoTree* info_tree) {
+ TextFormat::Parser parser;
+ MockErrorCollector error_collector;
+ parser.RecordErrorsTo(&error_collector);
+ parser.WriteLocationsTo(info_tree);
+
+ EXPECT_TRUE(parser.ParseFromString(input, proto));
+ }
+
+ void ExpectLocation(TextFormat::ParseInfoTree* tree,
+ const Descriptor* d, const string& field_name,
+ int index, int line, int column) {
+ TextFormat::ParseLocation location = tree->GetLocation(
+ d->FindFieldByName(field_name), index);
+ EXPECT_EQ(line, location.line);
+ EXPECT_EQ(column, location.column);
+ }
+
// An error collector which simply concatenates all its errors into a big
// block of text which can be checked.
class MockErrorCollector : public io::ErrorCollector {
@@ -702,6 +992,71 @@ class TextFormatParserTest : public testing::Test {
};
};
+TEST_F(TextFormatParserTest, ParseInfoTreeBuilding) {
+ scoped_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes);
+ const Descriptor* d = message->GetDescriptor();
+
+ 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"
+ ">";
+
+
+ TextFormat::ParseInfoTree tree;
+ ExpectSuccessAndTree(stringData, message.get(), &tree);
+
+ // Verify that the tree has the correct positions.
+ ExpectLocation(&tree, d, "optional_int32", -1, 0, 0);
+ ExpectLocation(&tree, d, "optional_int64", -1, 1, 0);
+ ExpectLocation(&tree, d, "optional_double", -1, 2, 2);
+
+ ExpectLocation(&tree, d, "repeated_int32", 0, 3, 0);
+ ExpectLocation(&tree, d, "repeated_int32", 1, 4, 0);
+
+ ExpectLocation(&tree, d, "optional_nested_message", -1, 5, 0);
+ ExpectLocation(&tree, d, "repeated_nested_message", 0, 8, 0);
+ ExpectLocation(&tree, d, "repeated_nested_message", 1, 11, 0);
+
+ // Check for fields not set. For an invalid field, the location returned
+ // should be -1, -1.
+ ExpectLocation(&tree, d, "repeated_int64", 0, -1, -1);
+ ExpectLocation(&tree, d, "repeated_int32", 6, -1, -1);
+ ExpectLocation(&tree, d, "some_unknown_field", -1, -1, -1);
+
+ // Verify inside the nested message.
+ const FieldDescriptor* nested_field =
+ d->FindFieldByName("optional_nested_message");
+
+ TextFormat::ParseInfoTree* nested_tree =
+ tree.GetTreeForNested(nested_field, -1);
+ ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 6, 2);
+
+ // Verify inside another nested message.
+ nested_field = d->FindFieldByName("repeated_nested_message");
+ nested_tree = tree.GetTreeForNested(nested_field, 0);
+ ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 9, 2);
+
+ nested_tree = tree.GetTreeForNested(nested_field, 1);
+ ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 12, 2);
+
+ // Verify a NULL tree for an unknown nested field.
+ TextFormat::ParseInfoTree* unknown_nested_tree =
+ tree.GetTreeForNested(nested_field, 2);
+
+ EXPECT_EQ(NULL, unknown_nested_tree);
+}
+
TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
scoped_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes);
const Descriptor* d = message->GetDescriptor();
@@ -712,6 +1067,12 @@ TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
EXPECT_EQ(value, message->optional_##name()); \
EXPECT_TRUE(message->has_optional_##name());
+#define EXPECT_BOOL_FIELD(name, value, valuestring) \
+ EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
+ valuestring, d->FindFieldByName("optional_" #name), message.get())); \
+ EXPECT_TRUE(message->optional_##name() == value); \
+ EXPECT_TRUE(message->has_optional_##name());
+
#define EXPECT_FLOAT_FIELD(name, value, valuestring) \
EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
valuestring, d->FindFieldByName("optional_" #name), message.get())); \
@@ -769,12 +1130,20 @@ TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
EXPECT_INVALID(fixed64, "1,2");
// bool
- EXPECT_FIELD(bool, true, "true");
- EXPECT_FIELD(bool, false, "false");
- EXPECT_INVALID(bool, "1");
+ EXPECT_BOOL_FIELD(bool, true, "true");
+ EXPECT_BOOL_FIELD(bool, false, "false");
+ EXPECT_BOOL_FIELD(bool, true, "1");
+ EXPECT_BOOL_FIELD(bool, true, "t");
+ EXPECT_BOOL_FIELD(bool, false, "0");
+ EXPECT_BOOL_FIELD(bool, false, "f");
+ EXPECT_FIELD(bool, true, "True");
+ EXPECT_FIELD(bool, false, "False");
+ EXPECT_INVALID(bool, "tRue");
+ EXPECT_INVALID(bool, "faLse");
+ EXPECT_INVALID(bool, "2");
+ EXPECT_INVALID(bool, "-0");
EXPECT_INVALID(bool, "on");
EXPECT_INVALID(bool, "a");
- EXPECT_INVALID(bool, "True");
// float
EXPECT_FIELD(float, 1, "1");
@@ -791,6 +1160,9 @@ TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
EXPECT_DOUBLE_FIELD(double, 3e5, "3e5");
EXPECT_INVALID(double, "a");
EXPECT_INVALID(double, "1,2");
+ // Rejects hex and oct numbers for a double field.
+ EXPECT_INVALID(double, "0xf");
+ EXPECT_INVALID(double, "012");
// string
EXPECT_FIELD(string, "hello", "\"hello\"");
@@ -799,7 +1171,8 @@ TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
// enum
EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR");
- EXPECT_INVALID(nested_enum, "1"); // number not supported
+ EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAZ,
+ SimpleItoa(unittest::TestAllTypes::BAZ));
EXPECT_INVALID(nested_enum, "FOOBAR");
// message
@@ -810,6 +1183,7 @@ TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
EXPECT_INVALID(nested_message, "any");
#undef EXPECT_FIELD
+#undef EXPECT_BOOL_FIELD
#undef EXPECT_FLOAT_FIELD
#undef EXPECT_DOUBLE_FIELD
#undef EXPECT_INVALID
@@ -820,7 +1194,7 @@ TEST_F(TextFormatParserTest, InvalidToken) {
ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.",
2, 1);
- ExpectFailure("optional_bool: true;\n", "Expected identifier.", 1, 20);
+ ExpectFailure("optional_bool: true!\n", "Expected identifier.", 1, 20);
ExpectFailure("\"some string\"", "Expected identifier.", 1, 1);
}
@@ -851,6 +1225,22 @@ TEST_F(TextFormatParserTest, InvalidCapitalization) {
1, 16);
}
+TEST_F(TextFormatParserTest, AllowIgnoreCapitalizationError) {
+ TextFormat::Parser parser;
+ protobuf_unittest::TestAllTypes proto;
+
+ // These fields have a mismatching case.
+ EXPECT_FALSE(parser.ParseFromString("Optional_Double: 10.0", &proto));
+ EXPECT_FALSE(parser.ParseFromString("oPtIoNaLgRoUp { a: 15 }", &proto));
+
+ // ... but are parsed correctly if we match case insensitive.
+ parser.AllowCaseInsensitiveField(true);
+ EXPECT_TRUE(parser.ParseFromString("Optional_Double: 10.0", &proto));
+ EXPECT_EQ(10.0, proto.optional_double());
+ EXPECT_TRUE(parser.ParseFromString("oPtIoNaLgRoUp { a: 15 }", &proto));
+ EXPECT_EQ(15, proto.optionalgroup().a());
+}
+
TEST_F(TextFormatParserTest, InvalidFieldValues) {
// Invalid values for a double/float field.
ExpectFailure("optional_double: \"hello\"\n", "Expected double.", 1, 18);
@@ -868,10 +1258,10 @@ TEST_F(TextFormatParserTest, InvalidFieldValues) {
1, 16);
ExpectFailure("optional_int32: 0x80000000\n",
"Integer out of range.", 1, 17);
- ExpectFailure("optional_int32: -0x80000001\n",
- "Integer out of range.", 1, 18);
ExpectFailure("optional_int64: 0x8000000000000000\n",
"Integer out of range.", 1, 17);
+ ExpectFailure("optional_int32: -0x80000001\n",
+ "Integer out of range.", 1, 18);
ExpectFailure("optional_int64: -0x8000000000000001\n",
"Integer out of range.", 1, 18);
@@ -890,7 +1280,7 @@ TEST_F(TextFormatParserTest, InvalidFieldValues) {
// Invalid values for a boolean field.
ExpectFailure("optional_bool: \"hello\"\n", "Expected identifier.", 1, 16);
- ExpectFailure("optional_bool: 5\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);
@@ -911,12 +1301,18 @@ TEST_F(TextFormatParserTest, InvalidFieldValues) {
1, 17);
// Invalid values for an enumeration field.
- ExpectFailure("optional_nested_enum: \"hello\"\n", "Expected identifier.",
- 1, 23);
-
- ExpectFailure("optional_nested_enum: 5\n", "Expected identifier.", 1, 23);
- ExpectFailure("optional_nested_enum: -7.5\n", "Expected identifier.", 1, 23);
- ExpectFailure("optional_nested_enum: !\n", "Expected identifier.", 1, 23);
+ ExpectFailure("optional_nested_enum: \"hello\"\n",
+ "Expected integer or identifier.", 1, 23);
+
+ // Valid token, but enum value is not defined.
+ ExpectFailure("optional_nested_enum: 5\n",
+ "Unknown enumeration value of \"5\" for field "
+ "\"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: !\n",
+ "Expected integer or identifier.", 1, 23);
ExpectFailure(
"optional_nested_enum: grah\n",
@@ -986,6 +1382,14 @@ TEST_F(TextFormatParserTest, MergeDuplicateOptional) {
EXPECT_EQ(2, message.c());
}
+TEST_F(TextFormatParserTest, ExplicitDelimiters) {
+ unittest::TestRequired message;
+ EXPECT_TRUE(TextFormat::ParseFromString("a:1,b:2;c:3", &message));
+ EXPECT_EQ(1, message.a());
+ EXPECT_EQ(2, message.b());
+ EXPECT_EQ(3, message.c());
+}
+
TEST_F(TextFormatParserTest, PrintErrorsToStderr) {
vector<string> errors;
@@ -1069,6 +1473,7 @@ TEST_F(TextFormatMessageSetTest, Deserialize) {
EXPECT_EQ(2, descriptors.size());
}
+
} // namespace text_format_unittest
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto
index d51fa1e..c48cc92 100644
--- a/src/google/protobuf/unittest.proto
+++ b/src/google/protobuf/unittest.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,6 +35,12 @@
// 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
@@ -63,6 +69,7 @@ message TestAllTypes {
FOO = 1;
BAR = 2;
BAZ = 3;
+ NEG = -1; // Intentionally negative.
}
// Singular
@@ -97,6 +104,12 @@ message TestAllTypes {
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;
@@ -129,6 +142,8 @@ message TestAllTypes {
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 ];
@@ -153,6 +168,20 @@ message TestAllTypes {
optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
optional string default_cord = 85 [ctype=CORD,default="123"];
+
+ // For oneof test
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ }
+}
+
+// This proto includes a recusively nested message.
+message NestedTestAllTypes {
+ optional NestedTestAllTypes child = 1;
+ optional TestAllTypes payload = 2;
}
message TestDeprecatedFields {
@@ -210,6 +239,12 @@ extend TestAllExtensions {
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;
@@ -244,6 +279,9 @@ extend TestAllExtensions {
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 ];
@@ -271,6 +309,12 @@ extend TestAllExtensions {
optional string default_string_piece_extension = 84 [ctype=STRING_PIECE,
default="abc"];
optional string default_cord_extension = 85 [ctype=CORD, default="123"];
+
+ // For oneof test
+ optional uint32 oneof_uint32_extension = 111;
+ optional TestAllTypes.NestedMessage oneof_nested_message_extension = 112;
+ optional string oneof_string_extension = 113;
+ optional bytes oneof_bytes_extension = 114;
}
message TestNestedExtension {
@@ -278,6 +322,9 @@ message TestNestedExtension {
// Check for bug where string extensions declared in tested scope did not
// compile.
optional string test = 1002 [default="test"];
+ // Used to test if generated extension name is correct when there are
+ // underscores.
+ optional string nested_string_extension = 1003;
}
}
@@ -391,6 +438,13 @@ message TestDupFieldNumber { // 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 {
@@ -404,6 +458,8 @@ message TestNestedMessageHasBits {
// Test an enum that has multiple values with the same number.
enum TestEnumWithDupValue {
+ option allow_alias = true;
+
FOO1 = 1;
BAR1 = 2;
BAZ = 3;
@@ -464,6 +520,8 @@ message TestExtremeDefaultValues {
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
@@ -487,6 +545,26 @@ message TestExtremeDefaultValues {
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"];
+ optional string replacement_string = 27 [default="${unknown}"];
+}
+
+message SparseEnumMessage {
+ optional TestSparseEnum sparse_enum = 1;
}
// Test String and Bytes: string is for valid UTF-8 strings
@@ -494,10 +572,113 @@ 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 int32, uint32, int64, uint64, and bool are all compatible
+message Int32Message {
+ optional int32 data = 1;
+}
+
+message Uint32Message {
+ optional uint32 data = 1;
+}
+
+message Int64Message {
+ optional int64 data = 1;
+}
+
+message Uint64Message {
+ optional uint64 data = 1;
+}
+
+message BoolMessage {
+ optional bool data = 1;
+}
+
+// Test oneofs.
+message TestOneof {
+ oneof foo {
+ int32 foo_int = 1;
+ string foo_string = 2;
+ TestAllTypes foo_message = 3;
+ group FooGroup = 4 {
+ optional int32 a = 5;
+ optional string b = 6;
+ }
+ }
+}
+
+message TestOneofBackwardsCompatible {
+ optional int32 foo_int = 1;
+ optional string foo_string = 2;
+ optional TestAllTypes foo_message = 3;
+ optional group FooGroup = 4 {
+ optional int32 a = 5;
+ optional string b = 6;
+ }
+}
+
+message TestOneof2 {
+ oneof foo {
+ int32 foo_int = 1;
+ string foo_string = 2;
+ string foo_cord = 3 [ctype=CORD];
+ string foo_string_piece = 4 [ctype=STRING_PIECE];
+ bytes foo_bytes = 5;
+ NestedEnum foo_enum = 6;
+ NestedMessage foo_message = 7;
+ group FooGroup = 8 {
+ optional int32 a = 9;
+ optional string b = 10;
+ }
+ NestedMessage foo_lazy_message = 11 [lazy=true];
+ }
+
+ oneof bar {
+ int32 bar_int = 12 [default = 5];
+ string bar_string = 13 [default = "STRING"];
+ string bar_cord = 14 [ctype=CORD, default = "CORD"];
+ string bar_string_piece = 15 [ctype=STRING_PIECE, default = "SPIECE"];
+ bytes bar_bytes = 16 [default = "BYTES"];
+ NestedEnum bar_enum = 17 [default = BAR];
+ }
+
+ optional int32 baz_int = 18;
+ optional string baz_string = 19 [default = "BAZ"];
+
+ message NestedMessage {
+ optional int64 qux_int = 1;
+ repeated int32 corge_int = 2;
+ }
+
+ enum NestedEnum {
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ }
+}
+
+message TestRequiredOneof {
+ oneof foo {
+ int32 foo_int = 1;
+ string foo_string = 2;
+ NestedMessage foo_message = 3;
+ }
+ message NestedMessage {
+ required double required_double = 1;
+ }
+}
+
// Test messages for packed fields
message TestPackedTypes {
@@ -557,6 +738,27 @@ extend TestPackedExtensions {
repeated ForeignEnum packed_enum_extension = 103 [packed = true];
}
+message TestUnpackedExtensions {
+ extensions 1 to max;
+}
+
+extend TestUnpackedExtensions {
+ repeated int32 unpacked_int32_extension = 90 [packed = false];
+ repeated int64 unpacked_int64_extension = 91 [packed = false];
+ repeated uint32 unpacked_uint32_extension = 92 [packed = false];
+ repeated uint64 unpacked_uint64_extension = 93 [packed = false];
+ repeated sint32 unpacked_sint32_extension = 94 [packed = false];
+ repeated sint64 unpacked_sint64_extension = 95 [packed = false];
+ repeated fixed32 unpacked_fixed32_extension = 96 [packed = false];
+ repeated fixed64 unpacked_fixed64_extension = 97 [packed = false];
+ repeated sfixed32 unpacked_sfixed32_extension = 98 [packed = false];
+ repeated sfixed64 unpacked_sfixed64_extension = 99 [packed = false];
+ repeated float unpacked_float_extension = 100 [packed = false];
+ repeated double unpacked_double_extension = 101 [packed = false];
+ repeated bool unpacked_bool_extension = 102 [packed = false];
+ repeated ForeignEnum unpacked_enum_extension = 103 [packed = false];
+}
+
// Used by ExtensionSetTest/DynamicExtensions. The test actually builds
// a set of extensions to TestAllExtensions dynamically, based on the fields
// of this message type.
@@ -598,10 +800,56 @@ message TestRepeatedScalarDifferentTagSizes {
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);
@@ -610,3 +858,4 @@ service TestService {
message BarRequest {}
message BarResponse {}
+
diff --git a/src/google/protobuf/unittest_custom_options.proto b/src/google/protobuf/unittest_custom_options.proto
index b6ee03d..0bb12e1 100644
--- a/src/google/protobuf/unittest_custom_options.proto
+++ b/src/google/protobuf/unittest_custom_options.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -35,6 +35,12 @@
// 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;
@@ -110,6 +116,12 @@ message CustomOptionFooRequest {
message CustomOptionFooResponse {
}
+message CustomOptionFooClientMessage {
+}
+
+message CustomOptionFooServerMessage {
+}
+
service TestServiceWithCustomOptions {
option (service_opt1) = -9876543210;
@@ -206,6 +218,7 @@ message ComplexOptionType1 {
optional int32 foo = 1;
optional int32 foo2 = 2;
optional int32 foo3 = 3;
+ repeated int32 foo4 = 4;
extensions 100 to max;
}
@@ -223,6 +236,7 @@ message ComplexOptionType2 {
}
optional ComplexOptionType4 fred = 3;
+ repeated ComplexOptionType4 barney = 4;
extensions 100 to max;
}
@@ -259,6 +273,8 @@ 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 (protobuf_unittest.complex_opt1).foo4 = 99;
+ option (protobuf_unittest.complex_opt1).foo4 = 88;
option (complex_opt2).baz = 987;
option (complex_opt2).(grault) = 654;
option (complex_opt2).bar.foo = 743;
@@ -269,7 +285,109 @@ message VariousComplexOptions {
option (complex_opt2).(protobuf_unittest.garply).(corge).qux = 2121;
option (ComplexOptionType2.ComplexOptionType4.complex_opt4).waldo = 1971;
option (complex_opt2).fred.waldo = 321;
+ option (complex_opt2).barney = { waldo: 101 };
+ option (complex_opt2).barney = { waldo: 212 };
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/src/google/protobuf/unittest_embed_optimize_for.proto b/src/google/protobuf/unittest_embed_optimize_for.proto
index fa17625..ad51513 100644
--- a/src/google/protobuf/unittest_embed_optimize_for.proto
+++ b/src/google/protobuf/unittest_embed_optimize_for.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/unittest_empty.proto b/src/google/protobuf/unittest_empty.proto
index ab12d1f..b7337ef 100644
--- a/src/google/protobuf/unittest_empty.proto
+++ b/src/google/protobuf/unittest_empty.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/unittest_enormous_descriptor.proto b/src/google/protobuf/unittest_enormous_descriptor.proto
index bc0b7c1..3ba8b41 100644
--- a/src/google/protobuf/unittest_enormous_descriptor.proto
+++ b/src/google/protobuf/unittest_enormous_descriptor.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/unittest_extension_nano.proto b/src/google/protobuf/unittest_extension_nano.proto
index 2a678a8..ca56b3d 100644
--- a/src/google/protobuf/unittest_extension_nano.proto
+++ b/src/google/protobuf/unittest_extension_nano.proto
@@ -16,11 +16,15 @@ enum AnEnum {
message AnotherMessage {
optional string string = 1;
optional bool value = 2;
+ repeated int32 integers = 3;
}
message ContainerMessage {
extend ExtendableMessage {
optional bool another_thing = 100;
+ // The largest permitted field number, per
+ // https://developers.google.com/protocol-buffers/docs/proto#simple
+ optional bool large_field_number = 536870911;
}
}
diff --git a/src/google/protobuf/unittest_import.proto b/src/google/protobuf/unittest_import.proto
index cd533ec..38275dc 100644
--- a/src/google/protobuf/unittest_import.proto
+++ b/src/google/protobuf/unittest_import.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -49,6 +49,9 @@ 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;
}
diff --git a/src/google/protobuf/unittest_import_lite.proto b/src/google/protobuf/unittest_import_lite.proto
index ebaab5c..7cee113 100644
--- a/src/google/protobuf/unittest_import_lite.proto
+++ b/src/google/protobuf/unittest_import_lite.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -38,6 +38,8 @@ 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;
}
diff --git a/src/google/protobuf/unittest_import_public.proto b/src/google/protobuf/unittest_import_public.proto
new file mode 100644
index 0000000..e5929cb
--- /dev/null
+++ b/src/google/protobuf/unittest_import_public.proto
@@ -0,0 +1,40 @@
+// 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: 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/src/google/protobuf/unittest_import_public_lite.proto b/src/google/protobuf/unittest_import_public_lite.proto
new file mode 100644
index 0000000..e39bdb4
--- /dev/null
+++ b/src/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.
+// 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: 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/src/google/protobuf/unittest_lite.proto b/src/google/protobuf/unittest_lite.proto
index cca6b49..30dd67f 100644
--- a/src/google/protobuf/unittest_lite.proto
+++ b/src/google/protobuf/unittest_lite.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -85,6 +85,12 @@ message TestAllTypesLite {
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;
@@ -118,6 +124,8 @@ message TestAllTypesLite {
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 ];
@@ -143,6 +151,14 @@ message TestAllTypesLite {
optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
optional string default_cord = 85 [ctype=CORD,default="123"];
+
+ // For oneof test
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ }
}
message ForeignMessageLite {
@@ -213,6 +229,12 @@ extend TestAllExtensionsLite {
[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;
@@ -249,6 +271,9 @@ extend TestAllExtensionsLite {
[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 ];
@@ -276,6 +301,12 @@ extend TestAllExtensionsLite {
optional string default_string_piece_extension_lite = 84 [ctype=STRING_PIECE,
default="abc"];
optional string default_cord_extension_lite = 85 [ctype=CORD, default="123"];
+
+ // For oneof test
+ optional uint32 oneof_uint32_extension_lite = 111;
+ optional TestAllTypesLite.NestedMessage oneof_nested_message_extension_lite = 112;
+ optional string oneof_string_extension_lite = 113;
+ optional bytes oneof_bytes_extension_lite = 114;
}
message TestPackedExtensionsLite {
@@ -310,3 +341,44 @@ message TestNestedExtensionLite {
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;
+ }
+}
+
+// TestEmptyMessageLite is used to test unknown fields support in lite mode.
+message TestEmptyMessageLite{
+}
+
+// Like above, but declare all field numbers as potential extensions. No
+// actual extensions should ever be defined for this type.
+message TestEmptyMessageWithExtensionsLite {
+ extensions 1 to max;
+}
diff --git a/src/google/protobuf/unittest_lite_imports_nonlite.proto b/src/google/protobuf/unittest_lite_imports_nonlite.proto
index d52cb8c..5ef8a06 100644
--- a/src/google/protobuf/unittest_lite_imports_nonlite.proto
+++ b/src/google/protobuf/unittest_lite_imports_nonlite.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
diff --git a/src/google/protobuf/unittest_mset.proto b/src/google/protobuf/unittest_mset.proto
index 3497f09..8fbe7ab 100644
--- a/src/google/protobuf/unittest_mset.proto
+++ b/src/google/protobuf/unittest_mset.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -62,6 +62,17 @@ message TestMessageSetExtension2 {
optional string str = 25;
}
+// 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"
+// extension.
+// message TestMessageSetUnknownExtension {
+// extend TestMessageSet {
+// optional TestMessageSetUnknownExtension message_set_extension = 56141421;
+// }
+// optional int64 a = 1;
+// }
+
// MessageSet wire format is equivalent to this.
message RawMessageSet {
repeated group Item = 1 {
diff --git a/src/google/protobuf/unittest_no_generic_services.proto b/src/google/protobuf/unittest_no_generic_services.proto
index fcae421..cf6d16c 100644
--- a/src/google/protobuf/unittest_no_generic_services.proto
+++ b/src/google/protobuf/unittest_no_generic_services.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,9 +32,8 @@
package google.protobuf.no_generic_services_test;
-option cc_generic_services = false;
-option java_generic_services = false;
-option py_generic_services = false;
+
+// *_generic_services are false by default.
message TestMessage {
optional int32 a = 1;
diff --git a/src/google/protobuf/unittest_optimize_for.proto b/src/google/protobuf/unittest_optimize_for.proto
index feecbef..9f7b4ee 100644
--- a/src/google/protobuf/unittest_optimize_for.proto
+++ b/src/google/protobuf/unittest_optimize_for.proto
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -50,12 +50,17 @@ message TestOptimizedForSize {
optional int32 test_extension = 1234;
optional TestRequiredOptimizedForSize test_extension2 = 1235;
}
+
+ oneof foo {
+ int32 integer_field = 2;
+ string string_field = 3;
+ }
}
message TestRequiredOptimizedForSize {
required int32 x = 1;
}
-
+
message TestOptionalOptimizedForSize {
optional TestRequiredOptimizedForSize o = 1;
}
diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc
index e1f8b83..020a323 100644
--- a/src/google/protobuf/unknown_field_set.cc
+++ b/src/google/protobuf/unknown_field_set.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -32,19 +32,20 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
-#include <google/protobuf/stubs/common.h>
#include <google/protobuf/unknown_field_set.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
+
+#include <google/protobuf/stubs/common.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>
#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
UnknownFieldSet::UnknownFieldSet()
- : fields_(NULL) {}
+ : fields_(NULL) {}
UnknownFieldSet::~UnknownFieldSet() {
Clear();
@@ -59,6 +60,14 @@ void UnknownFieldSet::ClearFallback() {
fields_->clear();
}
+void UnknownFieldSet::ClearAndFreeMemory() {
+ if (fields_ != NULL) {
+ Clear();
+ delete fields_;
+ fields_ = NULL;
+ }
+}
+
void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) {
for (int i = 0; i < other.field_count(); i++) {
AddField(other.field(i));
@@ -73,8 +82,9 @@ int UnknownFieldSet::SpaceUsedExcludingSelf() const {
const UnknownField& field = (*fields_)[i];
switch (field.type()) {
case UnknownField::TYPE_LENGTH_DELIMITED:
- total_size += sizeof(*field.length_delimited_) +
- internal::StringSpaceUsedExcludingSelf(*field.length_delimited_);
+ total_size += sizeof(*field.length_delimited_.string_value_) +
+ internal::StringSpaceUsedExcludingSelf(
+ *field.length_delimited_.string_value_);
break;
case UnknownField::TYPE_GROUP:
total_size += field.group_->SpaceUsed();
@@ -94,7 +104,7 @@ void UnknownFieldSet::AddVarint(int number, uint64 value) {
if (fields_ == NULL) fields_ = new vector<UnknownField>;
UnknownField field;
field.number_ = number;
- field.type_ = UnknownField::TYPE_VARINT;
+ field.SetType(UnknownField::TYPE_VARINT);
field.varint_ = value;
fields_->push_back(field);
}
@@ -103,7 +113,7 @@ void UnknownFieldSet::AddFixed32(int number, uint32 value) {
if (fields_ == NULL) fields_ = new vector<UnknownField>;
UnknownField field;
field.number_ = number;
- field.type_ = UnknownField::TYPE_FIXED32;
+ field.SetType(UnknownField::TYPE_FIXED32);
field.fixed32_ = value;
fields_->push_back(field);
}
@@ -112,7 +122,7 @@ void UnknownFieldSet::AddFixed64(int number, uint64 value) {
if (fields_ == NULL) fields_ = new vector<UnknownField>;
UnknownField field;
field.number_ = number;
- field.type_ = UnknownField::TYPE_FIXED64;
+ field.SetType(UnknownField::TYPE_FIXED64);
field.fixed64_ = value;
fields_->push_back(field);
}
@@ -121,17 +131,18 @@ string* UnknownFieldSet::AddLengthDelimited(int number) {
if (fields_ == NULL) fields_ = new vector<UnknownField>;
UnknownField field;
field.number_ = number;
- field.type_ = UnknownField::TYPE_LENGTH_DELIMITED;
- field.length_delimited_ = new string;
+ field.SetType(UnknownField::TYPE_LENGTH_DELIMITED);
+ field.length_delimited_.string_value_ = new string;
fields_->push_back(field);
- return field.length_delimited_;
+ return field.length_delimited_.string_value_;
}
+
UnknownFieldSet* UnknownFieldSet::AddGroup(int number) {
if (fields_ == NULL) fields_ = new vector<UnknownField>;
UnknownField field;
field.number_ = number;
- field.type_ = UnknownField::TYPE_GROUP;
+ field.SetType(UnknownField::TYPE_GROUP);
field.group_ = new UnknownFieldSet;
fields_->push_back(field);
return field.group_;
@@ -143,11 +154,43 @@ void UnknownFieldSet::AddField(const UnknownField& field) {
fields_->back().DeepCopy();
}
-bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) {
+void UnknownFieldSet::DeleteSubrange(int start, int num) {
+ GOOGLE_DCHECK(fields_ != NULL);
+ // Delete the specified fields.
+ for (int i = 0; i < num; ++i) {
+ (*fields_)[i + start].Delete();
+ }
+ // Slide down the remaining fields.
+ for (int i = start + num; i < fields_->size(); ++i) {
+ (*fields_)[i - num] = (*fields_)[i];
+ }
+ // Pop off the # of deleted fields.
+ for (int i = 0; i < num; ++i) {
+ fields_->pop_back();
+ }
+}
+
+void UnknownFieldSet::DeleteByNumber(int number) {
+ if (fields_ == NULL) return;
+ int left = 0; // The number of fields left after deletion.
+ for (int i = 0; i < fields_->size(); ++i) {
+ UnknownField* field = &(*fields_)[i];
+ if (field->number() == number) {
+ field->Delete();
+ } else {
+ if (i != left) {
+ (*fields_)[left] = (*fields_)[i];
+ }
+ ++left;
+ }
+ }
+ fields_->resize(left);
+}
+bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) {
UnknownFieldSet other;
if (internal::WireFormat::SkipMessage(input, &other) &&
- input->ConsumedEntireMessage()) {
+ input->ConsumedEntireMessage()) {
MergeFrom(other);
return true;
} else {
@@ -162,8 +205,8 @@ bool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) {
bool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
io::CodedInputStream coded_input(input);
- return ParseFromCodedStream(&coded_input) &&
- coded_input.ConsumedEntireMessage();
+ return (ParseFromCodedStream(&coded_input) &&
+ coded_input.ConsumedEntireMessage());
}
bool UnknownFieldSet::ParseFromArray(const void* data, int size) {
@@ -174,7 +217,7 @@ bool UnknownFieldSet::ParseFromArray(const void* data, int size) {
void UnknownField::Delete() {
switch (type()) {
case UnknownField::TYPE_LENGTH_DELIMITED:
- delete length_delimited_;
+ delete length_delimited_.string_value_;
break;
case UnknownField::TYPE_GROUP:
delete group_;
@@ -187,7 +230,8 @@ void UnknownField::Delete() {
void UnknownField::DeepCopy() {
switch (type()) {
case UnknownField::TYPE_LENGTH_DELIMITED:
- length_delimited_ = new string(*length_delimited_);
+ length_delimited_.string_value_ = new string(
+ *length_delimited_.string_value_);
break;
case UnknownField::TYPE_GROUP: {
UnknownFieldSet* group = new UnknownFieldSet;
@@ -200,5 +244,22 @@ void UnknownField::DeepCopy() {
}
}
+
+void UnknownField::SerializeLengthDelimitedNoTag(
+ io::CodedOutputStream* output) const {
+ GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
+ const string& data = *length_delimited_.string_value_;
+ output->WriteVarint32(data.size());
+ output->WriteRawMaybeAliased(data.data(), data.size());
+}
+
+uint8* UnknownField::SerializeLengthDelimitedNoTagToArray(uint8* target) const {
+ GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
+ const string& data = *length_delimited_.string_value_;
+ target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target);
+ target = io::CodedOutputStream::WriteStringToArray(data, target);
+ return target;
+}
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h
index 84c2e2b..31f17e2 100644
--- a/src/google/protobuf/unknown_field_set.h
+++ b/src/google/protobuf/unknown_field_set.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -38,12 +38,23 @@
#ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
#define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
+#include <assert.h>
#include <string>
#include <vector>
-#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
+ namespace io {
+ class CodedInputStream; // coded_stream.h
+ class CodedOutputStream; // coded_stream.h
+ class ZeroCopyInputStream; // zero_copy_stream.h
+ }
+ namespace internal {
+ class WireFormat; // wire_format.h
+ class MessageSetFieldSkipperUsingCord;
+ // extension_set_heavy.cc
+ }
class Message; // message.h
class UnknownField; // below
@@ -68,6 +79,9 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet {
// Remove all fields.
inline void Clear();
+ // Remove all fields and deallocate internal data objects
+ void ClearAndFreeMemory();
+
// Is this set empty?
inline bool empty() const;
@@ -107,6 +121,15 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet {
// Adds an unknown field from another set.
void AddField(const UnknownField& field);
+ // Delete fields with indices in the range [start .. start+num-1].
+ // Caution: implementation moves all fields with indices [start+num .. ].
+ void DeleteSubrange(int start, int num);
+
+ // Delete all fields with a specific field number. The order of left fields
+ // is preserved.
+ // Caution: implementation moves all fields after the first deleted field.
+ void DeleteByNumber(int number);
+
// Parsing helpers -------------------------------------------------
// These work exactly like the similarly-named methods of Message.
@@ -115,13 +138,14 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet {
bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input);
bool ParseFromArray(const void* data, int size);
inline bool ParseFromString(const string& data) {
- return ParseFromArray(data.data(), data.size());
+ return ParseFromArray(data.data(), static_cast<int>(data.size()));
}
private:
+
void ClearFallback();
- vector<UnknownField>* fields_;
+ std::vector<UnknownField>* fields_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet);
};
@@ -159,6 +183,15 @@ class LIBPROTOBUF_EXPORT UnknownField {
inline string* mutable_length_delimited();
inline UnknownFieldSet* mutable_group();
+ // Serialization API.
+ // These methods can take advantage of the underlying implementation and may
+ // archieve a better performance than using getters to retrieve the data and
+ // do the serialization yourself.
+ void SerializeLengthDelimitedNoTag(io::CodedOutputStream* output) const;
+ uint8* SerializeLengthDelimitedNoTagToArray(uint8* target) const;
+
+ inline int GetLengthDelimitedSize() const;
+
private:
friend class UnknownFieldSet;
@@ -168,13 +201,19 @@ class LIBPROTOBUF_EXPORT UnknownField {
// Make a deep copy of any pointers in this UnknownField.
void DeepCopy();
- unsigned int number_ : 29;
- unsigned int type_ : 3;
+ // Set the wire type of this UnknownField. Should only be used when this
+ // UnknownField is being created.
+ inline void SetType(Type type);
+
+ uint32 number_;
+ uint32 type_;
union {
uint64 varint_;
uint32 fixed32_;
uint64 fixed64_;
- string* length_delimited_;
+ mutable union {
+ string* string_value_;
+ } length_delimited_;
UnknownFieldSet* group_;
};
};
@@ -197,7 +236,7 @@ inline void UnknownFieldSet::Swap(UnknownFieldSet* x) {
}
inline int UnknownFieldSet::field_count() const {
- return (fields_ == NULL) ? 0 : fields_->size();
+ return (fields_ == NULL) ? 0 : static_cast<int>(fields_->size());
}
inline const UnknownField& UnknownFieldSet::field(int index) const {
return (*fields_)[index];
@@ -211,57 +250,68 @@ inline void UnknownFieldSet::AddLengthDelimited(
AddLengthDelimited(number)->assign(value);
}
+
inline int UnknownField::number() const { return number_; }
inline UnknownField::Type UnknownField::type() const {
return static_cast<Type>(type_);
}
-inline uint64 UnknownField::varint () const {
- GOOGLE_DCHECK_EQ(type_, TYPE_VARINT);
+inline uint64 UnknownField::varint() const {
+ assert(type() == TYPE_VARINT);
return varint_;
}
inline uint32 UnknownField::fixed32() const {
- GOOGLE_DCHECK_EQ(type_, TYPE_FIXED32);
+ assert(type() == TYPE_FIXED32);
return fixed32_;
}
inline uint64 UnknownField::fixed64() const {
- GOOGLE_DCHECK_EQ(type_, TYPE_FIXED64);
+ assert(type() == TYPE_FIXED64);
return fixed64_;
}
inline const string& UnknownField::length_delimited() const {
- GOOGLE_DCHECK_EQ(type_, TYPE_LENGTH_DELIMITED);
- return *length_delimited_;
+ assert(type() == TYPE_LENGTH_DELIMITED);
+ return *length_delimited_.string_value_;
}
inline const UnknownFieldSet& UnknownField::group() const {
- GOOGLE_DCHECK_EQ(type_, TYPE_GROUP);
+ assert(type() == TYPE_GROUP);
return *group_;
}
inline void UnknownField::set_varint(uint64 value) {
- GOOGLE_DCHECK_EQ(type_, TYPE_VARINT);
+ assert(type() == TYPE_VARINT);
varint_ = value;
}
inline void UnknownField::set_fixed32(uint32 value) {
- GOOGLE_DCHECK_EQ(type_, TYPE_FIXED32);
+ assert(type() == TYPE_FIXED32);
fixed32_ = value;
}
inline void UnknownField::set_fixed64(uint64 value) {
- GOOGLE_DCHECK_EQ(type_, TYPE_FIXED64);
+ assert(type() == TYPE_FIXED64);
fixed64_ = value;
}
inline void UnknownField::set_length_delimited(const string& value) {
- GOOGLE_DCHECK_EQ(type_, TYPE_LENGTH_DELIMITED);
- length_delimited_->assign(value);
+ assert(type() == TYPE_LENGTH_DELIMITED);
+ length_delimited_.string_value_->assign(value);
}
inline string* UnknownField::mutable_length_delimited() {
- GOOGLE_DCHECK_EQ(type_, TYPE_LENGTH_DELIMITED);
- return length_delimited_;
+ assert(type() == TYPE_LENGTH_DELIMITED);
+ return length_delimited_.string_value_;
}
inline UnknownFieldSet* UnknownField::mutable_group() {
- GOOGLE_DCHECK_EQ(type_, TYPE_GROUP);
+ assert(type() == TYPE_GROUP);
return group_;
}
+inline int UnknownField::GetLengthDelimitedSize() const {
+ GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
+ return static_cast<int>(length_delimited_.string_value_->size());
+}
+
+inline void UnknownField::SetType(Type type) {
+ type_ = type;
+}
+
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/unknown_field_set_unittest.cc b/src/google/protobuf/unknown_field_set_unittest.cc
index 1235c9e..aaaa2e8 100644
--- a/src/google/protobuf/unknown_field_set_unittest.cc
+++ b/src/google/protobuf/unknown_field_set_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -46,15 +46,13 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
using internal::WireFormat;
-namespace {
-
class UnknownFieldSetTest : public testing::Test {
protected:
virtual void SetUp() {
@@ -107,6 +105,8 @@ class UnknownFieldSetTest : public testing::Test {
UnknownFieldSet* unknown_fields_;
};
+namespace {
+
TEST_F(UnknownFieldSetTest, AllFieldsPresent) {
// All fields of TestAllTypes should be present, in numeric order (because
// that's the order we parsed them in). Fields that are not valid field
@@ -118,7 +118,12 @@ TEST_F(UnknownFieldSetTest, AllFieldsPresent) {
const FieldDescriptor* field = descriptor_->FindFieldByNumber(i);
if (field != NULL) {
ASSERT_LT(pos, unknown_fields_->field_count());
- EXPECT_EQ(i, unknown_fields_->field(pos++).number());
+ // Do not check oneof field if it is not set.
+ if (field->containing_oneof() == NULL) {
+ EXPECT_EQ(i, unknown_fields_->field(pos++).number());
+ } else if (i == unknown_fields_->field(pos).number()) {
+ pos++;
+ }
if (field->is_repeated()) {
// Should have a second instance.
ASSERT_LT(pos, unknown_fields_->field_count());
@@ -297,12 +302,21 @@ TEST_F(UnknownFieldSetTest, MergeFrom) {
destination.DebugString());
}
+
TEST_F(UnknownFieldSetTest, Clear) {
// Clear the set.
empty_message_.Clear();
EXPECT_EQ(0, unknown_fields_->field_count());
}
+TEST_F(UnknownFieldSetTest, ClearAndFreeMemory) {
+ EXPECT_GT(unknown_fields_->field_count(), 0);
+ unknown_fields_->ClearAndFreeMemory();
+ EXPECT_EQ(0, unknown_fields_->field_count());
+ unknown_fields_->AddVarint(123456, 654321);
+ EXPECT_EQ(1, unknown_fields_->field_count());
+}
+
TEST_F(UnknownFieldSetTest, ParseKnownAndUnknown) {
// Test mixing known and unknown fields when parsing.
@@ -498,6 +512,7 @@ TEST_F(UnknownFieldSetTest, SpaceUsed) {
EXPECT_LT(base_size, empty_message.SpaceUsed());
}
+
TEST_F(UnknownFieldSetTest, Empty) {
UnknownFieldSet unknown_fields;
EXPECT_TRUE(unknown_fields.empty());
@@ -507,6 +522,78 @@ TEST_F(UnknownFieldSetTest, Empty) {
EXPECT_TRUE(unknown_fields.empty());
}
+TEST_F(UnknownFieldSetTest, DeleteSubrange) {
+ // Exhaustively test the deletion of every possible subrange in arrays of all
+ // sizes from 0 through 9.
+ for (int size = 0; size < 10; ++size) {
+ for (int num = 0; num <= size; ++num) {
+ for (int start = 0; start < size - num; ++start) {
+ // Create a set with "size" fields.
+ UnknownFieldSet unknown;
+ for (int i = 0; i < size; ++i) {
+ unknown.AddFixed32(i, i);
+ }
+ // Delete the specified subrange.
+ unknown.DeleteSubrange(start, num);
+ // Make sure the resulting field values are still correct.
+ EXPECT_EQ(size - num, unknown.field_count());
+ for (int i = 0; i < unknown.field_count(); ++i) {
+ if (i < start) {
+ EXPECT_EQ(i, unknown.field(i).fixed32());
+ } else {
+ EXPECT_EQ(i + num, unknown.field(i).fixed32());
+ }
+ }
+ }
+ }
+ }
+}
+
+void CheckDeleteByNumber(const vector<int>& field_numbers, int deleted_number,
+ const vector<int>& expected_field_nubmers) {
+ UnknownFieldSet unknown_fields;
+ for (int i = 0; i < field_numbers.size(); ++i) {
+ unknown_fields.AddFixed32(field_numbers[i], i);
+ }
+ unknown_fields.DeleteByNumber(deleted_number);
+ ASSERT_EQ(expected_field_nubmers.size(), unknown_fields.field_count());
+ for (int i = 0; i < expected_field_nubmers.size(); ++i) {
+ EXPECT_EQ(expected_field_nubmers[i],
+ unknown_fields.field(i).number());
+ }
+}
+
+#define MAKE_VECTOR(x) vector<int>(x, x + GOOGLE_ARRAYSIZE(x))
+TEST_F(UnknownFieldSetTest, DeleteByNumber) {
+ CheckDeleteByNumber(vector<int>(), 1, vector<int>());
+ static const int kTestFieldNumbers1[] = {1, 2, 3};
+ static const int kFieldNumberToDelete1 = 1;
+ static const int kExpectedFieldNumbers1[] = {2, 3};
+ CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers1), kFieldNumberToDelete1,
+ MAKE_VECTOR(kExpectedFieldNumbers1));
+ static const int kTestFieldNumbers2[] = {1, 2, 3};
+ static const int kFieldNumberToDelete2 = 2;
+ static const int kExpectedFieldNumbers2[] = {1, 3};
+ CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers2), kFieldNumberToDelete2,
+ MAKE_VECTOR(kExpectedFieldNumbers2));
+ static const int kTestFieldNumbers3[] = {1, 2, 3};
+ static const int kFieldNumberToDelete3 = 3;
+ static const int kExpectedFieldNumbers3[] = {1, 2};
+ CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers3), kFieldNumberToDelete3,
+ MAKE_VECTOR(kExpectedFieldNumbers3));
+ static const int kTestFieldNumbers4[] = {1, 2, 1, 4, 1};
+ static const int kFieldNumberToDelete4 = 1;
+ static const int kExpectedFieldNumbers4[] = {2, 4};
+ CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers4), kFieldNumberToDelete4,
+ MAKE_VECTOR(kExpectedFieldNumbers4));
+ static const int kTestFieldNumbers5[] = {1, 2, 3, 4, 5};
+ static const int kFieldNumberToDelete5 = 6;
+ static const int kExpectedFieldNumbers5[] = {1, 2, 3, 4, 5};
+ CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers5), kFieldNumberToDelete5,
+ MAKE_VECTOR(kExpectedFieldNumbers5));
+}
+#undef MAKE_VECTOR
} // namespace
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc
index 831a579..6bdfcd6 100644
--- a/src/google/protobuf/wire_format.cc
+++ b/src/google/protobuf/wire_format.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -39,6 +39,7 @@
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/descriptor.pb.h>
@@ -48,12 +49,11 @@
#include <google/protobuf/unknown_field_set.h>
+
namespace google {
namespace protobuf {
namespace internal {
-using internal::WireFormatLite;
-
namespace {
// This function turns out to be convenient when using some macros later.
@@ -183,7 +183,8 @@ void WireFormat::SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
output->WriteVarint32(field.length_delimited().size());
- output->WriteString(field.length_delimited());
+ output->WriteRawMaybeAliased(field.length_delimited().data(),
+ field.length_delimited().size());
break;
case UnknownField::TYPE_GROUP:
output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
@@ -239,8 +240,6 @@ void WireFormat::SerializeUnknownMessageSetItems(
// The only unknown fields that are allowed to exist in a MessageSet are
// messages, which are length-delimited.
if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
- const string& data = field.length_delimited();
-
// Start group.
output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
@@ -250,8 +249,7 @@ void WireFormat::SerializeUnknownMessageSetItems(
// Write message.
output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
- output->WriteVarint32(data.size());
- output->WriteString(data);
+ field.SerializeLengthDelimitedNoTag(output);
// End group.
output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
@@ -268,8 +266,6 @@ uint8* WireFormat::SerializeUnknownMessageSetItemsToArray(
// The only unknown fields that are allowed to exist in a MessageSet are
// messages, which are length-delimited.
if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
- const string& data = field.length_delimited();
-
// Start group.
target = io::CodedOutputStream::WriteTagToArray(
WireFormatLite::kMessageSetItemStartTag, target);
@@ -283,8 +279,7 @@ uint8* WireFormat::SerializeUnknownMessageSetItemsToArray(
// Write message.
target = io::CodedOutputStream::WriteTagToArray(
WireFormatLite::kMessageSetMessageTag, target);
- target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target);
- target = io::CodedOutputStream::WriteStringToArray(data, target);
+ target = field.SerializeLengthDelimitedNoTagToArray(target);
// End group.
target = io::CodedOutputStream::WriteTagToArray(
@@ -354,9 +349,10 @@ int WireFormat::ComputeUnknownMessageSetItemsSize(
if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
size += WireFormatLite::kMessageSetItemTagsSize;
size += io::CodedOutputStream::VarintSize32(field.number());
- size += io::CodedOutputStream::VarintSize32(
- field.length_delimited().size());
- size += field.length_delimited().size();
+
+ int field_size = field.GetLengthDelimitedSize();
+ size += io::CodedOutputStream::VarintSize32(field_size);
+ size += field_size;
}
}
@@ -417,6 +413,37 @@ bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input,
}
}
+bool WireFormat::SkipMessageSetField(io::CodedInputStream* input,
+ uint32 field_number,
+ UnknownFieldSet* unknown_fields) {
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ return input->ReadString(
+ unknown_fields->AddLengthDelimited(field_number), length);
+}
+
+bool WireFormat::ParseAndMergeMessageSetField(uint32 field_number,
+ const FieldDescriptor* field,
+ Message* message,
+ io::CodedInputStream* input) {
+ const Reflection* message_reflection = message->GetReflection();
+ if (field == NULL) {
+ // We store unknown MessageSet extensions as groups.
+ return SkipMessageSetField(
+ input, field_number, message_reflection->MutableUnknownFields(message));
+ } else if (field->is_repeated() ||
+ field->type() != FieldDescriptor::TYPE_MESSAGE) {
+ // This shouldn't happen as we only allow optional message extensions to
+ // MessageSet.
+ GOOGLE_LOG(ERROR) << "Extensions of MessageSets must be optional messages.";
+ return false;
+ } else {
+ Message* sub_message = message_reflection->MutableMessage(
+ message, field, input->GetExtensionFactory());
+ return WireFormatLite::ReadMessage(input, sub_message);
+ }
+}
+
bool WireFormat::ParseAndMergeField(
uint32 tag,
const FieldDescriptor* field, // May be NULL for unknown
@@ -568,7 +595,8 @@ bool WireFormat::ParseAndMergeField(
case FieldDescriptor::TYPE_STRING: {
string value;
if (!WireFormatLite::ReadString(input, &value)) return false;
- VerifyUTF8String(value.data(), value.length(), PARSE);
+ VerifyUTF8StringNamedField(value.data(), value.length(), PARSE,
+ field->name().c_str());
if (field->is_repeated()) {
message_reflection->AddString(message, field, value);
} else {
@@ -632,20 +660,14 @@ bool WireFormat::ParseAndMergeMessageSetItem(
// required int32 type_id = 2;
// required data message = 3;
- // Once we see a type_id, we'll construct a fake tag for this extension
- // which is the tag it would have had under the proto2 extensions wire
- // format.
- uint32 fake_tag = 0;
+ uint32 last_type_id = 0;
// Once we see a type_id, we'll look up the FieldDescriptor for the
// extension.
const FieldDescriptor* field = NULL;
// If we see message data before the type_id, we'll append it to this so
- // we can parse it later. This will probably never happen in practice,
- // as no MessageSet encoder I know of writes the message before the type ID.
- // But, it's technically valid so we should allow it.
- // TODO(kenton): Use a Cord instead? Do I care?
+ // we can parse it later.
string message_data;
while (true) {
@@ -656,8 +678,7 @@ bool WireFormat::ParseAndMergeMessageSetItem(
case WireFormatLite::kMessageSetTypeIdTag: {
uint32 type_id;
if (!input->ReadVarint32(&type_id)) return false;
- fake_tag = WireFormatLite::MakeTag(
- type_id, WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+ last_type_id = type_id;
field = message_reflection->FindKnownExtensionByNumber(type_id);
if (!message_data.empty()) {
@@ -666,8 +687,8 @@ bool WireFormat::ParseAndMergeMessageSetItem(
io::ArrayInputStream raw_input(message_data.data(),
message_data.size());
io::CodedInputStream sub_input(&raw_input);
- if (!ParseAndMergeField(fake_tag, field, message,
- &sub_input)) {
+ if (!ParseAndMergeMessageSetField(last_type_id, field, message,
+ &sub_input)) {
return false;
}
message_data.clear();
@@ -677,16 +698,20 @@ bool WireFormat::ParseAndMergeMessageSetItem(
}
case WireFormatLite::kMessageSetMessageTag: {
- if (fake_tag == 0) {
+ if (last_type_id == 0) {
// We haven't seen a type_id yet. Append this data to message_data.
string temp;
uint32 length;
if (!input->ReadVarint32(&length)) return false;
if (!input->ReadString(&temp, length)) return false;
- message_data.append(temp);
+ io::StringOutputStream output_stream(&message_data);
+ io::CodedOutputStream coded_output(&output_stream);
+ coded_output.WriteVarint32(length);
+ coded_output.WriteString(temp);
} else {
// Already saw type_id, so we can parse this directly.
- if (!ParseAndMergeField(fake_tag, field, message, input)) {
+ if (!ParseAndMergeMessageSetField(last_type_id, field, message,
+ input)) {
return false;
}
}
@@ -834,7 +859,8 @@ void WireFormat::SerializeFieldWithCachedSizes(
message_reflection->GetRepeatedStringReference(
message, field, j, &scratch) :
message_reflection->GetStringReference(message, field, &scratch);
- VerifyUTF8String(value.data(), value.length(), SERIALIZE);
+ VerifyUTF8StringNamedField(value.data(), value.length(), SERIALIZE,
+ field->name().c_str());
WireFormatLite::WriteString(field->number(), value, output);
break;
}
@@ -1044,7 +1070,8 @@ int WireFormat::MessageSetItemByteSize(
void WireFormat::VerifyUTF8StringFallback(const char* data,
int size,
- Operation op) {
+ Operation op,
+ const char* field_name) {
if (!IsStructurallyValidUTF8(data, size)) {
const char* operation_str = NULL;
switch (op) {
@@ -1056,10 +1083,15 @@ void WireFormat::VerifyUTF8StringFallback(const char* data,
break;
// no default case: have the compiler warn if a case is not covered.
}
- GOOGLE_LOG(ERROR) << "Encountered string containing invalid UTF-8 data while "
- << operation_str
- << " protocol buffer. Strings must contain only UTF-8; "
- "use the 'bytes' type for raw bytes.";
+ string quoted_field_name = "";
+ if (field_name != NULL) {
+ quoted_field_name = StringPrintf(" '%s'", field_name);
+ }
+ // no space below to avoid double space when the field name is missing.
+ GOOGLE_LOG(ERROR) << "String field" << quoted_field_name << " contains invalid "
+ << "UTF-8 data when " << operation_str << " a protocol "
+ << "buffer. Use the 'bytes' type if you intend to send raw "
+ << "bytes. ";
}
}
diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h
index c753925..9f26eb2 100644
--- a/src/google/protobuf/wire_format.h
+++ b/src/google/protobuf/wire_format.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -40,6 +40,7 @@
#define GOOGLE_PROTOBUF_WIRE_FORMAT_H__
#include <string>
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/message.h>
@@ -78,7 +79,7 @@ class LIBPROTOBUF_EXPORT WireFormat {
static inline WireFormatLite::WireType WireTypeForField(
const FieldDescriptor* field);
- // Given a FieldSescriptor::Type return its WireType
+ // Given a FieldDescriptor::Type return its WireType
static inline WireFormatLite::WireType WireTypeForFieldType(
FieldDescriptor::Type type);
@@ -179,7 +180,7 @@ class LIBPROTOBUF_EXPORT WireFormat {
// of packed repeated fields.
static uint32 MakeTag(const FieldDescriptor* field);
- // Parse a single field. The input should start out positioned immidately
+ // Parse a single field. The input should start out positioned immediately
// after the tag.
static bool ParseAndMergeField(
uint32 tag,
@@ -227,14 +228,34 @@ class LIBPROTOBUF_EXPORT WireFormat {
};
// Verifies that a string field is valid UTF8, logging an error if not.
+ // This function will not be called by newly generated protobuf code
+ // but remains present to support existing code.
static void VerifyUTF8String(const char* data, int size, Operation op);
+ // The NamedField variant takes a field name in order to produce an
+ // informative error message if verification fails.
+ static void VerifyUTF8StringNamedField(const char* data,
+ int size,
+ Operation op,
+ const char* field_name);
private:
// Verifies that a string field is valid UTF8, logging an error if not.
static void VerifyUTF8StringFallback(
const char* data,
int size,
- Operation op);
+ Operation op,
+ const char* field_name);
+
+ // Skip a MessageSet field.
+ static bool SkipMessageSetField(io::CodedInputStream* input,
+ uint32 field_number,
+ UnknownFieldSet* unknown_fields);
+
+ // Parse a MessageSet field.
+ static bool ParseAndMergeMessageSetField(uint32 field_number,
+ const FieldDescriptor* field,
+ Message* message,
+ io::CodedInputStream* input);
@@ -253,7 +274,7 @@ class LIBPROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper {
virtual bool SkipMessage(io::CodedInputStream* input);
virtual void SkipUnknownEnum(int field_number, int value);
- private:
+ protected:
UnknownFieldSet* unknown_fields_;
};
@@ -292,7 +313,18 @@ inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) {
inline void WireFormat::VerifyUTF8String(const char* data, int size,
WireFormat::Operation op) {
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
- WireFormat::VerifyUTF8StringFallback(data, size, op);
+ WireFormat::VerifyUTF8StringFallback(data, size, op, NULL);
+#else
+ // Avoid the compiler warning about unsued variables.
+ (void)data; (void)size; (void)op;
+#endif
+}
+
+inline void WireFormat::VerifyUTF8StringNamedField(
+ const char* data, int size, WireFormat::Operation op,
+ const char* field_name) {
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ WireFormat::VerifyUTF8StringFallback(data, size, op, field_name);
#endif
}
diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc
index d347d11..8de8278 100644
--- a/src/google/protobuf/wire_format_lite.cc
+++ b/src/google/protobuf/wire_format_lite.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -40,7 +40,7 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream_inl.h>
#include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google {
namespace protobuf {
@@ -56,10 +56,10 @@ const int WireFormatLite::kMessageSetMessageTag;
#endif
const int WireFormatLite::kMessageSetItemTagsSize =
- io::CodedOutputStream::VarintSize32(kMessageSetItemStartTag) +
- io::CodedOutputStream::VarintSize32(kMessageSetItemEndTag) +
- io::CodedOutputStream::VarintSize32(kMessageSetTypeIdTag) +
- io::CodedOutputStream::VarintSize32(kMessageSetMessageTag);
+ io::CodedOutputStream::StaticVarintSize32<kMessageSetItemStartTag>::value +
+ io::CodedOutputStream::StaticVarintSize32<kMessageSetItemEndTag>::value +
+ io::CodedOutputStream::StaticVarintSize32<kMessageSetTypeIdTag>::value +
+ io::CodedOutputStream::StaticVarintSize32<kMessageSetMessageTag>::value;
const WireFormatLite::CppType
WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = {
@@ -153,8 +153,65 @@ bool WireFormatLite::SkipField(
}
}
+bool WireFormatLite::SkipField(
+ io::CodedInputStream* input, uint32 tag, io::CodedOutputStream* output) {
+ switch (WireFormatLite::GetTagWireType(tag)) {
+ case WireFormatLite::WIRETYPE_VARINT: {
+ uint64 value;
+ if (!input->ReadVarint64(&value)) return false;
+ output->WriteVarint32(tag);
+ output->WriteVarint64(value);
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_FIXED64: {
+ uint64 value;
+ if (!input->ReadLittleEndian64(&value)) return false;
+ output->WriteVarint32(tag);
+ output->WriteLittleEndian64(value);
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ output->WriteVarint32(tag);
+ output->WriteVarint32(length);
+ // TODO(mkilavuz): Provide API to prevent extra string copying.
+ string temp;
+ if (!input->ReadString(&temp, length)) return false;
+ output->WriteString(temp);
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_START_GROUP: {
+ output->WriteVarint32(tag);
+ if (!input->IncrementRecursionDepth()) return false;
+ if (!SkipMessage(input, output)) return false;
+ input->DecrementRecursionDepth();
+ // Check that the ending tag matched the starting tag.
+ if (!input->LastTagWas(WireFormatLite::MakeTag(
+ WireFormatLite::GetTagFieldNumber(tag),
+ WireFormatLite::WIRETYPE_END_GROUP))) {
+ return false;
+ }
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_END_GROUP: {
+ return false;
+ }
+ case WireFormatLite::WIRETYPE_FIXED32: {
+ uint32 value;
+ if (!input->ReadLittleEndian32(&value)) return false;
+ output->WriteVarint32(tag);
+ output->WriteLittleEndian32(value);
+ return true;
+ }
+ default: {
+ return false;
+ }
+ }
+}
+
bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
- while(true) {
+ while (true) {
uint32 tag = input->ReadTag();
if (tag == 0) {
// End of input. This is a valid place to end, so return true.
@@ -172,6 +229,27 @@ bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
}
}
+bool WireFormatLite::SkipMessage(io::CodedInputStream* input,
+ io::CodedOutputStream* output) {
+ while (true) {
+ uint32 tag = input->ReadTag();
+ if (tag == 0) {
+ // End of input. This is a valid place to end, so return true.
+ return true;
+ }
+
+ WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
+
+ if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
+ output->WriteVarint32(tag);
+ // Must be the end of the message.
+ return true;
+ }
+
+ if (!SkipField(input, tag, output)) return false;
+ }
+}
+
bool FieldSkipper::SkipField(
io::CodedInputStream* input, uint32 tag) {
return WireFormatLite::SkipField(input, tag);
@@ -182,10 +260,25 @@ bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
}
void FieldSkipper::SkipUnknownEnum(
- int field_number, int value) {
+ int /* field_number */, int /* value */) {
// Nothing.
}
+bool CodedOutputStreamFieldSkipper::SkipField(
+ io::CodedInputStream* input, uint32 tag) {
+ return WireFormatLite::SkipField(input, tag, unknown_fields_);
+}
+
+bool CodedOutputStreamFieldSkipper::SkipMessage(io::CodedInputStream* input) {
+ return WireFormatLite::SkipMessage(input, unknown_fields_);
+}
+
+void CodedOutputStreamFieldSkipper::SkipUnknownEnum(
+ int field_number, int value) {
+ unknown_fields_->WriteVarint32(field_number);
+ unknown_fields_->WriteVarint64(value);
+}
+
bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
bool (*is_valid)(int),
RepeatedField<int>* values) {
@@ -281,15 +374,34 @@ 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);
output->WriteVarint32(value.size());
output->WriteString(value);
}
+void WireFormatLite::WriteStringMaybeAliased(
+ 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);
+ 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);
output->WriteVarint32(value.size());
output->WriteString(value);
}
+void WireFormatLite::WriteBytesMaybeAliased(
+ int field_number, const string& value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
+ GOOGLE_CHECK(value.size() <= kint32max);
+ output->WriteVarint32(value.size());
+ output->WriteRawMaybeAliased(value.data(), value.size());
+}
void WireFormatLite::WriteGroup(int field_number,
diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h
index e3d5b2d..21aa488 100644
--- a/src/google/protobuf/wire_format_lite.h
+++ b/src/google/protobuf/wire_format_lite.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -41,16 +41,14 @@
#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
#include <string>
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message_lite.h>
+#include <google/protobuf/io/coded_stream.h> // for CodedOutputStream::Varint32Size
namespace google {
namespace protobuf {
template <typename T> class RepeatedField; // repeated_field.h
- namespace io {
- class CodedInputStream; // coded_stream.h
- class CodedOutputStream; // coded_stream.h
- }
}
namespace protobuf {
@@ -165,11 +163,22 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
// records to an UnknownFieldSet.
static bool SkipField(io::CodedInputStream* input, uint32 tag);
+ // Skips a field value with the given tag. The input should start
+ // positioned immediately after the tag. Skipped values are recorded to a
+ // CodedOutputStream.
+ static bool SkipField(io::CodedInputStream* input, uint32 tag,
+ io::CodedOutputStream* output);
+
// Reads and ignores a message from the input. Skipped values are simply
// discarded, not recorded anywhere. See WireFormat::SkipMessage() for a
// version that records to an UnknownFieldSet.
static bool SkipMessage(io::CodedInputStream* input);
+ // Reads and ignores a message from the input. Skipped values are recorded
+ // to a CodedOutputStream.
+ static bool SkipMessage(io::CodedInputStream* input,
+ io::CodedOutputStream* output);
+
// This macro does the same thing as WireFormatLite::MakeTag(), but the
// result is usable as a compile-time constant, which makes it usable
// as a switch case or a template input. WireFormatLite::MakeTag() is more
@@ -230,9 +239,9 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
// that file to use these.
// Avoid ugly line wrapping
-#define input io::CodedInputStream* input
-#define output io::CodedOutputStream* output
-#define field_number int field_number
+#define input io::CodedInputStream* input_arg
+#define output io::CodedOutputStream* output_arg
+#define field_number int field_number_arg
#define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE
// Read fields, not including tags. The assumption is that you already
@@ -342,6 +351,10 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
static void WriteString(field_number, const string& value, output);
static void WriteBytes (field_number, const string& value, output);
+ static void WriteStringMaybeAliased(
+ field_number, const string& value, output);
+ static void WriteBytesMaybeAliased(
+ field_number, const string& value, output);
static void WriteGroup(
field_number, const MessageLite& value, output);
@@ -477,6 +490,10 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
template<typename MessageType>
static inline int MessageSizeNoVirtual(const MessageType& value);
+ // Given the length of data, calculate the byte size of the data on the
+ // wire if we encode the data as a length delimited field.
+ static inline int LengthDelimitedSize(int length);
+
private:
// A helper method for the repeated primitive reader. This method has
// optimizations for primitive types that have fixed size on the wire, and
@@ -488,6 +505,12 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
google::protobuf::io::CodedInputStream* input,
RepeatedField<CType>* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ // Like ReadRepeatedFixedSizePrimitive but for packed primitive fields.
+ template <typename CType, enum FieldType DeclaredType>
+ static inline bool ReadPackedFixedSizePrimitive(
+ google::protobuf::io::CodedInputStream* input,
+ RepeatedField<CType>* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
static const CppType kFieldTypeToCppTypeMap[];
static const WireFormatLite::WireType kWireTypeForFieldType[];
@@ -516,6 +539,24 @@ class LIBPROTOBUF_EXPORT FieldSkipper {
virtual void SkipUnknownEnum(int field_number, int value);
};
+// Subclass of FieldSkipper which saves skipped fields to a CodedOutputStream.
+
+class LIBPROTOBUF_EXPORT CodedOutputStreamFieldSkipper : public FieldSkipper {
+ public:
+ explicit CodedOutputStreamFieldSkipper(io::CodedOutputStream* unknown_fields)
+ : unknown_fields_(unknown_fields) {}
+ virtual ~CodedOutputStreamFieldSkipper() {}
+
+ // implements FieldSkipper -----------------------------------------
+ virtual bool SkipField(io::CodedInputStream* input, uint32 tag);
+ virtual bool SkipMessage(io::CodedInputStream* input);
+ virtual void SkipUnknownEnum(int field_number, int value);
+
+ protected:
+ io::CodedOutputStream* unknown_fields_;
+};
+
+
// inline methods ====================================================
inline WireFormatLite::CppType
diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h
index 3f0d7f8..4e8ac9b 100644
--- a/src/google/protobuf/wire_format_lite_inl.h
+++ b/src/google/protobuf/wire_format_lite_inl.h
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -36,12 +36,16 @@
#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
+#ifdef _MSC_VER
+// This is required for min/max on VS2013 only.
+#include <algorithm>
+#endif
+
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite.h>
-#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/io/coded_stream.h>
@@ -151,8 +155,8 @@ template <>
inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
io::CodedInputStream* input,
bool* value) {
- uint32 temp;
- if (!input->ReadVarint32(&temp)) return false;
+ uint64 temp;
+ if (!input->ReadVarint64(&temp)) return false;
*value = temp != 0;
return true;
}
@@ -222,10 +226,11 @@ inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
}
template <typename CType, enum WireFormatLite::FieldType DeclaredType>
-inline bool WireFormatLite::ReadRepeatedPrimitive(int, // tag_size, unused
- uint32 tag,
- io::CodedInputStream* input,
- RepeatedField<CType>* values) {
+inline bool WireFormatLite::ReadRepeatedPrimitive(
+ int, // tag_size, unused.
+ uint32 tag,
+ io::CodedInputStream* input,
+ RepeatedField<CType>* values) {
CType value;
if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
values->Add(value);
@@ -285,7 +290,7 @@ inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
return true;
}
-// Specializations of ReadRepeatedPrimitive for the fixed size types, which use
+// Specializations of ReadRepeatedPrimitive for the fixed size types, which use
// the optimized code path.
#define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \
template <> \
@@ -300,12 +305,12 @@ inline bool WireFormatLite::ReadRepeatedPrimitive< \
tag_size, tag, input, values); \
}
-READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32);
-READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64);
-READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32);
-READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64);
-READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT);
-READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE);
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32)
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64)
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32)
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64)
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
#undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
@@ -335,6 +340,86 @@ 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);
+ 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
+ // to a malicious user-supplied "length" above. So we have a fast
+ // path that pre-allocates when the "length" is less than a bound.
+ // We determine the bound by calling BytesUntilTotalBytesLimit() and
+ // BytesUntilLimit(). These return -1 to mean "no limit set".
+ // There are four cases:
+ // TotalBytesLimit Limit
+ // -1 -1 Use slow path.
+ // -1 >= 0 Use fast path if length <= Limit.
+ // >= 0 -1 Use slow path.
+ // >= 0 >= 0 Use fast path if length <= min(both limits).
+ int64 bytes_limit = input->BytesUntilTotalBytesLimit();
+ if (bytes_limit == -1) {
+ bytes_limit = input->BytesUntilLimit();
+ } else {
+ bytes_limit =
+ min(bytes_limit, static_cast<int64>(input->BytesUntilLimit()));
+ }
+ if (bytes_limit >= new_bytes) {
+ // Fast-path that pre-allocates *values to the final size.
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+ values->Resize(old_entries + new_entries, 0);
+ // values->mutable_data() may change after Resize(), so do this after:
+ void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries);
+ if (!input->ReadRaw(dest, new_bytes)) {
+ values->Truncate(old_entries);
+ return false;
+ }
+#else
+ values->Reserve(old_entries + new_entries);
+ CType value;
+ for (int i = 0; i < new_entries; ++i) {
+ if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
+ values->AddAlreadyReserved(value);
+ }
+#endif
+ } else {
+ // This is the slow-path case where "length" may be too large to
+ // 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) {
+ if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
+ values->Add(value);
+ }
+ }
+ return true;
+}
+
+// Specializations of ReadPackedPrimitive for the fixed size types, which use
+// an optimized code path.
+#define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \
+template <> \
+inline bool WireFormatLite::ReadPackedPrimitive< \
+ CPPTYPE, WireFormatLite::DECLARED_TYPE>( \
+ io::CodedInputStream* input, \
+ RepeatedField<CPPTYPE>* values) { \
+ return ReadPackedFixedSizePrimitive< \
+ 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);
+
+#undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE
+
+template <typename CType, enum WireFormatLite::FieldType DeclaredType>
bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
RepeatedField<CType>* values) {
return ReadPackedPrimitive<CType, DeclaredType>(input, values);
@@ -368,12 +453,24 @@ inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
return true;
}
-template<typename MessageType>
-inline bool WireFormatLite::ReadGroupNoVirtual(int field_number,
- io::CodedInputStream* input,
- MessageType* value) {
+// We name the template parameter something long and extremely unlikely to occur
+// elsewhere because a *qualified* member access expression designed to avoid
+// virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the
+// name of the qualifying class to be looked up both in the context of the full
+// expression (finding the template parameter) and in the context of the object
+// whose member we are accessing. This could potentially find a nested type
+// within that object. The standard goes on to require these names to refer to
+// the same entity, which this collision would violate. The lack of a safe way
+// to avoid this collision appears to be a defect in the standard, but until it
+// is corrected, we choose the name to avoid accidental collisions.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline bool WireFormatLite::ReadGroupNoVirtual(
+ int field_number, io::CodedInputStream* input,
+ MessageType_WorkAroundCppLookupDefect* value) {
if (!input->IncrementRecursionDepth()) return false;
- if (!value->MessageType::MergePartialFromCodedStream(input)) return false;
+ if (!value->
+ MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
+ return false;
input->DecrementRecursionDepth();
// Make sure the last thing read was an end tag for this group.
if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
@@ -381,14 +478,16 @@ inline bool WireFormatLite::ReadGroupNoVirtual(int field_number,
}
return true;
}
-template<typename MessageType>
-inline bool WireFormatLite::ReadMessageNoVirtual(io::CodedInputStream* input,
- MessageType* value) {
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline bool WireFormatLite::ReadMessageNoVirtual(
+ io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
uint32 length;
if (!input->ReadVarint32(&length)) return false;
if (!input->IncrementRecursionDepth()) return false;
io::CodedInputStream::Limit limit = input->PushLimit(length);
- if (!value->MessageType::MergePartialFromCodedStream(input)) return false;
+ if (!value->
+ MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
+ return false;
// Make sure that parsing stopped when the limit was hit, not at an endgroup
// tag.
if (!input->ConsumedEntireMessage()) return false;
@@ -461,21 +560,24 @@ inline void WireFormatLite::WriteEnumNoTag(int value,
output->WriteVarint32SignExtended(value);
}
-template<typename MessageType>
-inline void WireFormatLite::WriteGroupNoVirtual(int field_number,
- const MessageType& value,
- io::CodedOutputStream* output) {
+// See comment on ReadGroupNoVirtual to understand the need for this template
+// parameter name.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline void WireFormatLite::WriteGroupNoVirtual(
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_START_GROUP, output);
- value.MessageType::SerializeWithCachedSizes(output);
+ value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
WriteTag(field_number, WIRETYPE_END_GROUP, output);
}
-template<typename MessageType>
-inline void WireFormatLite::WriteMessageNoVirtual(int field_number,
- const MessageType& value,
- io::CodedOutputStream* output) {
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline void WireFormatLite::WriteMessageNoVirtual(
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
- output->WriteVarint32(value.MessageType::GetCachedSize());
- value.MessageType::SerializeWithCachedSizes(output);
+ output->WriteVarint32(
+ value.MessageType_WorkAroundCppLookupDefect::GetCachedSize());
+ value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
}
// ===================================================================
@@ -644,15 +746,13 @@ inline uint8* WireFormatLite::WriteStringToArray(int field_number,
// WriteString() to avoid code duplication. If the implementations become
// different, you will need to update that usage.
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
- target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
- return io::CodedOutputStream::WriteStringToArray(value, target);
+ return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
}
inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
const string& value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
- target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
- return io::CodedOutputStream::WriteStringToArray(value, target);
+ return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
}
@@ -672,20 +772,26 @@ inline uint8* WireFormatLite::WriteMessageToArray(int field_number,
return value.SerializeWithCachedSizesToArray(target);
}
-template<typename MessageType>
+// See comment on ReadGroupNoVirtual to understand the need for this template
+// parameter name.
+template<typename MessageType_WorkAroundCppLookupDefect>
inline uint8* WireFormatLite::WriteGroupNoVirtualToArray(
- int field_number, const MessageType& value, uint8* target) {
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
- target = value.MessageType::SerializeWithCachedSizesToArray(target);
+ target = value.MessageType_WorkAroundCppLookupDefect
+ ::SerializeWithCachedSizesToArray(target);
return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
}
-template<typename MessageType>
+template<typename MessageType_WorkAroundCppLookupDefect>
inline uint8* WireFormatLite::WriteMessageNoVirtualToArray(
- int field_number, const MessageType& value, uint8* target) {
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
target = io::CodedOutputStream::WriteVarint32ToArray(
- value.MessageType::GetCachedSize(), target);
- return value.MessageType::SerializeWithCachedSizesToArray(target);
+ value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
+ return value.MessageType_WorkAroundCppLookupDefect
+ ::SerializeWithCachedSizesToArray(target);
}
// ===================================================================
@@ -726,18 +832,25 @@ inline int WireFormatLite::GroupSize(const MessageLite& value) {
return value.ByteSize();
}
inline int WireFormatLite::MessageSize(const MessageLite& value) {
- int size = value.ByteSize();
- return io::CodedOutputStream::VarintSize32(size) + size;
+ return LengthDelimitedSize(value.ByteSize());
}
-template<typename MessageType>
-inline int WireFormatLite::GroupSizeNoVirtual(const MessageType& value) {
- return value.MessageType::ByteSize();
+// See comment on ReadGroupNoVirtual to understand the need for this template
+// parameter name.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline int WireFormatLite::GroupSizeNoVirtual(
+ const MessageType_WorkAroundCppLookupDefect& value) {
+ return value.MessageType_WorkAroundCppLookupDefect::ByteSize();
}
-template<typename MessageType>
-inline int WireFormatLite::MessageSizeNoVirtual(const MessageType& value) {
- int size = value.MessageType::ByteSize();
- return io::CodedOutputStream::VarintSize32(size) + size;
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline int WireFormatLite::MessageSizeNoVirtual(
+ const MessageType_WorkAroundCppLookupDefect& value) {
+ return LengthDelimitedSize(
+ value.MessageType_WorkAroundCppLookupDefect::ByteSize());
+}
+
+inline int WireFormatLite::LengthDelimitedSize(int length) {
+ return io::CodedOutputStream::VarintSize32(length) + length;
}
} // namespace internal
diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc
index 867970c..81a024b 100644
--- a/src/google/protobuf/wire_format_unittest.cc
+++ b/src/google/protobuf/wire_format_unittest.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -44,7 +44,7 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
-#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
@@ -175,6 +175,43 @@ TEST(WireFormatTest, ParsePackedExtensions) {
TestUtil::ExpectPackedExtensionsSet(dest);
}
+TEST(WireFormatTest, ParseOneof) {
+ unittest::TestOneof2 source, dest;
+ string data;
+
+ // Serialize using the generated code.
+ TestUtil::SetOneof1(&source);
+ source.SerializeToString(&data);
+
+ // Parse using WireFormat.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectOneofSet1(dest);
+}
+
+TEST(WireFormatTest, OneofOnlySetLast) {
+ unittest::TestOneofBackwardsCompatible source;
+ unittest::TestOneof oneof_dest;
+ string data;
+
+ // Set two fields
+ source.set_foo_int(100);
+ source.set_foo_string("101");
+
+ // Serialize and parse to oneof message.
+ source.SerializeToString(&data);
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &oneof_dest);
+
+ // Only the last field is set.
+ EXPECT_FALSE(oneof_dest.has_foo_int());
+ EXPECT_TRUE(oneof_dest.has_foo_string());
+}
+
TEST(WireFormatTest, ByteSize) {
unittest::TestAllTypes message;
TestUtil::SetAllFields(&message);
@@ -217,6 +254,18 @@ TEST(WireFormatTest, ByteSizePackedExtensions) {
EXPECT_EQ(0, WireFormat::ByteSize(message));
}
+TEST(WireFormatTest, ByteSizeOneof) {
+ unittest::TestOneof2 message;
+ TestUtil::SetOneof1(&message);
+
+ EXPECT_EQ(message.ByteSize(),
+ WireFormat::ByteSize(message));
+ message.Clear();
+
+ EXPECT_EQ(0, message.ByteSize());
+ EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
TEST(WireFormatTest, Serialize) {
unittest::TestAllTypes message;
string generated_data;
@@ -311,6 +360,36 @@ TEST(WireFormatTest, SerializeFieldsAndExtensions) {
TestUtil::ExpectAllFieldsAndExtensionsInOrder(generated_data);
}
+TEST(WireFormatTest, SerializeOneof) {
+ unittest::TestOneof2 message;
+ string generated_data;
+ string dynamic_data;
+
+ TestUtil::SetOneof1(&message);
+ int size = message.ByteSize();
+
+ // Serialize using the generated code.
+ {
+ io::StringOutputStream raw_output(&generated_data);
+ io::CodedOutputStream output(&raw_output);
+ message.SerializeWithCachedSizes(&output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Serialize using WireFormat.
+ {
+ io::StringOutputStream raw_output(&dynamic_data);
+ io::CodedOutputStream output(&raw_output);
+ WireFormat::SerializeWithCachedSizes(message, size, &output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Should be the same.
+ // Don't use EXPECT_EQ here because we're comparing raw binary data and
+ // we really don't want it dumped to stdout on failure.
+ EXPECT_TRUE(dynamic_data == generated_data);
+}
+
TEST(WireFormatTest, ParseMultipleExtensionRanges) {
// Make sure we can parse a message that contains multiple extensions ranges.
unittest::TestFieldOrderings source;
@@ -480,6 +559,54 @@ TEST(WireFormatTest, ParseMessageSet) {
EXPECT_EQ(message_set.DebugString(), dynamic_message_set.DebugString());
}
+TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) {
+ string data;
+ {
+ unittest::TestMessageSetExtension1 message;
+ message.set_i(123);
+ // Build a MessageSet manually with its message content put before its
+ // type_id.
+ io::StringOutputStream output_stream(&data);
+ io::CodedOutputStream coded_output(&output_stream);
+ coded_output.WriteTag(WireFormatLite::kMessageSetItemStartTag);
+ // Write the message content first.
+ WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber,
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ &coded_output);
+ coded_output.WriteVarint32(message.ByteSize());
+ message.SerializeWithCachedSizes(&coded_output);
+ // Write the type id.
+ uint32 type_id = message.GetDescriptor()->extension(0)->number();
+ WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
+ type_id, &coded_output);
+ coded_output.WriteTag(WireFormatLite::kMessageSetItemEndTag);
+ }
+ {
+ unittest::TestMessageSet message_set;
+ ASSERT_TRUE(message_set.ParseFromString(data));
+
+ EXPECT_EQ(123, message_set.GetExtension(
+ unittest::TestMessageSetExtension1::message_set_extension).i());
+ }
+ {
+ // Test parse the message via Reflection.
+ unittest::TestMessageSet message_set;
+ io::CodedInputStream input(
+ reinterpret_cast<const uint8*>(data.data()), data.size());
+ EXPECT_TRUE(WireFormat::ParseAndMergePartial(&input, &message_set));
+ EXPECT_TRUE(input.ConsumedEntireMessage());
+
+ EXPECT_EQ(123, message_set.GetExtension(
+ unittest::TestMessageSetExtension1::message_set_extension).i());
+ }
+}
+
+TEST(WireFormatTest, ParseBrokenMessageSet) {
+ unittest::TestMessageSet message_set;
+ string input("goodbye"); // Invalid wire format data.
+ EXPECT_FALSE(message_set.ParseFromString(input));
+}
+
TEST(WireFormatTest, RecursionLimit) {
unittest::TestRecursiveMessage message;
message.mutable_a()->mutable_a()->mutable_a()->mutable_a()->set_i(1);
@@ -639,6 +766,34 @@ TEST(WireFormatTest, RepeatedScalarsDifferentTagSizes) {
EXPECT_EQ(msg1.DebugString(), msg2.DebugString());
}
+TEST(WireFormatTest, CompatibleTypes) {
+ const int64 data = 0x100000000;
+ unittest::Int64Message msg1;
+ msg1.set_data(data);
+ string serialized;
+ msg1.SerializeToString(&serialized);
+
+ // Test int64 is compatible with bool
+ unittest::BoolMessage msg2;
+ ASSERT_TRUE(msg2.ParseFromString(serialized));
+ ASSERT_EQ(static_cast<bool>(data), msg2.data());
+
+ // Test int64 is compatible with uint64
+ unittest::Uint64Message msg3;
+ ASSERT_TRUE(msg3.ParseFromString(serialized));
+ ASSERT_EQ(static_cast<uint64>(data), msg3.data());
+
+ // Test int64 is compatible with int32
+ unittest::Int32Message msg4;
+ ASSERT_TRUE(msg4.ParseFromString(serialized));
+ ASSERT_EQ(static_cast<int32>(data), msg4.data());
+
+ // Test int64 is compatible with uint32
+ unittest::Uint32Message msg5;
+ ASSERT_TRUE(msg5.ParseFromString(serialized));
+ ASSERT_EQ(static_cast<uint32>(data), msg5.data());
+}
+
class WireFormatInvalidInputTest : public testing::Test {
protected:
// Make a serialized TestAllTypes in which the field optional_nested_message
@@ -800,7 +955,20 @@ bool ReadMessage(const string &wire_buffer, T *message) {
return message->ParseFromArray(wire_buffer.data(), wire_buffer.size());
}
-TEST(Utf8ValidationTest, WriteInvalidUTF8String) {
+bool StartsWith(const string& s, const string& prefix) {
+ return s.substr(0, prefix.length()) == prefix;
+}
+
+class Utf8ValidationTest : public ::testing::Test {
+ protected:
+ Utf8ValidationTest() {}
+ virtual ~Utf8ValidationTest() {}
+ virtual void SetUp() {
+ }
+
+};
+
+TEST_F(Utf8ValidationTest, WriteInvalidUTF8String) {
string wire_buffer;
protobuf_unittest::OneString input;
vector<string> errors;
@@ -811,17 +979,17 @@ TEST(Utf8ValidationTest, WriteInvalidUTF8String) {
}
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
ASSERT_EQ(1, errors.size());
- EXPECT_EQ("Encountered string containing invalid UTF-8 data while "
- "serializing protocol buffer. Strings must contain only UTF-8; "
- "use the 'bytes' type for raw bytes.",
- errors[0]);
-
+ EXPECT_TRUE(StartsWith(errors[0],
+ "String field 'data' contains invalid UTF-8 data when "
+ "serializing a protocol buffer. Use the "
+ "'bytes' type if you intend to send raw bytes."));
#else
ASSERT_EQ(0, errors.size());
#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
}
-TEST(Utf8ValidationTest, ReadInvalidUTF8String) {
+
+TEST_F(Utf8ValidationTest, ReadInvalidUTF8String) {
string wire_buffer;
protobuf_unittest::OneString input;
WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
@@ -834,17 +1002,18 @@ TEST(Utf8ValidationTest, ReadInvalidUTF8String) {
}
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
ASSERT_EQ(1, errors.size());
- EXPECT_EQ("Encountered string containing invalid UTF-8 data while "
- "parsing protocol buffer. Strings must contain only UTF-8; "
- "use the 'bytes' type for raw bytes.",
- errors[0]);
+ EXPECT_TRUE(StartsWith(errors[0],
+ "String field 'data' contains invalid UTF-8 data when "
+ "parsing a protocol buffer. Use the "
+ "'bytes' type if you intend to send raw bytes."));
#else
ASSERT_EQ(0, errors.size());
#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
}
-TEST(Utf8ValidationTest, WriteValidUTF8String) {
+
+TEST_F(Utf8ValidationTest, WriteValidUTF8String) {
string wire_buffer;
protobuf_unittest::OneString input;
vector<string> errors;
@@ -856,7 +1025,7 @@ TEST(Utf8ValidationTest, WriteValidUTF8String) {
ASSERT_EQ(0, errors.size());
}
-TEST(Utf8ValidationTest, ReadValidUTF8String) {
+TEST_F(Utf8ValidationTest, ReadValidUTF8String) {
string wire_buffer;
protobuf_unittest::OneString input;
WriteMessage(kValidUTF8String, &input, &wire_buffer);
@@ -872,7 +1041,7 @@ TEST(Utf8ValidationTest, ReadValidUTF8String) {
}
// Bytes: anything can pass as bytes, use invalid UTF-8 string to test
-TEST(Utf8ValidationTest, WriteArbitraryBytes) {
+TEST_F(Utf8ValidationTest, WriteArbitraryBytes) {
string wire_buffer;
protobuf_unittest::OneBytes input;
vector<string> errors;
@@ -884,7 +1053,7 @@ TEST(Utf8ValidationTest, WriteArbitraryBytes) {
ASSERT_EQ(0, errors.size());
}
-TEST(Utf8ValidationTest, ReadArbitraryBytes) {
+TEST_F(Utf8ValidationTest, ReadArbitraryBytes) {
string wire_buffer;
protobuf_unittest::OneBytes input;
WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
@@ -899,6 +1068,52 @@ TEST(Utf8ValidationTest, ReadArbitraryBytes) {
EXPECT_EQ(input.data(), output.data());
}
+TEST_F(Utf8ValidationTest, ParseRepeatedString) {
+ protobuf_unittest::MoreBytes input;
+ input.add_data(kValidUTF8String);
+ input.add_data(kInvalidUTF8String);
+ input.add_data(kInvalidUTF8String);
+ string wire_buffer = input.SerializeAsString();
+
+ protobuf_unittest::MoreString output;
+ vector<string> errors;
+ {
+ ScopedMemoryLog log;
+ ReadMessage(wire_buffer, &output);
+ errors = log.GetMessages(ERROR);
+ }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ ASSERT_EQ(2, errors.size());
+#else
+ ASSERT_EQ(0, errors.size());
+#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ EXPECT_EQ(wire_buffer, output.SerializeAsString());
+}
+
+// Test the old VerifyUTF8String() function, which may still be called by old
+// generated code.
+TEST_F(Utf8ValidationTest, OldVerifyUTF8String) {
+ string data(kInvalidUTF8String);
+
+ vector<string> errors;
+ {
+ ScopedMemoryLog log;
+ WireFormat::VerifyUTF8String(data.data(), data.size(),
+ WireFormat::SERIALIZE);
+ errors = log.GetMessages(ERROR);
+ }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ ASSERT_EQ(1, errors.size());
+ EXPECT_TRUE(StartsWith(errors[0],
+ "String field contains invalid UTF-8 data when "
+ "serializing a protocol buffer. Use the "
+ "'bytes' type if you intend to send raw bytes."));
+#else
+ ASSERT_EQ(0, errors.size());
+#endif
+}
+
+
} // namespace
} // namespace internal
} // namespace protobuf
diff --git a/test-driver b/test-driver
new file mode 100755
index 0000000..d306056
--- /dev/null
+++ b/test-driver
@@ -0,0 +1,139 @@
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2013-07-13.22; # UTC
+
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+# Make unconditional expansion of undefined variables an error. This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+ echo "$0: $*" >&2
+ print_usage >&2
+ exit 2
+}
+
+print_usage ()
+{
+ cat <<END
+Usage:
+ test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+ [--expect-failure={yes|no}] [--color-tests={yes|no}]
+ [--enable-hard-errors={yes|no}] [--]
+ TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+test_name= # Used for reporting.
+log_file= # Where to save the output of the test script.
+trs_file= # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+ case $1 in
+ --help) print_usage; exit $?;;
+ --version) echo "test-driver $scriptversion"; exit $?;;
+ --test-name) test_name=$2; shift;;
+ --log-file) log_file=$2; shift;;
+ --trs-file) trs_file=$2; shift;;
+ --color-tests) color_tests=$2; shift;;
+ --expect-failure) expect_failure=$2; shift;;
+ --enable-hard-errors) enable_hard_errors=$2; shift;;
+ --) shift; break;;
+ -*) usage_error "invalid option: '$1'";;
+ *) break;;
+ esac
+ shift
+done
+
+missing_opts=
+test x"$test_name" = x && missing_opts="$missing_opts --test-name"
+test x"$log_file" = x && missing_opts="$missing_opts --log-file"
+test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
+if test x"$missing_opts" != x; then
+ usage_error "the following mandatory options are missing:$missing_opts"
+fi
+
+if test $# -eq 0; then
+ usage_error "missing argument"
+fi
+
+if test $color_tests = yes; then
+ # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+ red='' # Red.
+ grn='' # Green.
+ lgn='' # Light green.
+ blu='' # Blue.
+ mgn='' # Magenta.
+ std='' # No color.
+else
+ red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+ estatus=1
+fi
+
+case $estatus:$expect_failure in
+ 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+ 0:*) col=$grn res=PASS recheck=no gcopy=no;;
+ 77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
+ 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;;
+ *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;;
+ *:*) col=$red res=FAIL recheck=yes gcopy=yes;;
+esac
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/vsprojects/extract_includes.bat b/vsprojects/extract_includes.bat
index 5e513d7..beab8c4 100755
--- a/vsprojects/extract_includes.bat
+++ b/vsprojects/extract_includes.bat
@@ -7,13 +7,19 @@ md include\google\protobuf\compiler
md include\google\protobuf\compiler\cpp
md include\google\protobuf\compiler\java
md include\google\protobuf\compiler\python
+copy ..\src\google\protobuf\stubs\atomicops.h include\google\protobuf\stubs\atomicops.h
+copy ..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h include\google\protobuf\stubs\atomicops_internals_x86_msvc.h
copy ..\src\google\protobuf\stubs\common.h include\google\protobuf\stubs\common.h
copy ..\src\google\protobuf\stubs\once.h include\google\protobuf\stubs\once.h
+copy ..\src\google\protobuf\stubs\platform_macros.h include\google\protobuf\stubs\platform_macros.h
+copy ..\src\google\protobuf\stubs\template_util.h include\google\protobuf\stubs\template_util.h
+copy ..\src\google\protobuf\stubs\type_traits.h include\google\protobuf\stubs\type_traits.h
copy ..\src\google\protobuf\descriptor.h include\google\protobuf\descriptor.h
copy ..\src\google\protobuf\descriptor.pb.h include\google\protobuf\descriptor.pb.h
copy ..\src\google\protobuf\descriptor_database.h include\google\protobuf\descriptor_database.h
copy ..\src\google\protobuf\dynamic_message.h include\google\protobuf\dynamic_message.h
copy ..\src\google\protobuf\extension_set.h include\google\protobuf\extension_set.h
+copy ..\src\google\protobuf\generated_enum_reflection.h include\google\protobuf\generated_enum_reflection.h
copy ..\src\google\protobuf\generated_message_util.h include\google\protobuf\generated_message_util.h
copy ..\src\google\protobuf\generated_message_reflection.h include\google\protobuf\generated_message_reflection.h
copy ..\src\google\protobuf\message.h include\google\protobuf\message.h
@@ -29,6 +35,7 @@ copy ..\src\google\protobuf\wire_format_lite_inl.h include\google\protobuf\wire_
copy ..\src\google\protobuf\io\coded_stream.h include\google\protobuf\io\coded_stream.h
copy ..\src\google\protobuf\io\gzip_stream.h include\google\protobuf\io\gzip_stream.h
copy ..\src\google\protobuf\io\printer.h include\google\protobuf\io\printer.h
+copy ..\src\google\protobuf\io\strtod.h include\google\protobuf\io\strtod.h
copy ..\src\google\protobuf\io\tokenizer.h include\google\protobuf\io\tokenizer.h
copy ..\src\google\protobuf\io\zero_copy_stream.h include\google\protobuf\io\zero_copy_stream.h
copy ..\src\google\protobuf\io\zero_copy_stream_impl.h include\google\protobuf\io\zero_copy_stream_impl.h
@@ -40,3 +47,4 @@ copy ..\src\google\protobuf\compiler\parser.h include\google\protobuf\compiler\p
copy ..\src\google\protobuf\compiler\cpp\cpp_generator.h include\google\protobuf\compiler\cpp\cpp_generator.h
copy ..\src\google\protobuf\compiler\java\java_generator.h include\google\protobuf\compiler\java\java_generator.h
copy ..\src\google\protobuf\compiler\python\python_generator.h include\google\protobuf\compiler\python\python_generator.h
+copy ..\src\google\protobuf\compiler\plugin.h include\google\protobuf\compiler\plugin.h
diff --git a/vsprojects/libprotobuf-lite.vcproj b/vsprojects/libprotobuf-lite.vcproj
index 8197699..06b1598 100644
--- a/vsprojects/libprotobuf-lite.vcproj
+++ b/vsprojects/libprotobuf-lite.vcproj
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="8.00"
+ Version="9.00"
Name="libprotobuf-lite"
ProjectGUID="{49EA010D-706F-4BE2-A397-77854B72A040}"
Keyword="Win32Proj"
@@ -188,11 +188,23 @@
>
</File>
<File
+ RelativePath="..\src\google\protobuf\stubs\atomicops.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\platform_macros.h"
+ >
+ </File>
+ <File
RelativePath="..\src\google\protobuf\repeated_field.h"
>
</File>
<File
- RelativePath="..\src\google\protobuf\stubs\stl_util-inl.h"
+ RelativePath="..\src\google\protobuf\stubs\stl_util.h"
>
</File>
<File
@@ -211,6 +223,18 @@
RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.h"
>
</File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\stringprintf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\template_util.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\type_traits.h"
+ >
+ </File>
</Filter>
<Filter
Name="Resource Files"
@@ -240,15 +264,15 @@
>
</File>
<File
- RelativePath="..\src\google\protobuf\stubs\hash.cc"
+ RelativePath="..\src\google\protobuf\message_lite.cc"
>
</File>
<File
- RelativePath="..\src\google\protobuf\message_lite.cc"
+ RelativePath="..\src\google\protobuf\stubs\once.cc"
>
</File>
<File
- RelativePath="..\src\google\protobuf\stubs\once.cc"
+ RelativePath="..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.cc"
>
</File>
<File
@@ -267,6 +291,10 @@
RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.cc"
>
</File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\stringprintf.cc"
+ >
+ </File>
</Filter>
</Files>
<Globals>
diff --git a/vsprojects/libprotobuf.vcproj b/vsprojects/libprotobuf.vcproj
index 7b8111f..1a488f7 100644
--- a/vsprojects/libprotobuf.vcproj
+++ b/vsprojects/libprotobuf.vcproj
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="8.00"
+ Version="9.00"
Name="libprotobuf"
ProjectGUID="{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}"
Keyword="Win32Proj"
@@ -196,6 +196,10 @@
>
</File>
<File
+ RelativePath="..\src\google\protobuf\io\strtod.h"
+ >
+ </File>
+ <File
RelativePath="..\src\google\protobuf\stubs\hash.h"
>
</File>
@@ -204,7 +208,7 @@
>
</File>
<File
- RelativePath="..\src\google\protobuf\stubs\map-util.h"
+ RelativePath="..\src\google\protobuf\stubs\map_util.h"
>
</File>
<File
@@ -216,6 +220,18 @@
>
</File>
<File
+ RelativePath="..\src\google\protobuf\stubs\atomicops.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\platform_macros.h"
+ >
+ </File>
+ <File
RelativePath="..\src\google\protobuf\stubs\once.h"
>
</File>
@@ -240,7 +256,19 @@
>
</File>
<File
- RelativePath="..\src\google\protobuf\stubs\stl_util-inl.h"
+ RelativePath="..\src\google\protobuf\stubs\stl_util.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\stringprintf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\template_util.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\type_traits.h"
>
</File>
<File
@@ -344,7 +372,7 @@
>
</File>
<File
- RelativePath="..\src\google\protobuf\stubs\hash.cc"
+ RelativePath="..\src\google\protobuf\io\strtod.cc"
>
</File>
<File
@@ -364,6 +392,10 @@
>
</File>
<File
+ RelativePath="..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.cc"
+ >
+ </File>
+ <File
RelativePath="..\src\google\protobuf\compiler\parser.cc"
>
</File>
@@ -427,6 +459,10 @@
RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.cc"
>
</File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\stringprintf.cc"
+ >
+ </File>
</Filter>
</Files>
<Globals>
diff --git a/vsprojects/libprotoc.vcproj b/vsprojects/libprotoc.vcproj
index 81063d3..ccbc0b3 100644
--- a/vsprojects/libprotoc.vcproj
+++ b/vsprojects/libprotoc.vcproj
@@ -1,406 +1,466 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="libprotoc"
- ProjectGUID="{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}"
- Keyword="Win32Proj"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
- Optimization="0"
- AdditionalIncludeDirectories="../src;."
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOC_EXPORTS;"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
- AdditionalIncludeDirectories="../src;."
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOC_EXPORTS;"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\src\google\protobuf\compiler\code_generator.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\command_line_interface.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\subprocess.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\zip_writer.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\plugin.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\plugin.pb.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum_field.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_extension.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_field.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_file.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_generator.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_helpers.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_message.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_message_field.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_primitive_field.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_service.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_string_field.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_enum.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_enum_field.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_extension.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_field.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_file.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_generator.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_helpers.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_message.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_message_field.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_primitive_field.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_service.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\python\python_generator.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\src\google\protobuf\compiler\code_generator.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\command_line_interface.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\subprocess.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\zip_writer.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\plugin.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\plugin.pb.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum_field.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_extension.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_field.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_file.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_generator.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_helpers.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_message.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_message_field.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_primitive_field.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_service.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_string_field.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_enum.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_enum_field.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_extension.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_field.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_file.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_generator.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_helpers.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_message.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_message_field.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_primitive_field.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\java\java_service.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\python\python_generator.cc"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="libprotoc"
+ ProjectGUID="{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="0"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="4"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+ Optimization="0"
+ AdditionalIncludeDirectories="../src;."
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOC_EXPORTS;"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="4"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+ AdditionalIncludeDirectories="../src;."
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOC_EXPORTS;"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\src\google\protobuf\compiler\code_generator.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\command_line_interface.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\subprocess.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\zip_writer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\plugin.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\plugin.pb.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum_field.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_extension.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_field.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_file.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_generator.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_helpers.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_message.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_message_field.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_options.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_primitive_field.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_service.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_string_field.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_context.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_enum.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_enum_field.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_extension.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_field.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_file.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_generator.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_generator_factory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_helpers.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_lazy_message_field.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_message.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_message_field.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_name_resolver.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_primitive_field.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_service.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_shared_code_generator.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_string_field.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_doc_comment.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_doc_comment.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\python\python_generator.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\src\google\protobuf\compiler\code_generator.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\command_line_interface.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\subprocess.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\zip_writer.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\plugin.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\plugin.pb.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum_field.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_extension.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_field.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_file.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_generator.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_helpers.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_message.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_message_field.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_primitive_field.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_service.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_string_field.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_context.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_enum.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_enum_field.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_extension.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_field.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_file.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_generator.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_generator_factory.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_helpers.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_lazy_message_field.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_message.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_message_field.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_name_resolver.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_primitive_field.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_service.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_shared_code_generator.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\java\java_string_field.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\python\python_generator.cc"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vsprojects/lite-test.vcproj b/vsprojects/lite-test.vcproj
index 0887cf1..0314b36 100644
--- a/vsprojects/lite-test.vcproj
+++ b/vsprojects/lite-test.vcproj
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="8.00"
+ Version="9.00"
Name="lite-test"
ProjectGUID="{12015ACE-42BE-4952-A5A0-44A9A46908E2}"
RootNamespace="tests"
@@ -46,7 +46,7 @@
AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
Optimization="0"
AdditionalIncludeDirectories="../src;.;../gtest/include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_VARIADIC_MAX=10;"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -122,7 +122,7 @@
Name="VCCLCompilerTool"
AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
AdditionalIncludeDirectories="../src;.;../gtest/include"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_VARIADIC_MAX=10;"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
@@ -190,6 +190,10 @@
RelativePath=".\google\protobuf\unittest_import_lite.pb.h"
>
</File>
+ <File
+ RelativePath=".\google\protobuf\unittest_import_public_lite.pb.h"
+ >
+ </File>
</Filter>
<Filter
Name="Resource Files"
@@ -218,6 +222,10 @@
RelativePath=".\google\protobuf\unittest_import_lite.pb.cc"
>
</File>
+ <File
+ RelativePath=".\google\protobuf\unittest_import_public_lite.pb.cc"
+ >
+ </File>
</Filter>
<File
RelativePath="..\src\google\protobuf\unittest_lite.proto"
@@ -267,6 +275,30 @@
/>
</FileConfiguration>
</File>
+ <File
+ RelativePath="..\src\google\protobuf\unittest_import_public_lite.proto"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating unittest_import_public_lite.pb.{h,cc}..."
+ CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_public_lite.proto&#x0D;&#x0A;"
+ Outputs="google\protobuf\unittest_import_public_lite.pb.h;google\protobuf\unittest_import_public_lite.pb.cc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating unittest_import_public_lite.pb.{h,cc}..."
+ CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_public_lite.proto&#x0D;&#x0A;"
+ Outputs="google\protobuf\unittest_import_public_lite.pb.h;google\protobuf\unittest_import_public_lite.pb.cc"
+ />
+ </FileConfiguration>
+ </File>
</Files>
<Globals>
</Globals>
diff --git a/vsprojects/protobuf.sln b/vsprojects/protobuf.sln
index bac0055..567dee6 100644
--- a/vsprojects/protobuf.sln
+++ b/vsprojects/protobuf.sln
@@ -1,92 +1,92 @@
-
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf", "libprotobuf.vcproj", "{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotoc", "libprotoc.vcproj", "{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}"
- ProjectSection(ProjectDependencies) = postProject
- {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "protoc", "protoc.vcproj", "{1738D5F6-ED1E-47E0-B2F0-456864B93C1E}"
- ProjectSection(ProjectDependencies) = postProject
- {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}
- {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests.vcproj", "{4DF72760-C055-40A5-A77E-30A17E2AC2DB}"
- ProjectSection(ProjectDependencies) = postProject
- {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}
- {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
- {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}
- {3AF54C8A-10BF-4332-9147-F68ED9862032} = {3AF54C8A-10BF-4332-9147-F68ED9862032}
- {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32} = {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}
- {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} = {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "..\gtest\msvc\gtest.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main", "..\gtest\msvc\gtest_main.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862032}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf-lite", "libprotobuf-lite.vcproj", "{49EA010D-706F-4BE2-A397-77854B72A040}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lite-test", "lite-test.vcproj", "{12015ACE-42BE-4952-A5A0-44A9A46908E2}"
- ProjectSection(ProjectDependencies) = postProject
- {49EA010D-706F-4BE2-A397-77854B72A040} = {49EA010D-706F-4BE2-A397-77854B72A040}
- {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} = {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_plugin", "test_plugin.vcproj", "{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}"
- ProjectSection(ProjectDependencies) = postProject
- {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}
- {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
- {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.ActiveCfg = Debug|Win32
- {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.Build.0 = Debug|Win32
- {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.ActiveCfg = Release|Win32
- {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.Build.0 = Release|Win32
- {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|Win32.ActiveCfg = Debug|Win32
- {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|Win32.Build.0 = Debug|Win32
- {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|Win32.ActiveCfg = Release|Win32
- {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|Win32.Build.0 = Release|Win32
- {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|Win32.ActiveCfg = Debug|Win32
- {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|Win32.Build.0 = Debug|Win32
- {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|Win32.ActiveCfg = Release|Win32
- {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|Win32.Build.0 = Release|Win32
- {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|Win32.ActiveCfg = Debug|Win32
- {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|Win32.Build.0 = Debug|Win32
- {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|Win32.ActiveCfg = Release|Win32
- {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|Win32.Build.0 = Release|Win32
- {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.ActiveCfg = Debug|Win32
- {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.Build.0 = Debug|Win32
- {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.ActiveCfg = Release|Win32
- {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.Build.0 = Release|Win32
- {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.ActiveCfg = Debug|Win32
- {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.Build.0 = Debug|Win32
- {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.ActiveCfg = Release|Win32
- {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.Build.0 = Release|Win32
- {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|Win32.ActiveCfg = Debug|Win32
- {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|Win32.Build.0 = Debug|Win32
- {49EA010D-706F-4BE2-A397-77854B72A040}.Release|Win32.ActiveCfg = Release|Win32
- {49EA010D-706F-4BE2-A397-77854B72A040}.Release|Win32.Build.0 = Release|Win32
- {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|Win32.ActiveCfg = Debug|Win32
- {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|Win32.Build.0 = Debug|Win32
- {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.ActiveCfg = Release|Win32
- {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.Build.0 = Release|Win32
- {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.ActiveCfg = Debug|Win32
- {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.Build.0 = Debug|Win32
- {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.ActiveCfg = Release|Win32
- {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf", "libprotobuf.vcproj", "{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotoc", "libprotoc.vcproj", "{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "protoc", "protoc.vcproj", "{1738D5F6-ED1E-47E0-B2F0-456864B93C1E}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}
+ {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests.vcproj", "{4DF72760-C055-40A5-A77E-30A17E2AC2DB}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}
+ {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
+ {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}
+ {3AF54C8A-10BF-4332-9147-F68ED9862032} = {3AF54C8A-10BF-4332-9147-F68ED9862032}
+ {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32} = {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}
+ {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} = {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "..\gtest\msvc\gtest.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main", "..\gtest\msvc\gtest_main.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862032}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf-lite", "libprotobuf-lite.vcproj", "{49EA010D-706F-4BE2-A397-77854B72A040}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lite-test", "lite-test.vcproj", "{12015ACE-42BE-4952-A5A0-44A9A46908E2}"
+ ProjectSection(ProjectDependencies) = postProject
+ {49EA010D-706F-4BE2-A397-77854B72A040} = {49EA010D-706F-4BE2-A397-77854B72A040}
+ {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} = {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_plugin", "test_plugin.vcproj", "{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}
+ {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
+ {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.Build.0 = Debug|Win32
+ {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.ActiveCfg = Release|Win32
+ {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.Build.0 = Release|Win32
+ {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|Win32.Build.0 = Debug|Win32
+ {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|Win32.ActiveCfg = Release|Win32
+ {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|Win32.Build.0 = Release|Win32
+ {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|Win32.Build.0 = Debug|Win32
+ {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|Win32.ActiveCfg = Release|Win32
+ {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|Win32.Build.0 = Release|Win32
+ {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|Win32.Build.0 = Debug|Win32
+ {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|Win32.ActiveCfg = Release|Win32
+ {4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|Win32.Build.0 = Release|Win32
+ {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.Build.0 = Debug|Win32
+ {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.ActiveCfg = Release|Win32
+ {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.Build.0 = Release|Win32
+ {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.Build.0 = Debug|Win32
+ {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.ActiveCfg = Release|Win32
+ {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.Build.0 = Release|Win32
+ {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|Win32.ActiveCfg = Debug|Win32
+ {49EA010D-706F-4BE2-A397-77854B72A040}.Debug|Win32.Build.0 = Debug|Win32
+ {49EA010D-706F-4BE2-A397-77854B72A040}.Release|Win32.ActiveCfg = Release|Win32
+ {49EA010D-706F-4BE2-A397-77854B72A040}.Release|Win32.Build.0 = Release|Win32
+ {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|Win32.Build.0 = Debug|Win32
+ {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.ActiveCfg = Release|Win32
+ {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.Build.0 = Release|Win32
+ {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.ActiveCfg = Debug|Win32
+ {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.Build.0 = Debug|Win32
+ {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.ActiveCfg = Release|Win32
+ {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/vsprojects/protoc.vcproj b/vsprojects/protoc.vcproj
index a0ca63e..17e8474 100644
--- a/vsprojects/protoc.vcproj
+++ b/vsprojects/protoc.vcproj
@@ -1,192 +1,192 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="protoc"
- ProjectGUID="{1738D5F6-ED1E-47E0-B2F0-456864B93C1E}"
- Keyword="Win32Proj"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
- Optimization="0"
- AdditionalIncludeDirectories="../src;."
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
- AdditionalIncludeDirectories="../src;."
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\src\google\protobuf\compiler\main.cc"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="protoc"
+ ProjectGUID="{1738D5F6-ED1E-47E0-B2F0-456864B93C1E}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="0"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+ Optimization="0"
+ AdditionalIncludeDirectories="../src;."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+ AdditionalIncludeDirectories="../src;."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\src\google\protobuf\compiler\main.cc"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vsprojects/test_plugin.vcproj b/vsprojects/test_plugin.vcproj
index cfe387f..2dcf2ad 100755
--- a/vsprojects/test_plugin.vcproj
+++ b/vsprojects/test_plugin.vcproj
@@ -1,20 +1,20 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="test_plugin"
- ProjectGUID="{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}"
- RootNamespace="test_plugin"
- Keyword="Win32Proj"
- TargetFrameworkVersion="196613"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="test_plugin"
+ ProjectGUID="{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}"
+ RootNamespace="test_plugin"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
@@ -46,7 +46,7 @@
AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
Optimization="0"
AdditionalIncludeDirectories="../src;.;../gtest/include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_VARIADIC_MAX=10;"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -122,7 +122,7 @@
Name="VCCLCompilerTool"
AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
AdditionalIncludeDirectories="../src;.;../gtest/include"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_VARIADIC_MAX=10;"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
diff --git a/vsprojects/tests.vcproj b/vsprojects/tests.vcproj
index 772046a..fb815b5 100644
--- a/vsprojects/tests.vcproj
+++ b/vsprojects/tests.vcproj
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="8.00"
+ Version="9.00"
Name="tests"
ProjectGUID="{4DF72760-C055-40A5-A77E-30A17E2AC2DB}"
RootNamespace="tests"
@@ -46,7 +46,7 @@
AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
Optimization="0"
AdditionalIncludeDirectories="../src;.;../gtest/include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_VARIADIC_MAX=10;"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -122,7 +122,7 @@
Name="VCCLCompilerTool"
AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
AdditionalIncludeDirectories="../src;.;../gtest/include"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_VARIADIC_MAX=10;"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
@@ -215,6 +215,10 @@
>
</File>
<File
+ RelativePath=".\google\protobuf\unittest_import_public.pb.h"
+ >
+ </File>
+ <File
RelativePath=".\google\protobuf\unittest_lite_imports_nonline.pb.h"
>
</File>
@@ -263,6 +267,10 @@
>
</File>
<File
+ RelativePath="..\src\google\protobuf\compiler\cpp\cpp_unittest.cc"
+ >
+ </File>
+ <File
RelativePath=".\google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc"
>
</File>
@@ -279,6 +287,10 @@
>
</File>
<File
+ RelativePath="..\src\google\protobuf\compiler\java\java_doc_comment_unittest.cc"
+ >
+ </File>
+ <File
RelativePath="..\src\google\protobuf\compiler\python\python_plugin_unittest.cc"
>
</File>
@@ -339,10 +351,26 @@
>
</File>
<File
+ RelativePath="..\src\google\protobuf\repeated_field_reflection_unittest.cc"
+ >
+ </File>
+ <File
RelativePath="..\src\google\protobuf\stubs\structurally_valid_unittest.cc"
>
</File>
<File
+ RelativePath="..\src\google\protobuf\stubs\stringprintf_unittest.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\template_util_unittest.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\stubs\type_traits_unittest.cc"
+ >
+ </File>
+ <File
RelativePath="..\src\google\protobuf\stubs\strutil_unittest.cc"
>
</File>
@@ -375,6 +403,10 @@
>
</File>
<File
+ RelativePath=".\google\protobuf\unittest_import_public.pb.cc"
+ >
+ </File>
+ <File
RelativePath=".\google\protobuf\unittest_lite_imports_nonlite.pb.cc"
>
</File>
@@ -524,6 +556,30 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\src\google\protobuf\unittest_import_public.proto"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating unittest_import_public.pb.{h,cc}..."
+ CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_public.proto&#x0D;&#x0A;"
+ Outputs="google\protobuf\unittest_import_public.pb.h;google\protobuf\unittest_import_public.pb.cc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating unittest_import_public.pb.{h,cc}..."
+ CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_public.proto&#x0D;&#x0A;"
+ Outputs="google\protobuf\unittest_import_public.pb.h;google\protobuf\unittest_import_public.pb.cc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath="..\src\google\protobuf\unittest_lite_imports_nonlite.proto"
>
<FileConfiguration