protoc 2.6.1.1 → 2.6.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/protoc/Makefile.in +10 -13
- data/ext/protoc/extconf.rb +0 -1
- data/ext/protoc/protobuf/CHANGES.txt +593 -0
- data/ext/protoc/protobuf/CONTRIBUTORS.txt +93 -0
- data/ext/protoc/protobuf/INSTALL.txt +237 -0
- data/ext/protoc/protobuf/LICENSE +33 -0
- data/ext/protoc/protobuf/Makefile.am +267 -0
- data/ext/protoc/protobuf/README.md +167 -0
- data/ext/protoc/protobuf/autogen.sh +41 -0
- data/ext/protoc/protobuf/benchmarks/ProtoBench.java +203 -0
- data/ext/protoc/protobuf/benchmarks/google_message1.dat +0 -0
- data/ext/protoc/protobuf/benchmarks/google_message2.dat +0 -0
- data/ext/protoc/protobuf/benchmarks/google_size.proto +136 -0
- data/ext/protoc/protobuf/benchmarks/google_speed.proto +136 -0
- data/ext/protoc/protobuf/benchmarks/readme.txt +50 -0
- data/ext/protoc/protobuf/configure.ac +159 -0
- data/ext/protoc/protobuf/editors/README.txt +5 -0
- data/ext/protoc/protobuf/editors/proto.vim +105 -0
- data/ext/protoc/protobuf/editors/protobuf-mode.el +220 -0
- data/ext/protoc/protobuf/examples/AddPerson.java +95 -0
- data/ext/protoc/protobuf/examples/ListPeople.java +50 -0
- data/ext/protoc/protobuf/examples/Makefile +58 -0
- data/ext/protoc/protobuf/examples/README.txt +29 -0
- data/ext/protoc/protobuf/examples/add_person.cc +95 -0
- data/ext/protoc/protobuf/examples/add_person.py +58 -0
- data/ext/protoc/protobuf/examples/addressbook.proto +30 -0
- data/ext/protoc/protobuf/examples/list_people.cc +68 -0
- data/ext/protoc/protobuf/examples/list_people.py +38 -0
- data/ext/protoc/protobuf/generate_descriptor_proto.sh +33 -0
- data/ext/protoc/protobuf/java/README.txt +96 -0
- data/ext/protoc/protobuf/java/pom.xml +217 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/AbstractMessage.java +466 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/AbstractMessageLite.java +355 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/AbstractParser.java +253 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java +51 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/BlockingService.java +64 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/BoundedByteString.java +163 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/ByteString.java +1022 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/CodedInputStream.java +1311 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/CodedOutputStream.java +1297 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/Descriptors.java +2238 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/DynamicMessage.java +622 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/Extension.java +96 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistry.java +392 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java +185 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/FieldSet.java +907 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessage.java +2213 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java +949 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/Internal.java +391 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java +122 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/LazyField.java +154 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/LazyFieldLite.java +176 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/LazyStringArrayList.java +367 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/LazyStringList.java +163 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/LiteralByteString.java +362 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/Message.java +244 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/MessageLite.java +320 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java +60 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/MessageOrBuilder.java +143 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/MessageReflection.java +931 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/Parser.java +261 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java +58 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/ProtocolStringList.java +48 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java +696 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/RopeByteString.java +957 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/RpcCallback.java +47 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/RpcChannel.java +71 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/RpcController.java +118 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/RpcUtil.java +134 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/Service.java +117 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/ServiceException.java +52 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java +241 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/SmallSortedMap.java +618 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/TextFormat.java +1984 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/UninitializedMessageException.java +99 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/UnknownFieldSet.java +995 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java +205 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/Utf8.java +349 -0
- data/ext/protoc/protobuf/java/src/main/java/com/google/protobuf/WireFormat.java +163 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/AbstractMessageTest.java +527 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/BoundedByteStringTest.java +68 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/ByteStringTest.java +759 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/CheckUtf8Test.java +141 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java +769 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java +401 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java +80 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/DescriptorsTest.java +735 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/DynamicMessageTest.java +326 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java +48 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java +1515 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/IsValidUtf8Test.java +180 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java +421 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java +134 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/LazyFieldTest.java +121 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java +319 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java +174 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java +143 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java +85 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/LiteTest.java +148 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java +396 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/MessageTest.java +353 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/NestedBuildersTest.java +185 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/ParserTest.java +381 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java +190 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java +97 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/RopeByteStringTest.java +115 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/ServiceTest.java +320 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java +155 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java +420 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java +96 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/TestUtil.java +4124 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/TextFormatTest.java +994 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java +653 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java +227 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/WireFormatTest.java +606 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/lazy_fields_lite.proto +61 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto +55 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/multiple_files_test.proto +77 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/nested_builders_test.proto +53 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/nested_extension.proto +46 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/nested_extension_lite.proto +48 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension.proto +49 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto +50 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/outer_class_name_test.proto +38 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/outer_class_name_test2.proto +42 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/outer_class_name_test3.proto +43 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto +157 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/test_check_utf8.proto +50 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/test_check_utf8_size.proto +51 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/test_custom_options.proto +43 -0
- data/ext/protoc/protobuf/java/src/test/java/com/google/protobuf/test_extra_interfaces.proto +60 -0
- data/ext/protoc/protobuf/m4/ac_system_extensions.m4 +37 -0
- data/ext/protoc/protobuf/m4/acx_check_suncc.m4 +75 -0
- data/ext/protoc/protobuf/m4/acx_pthread.m4 +397 -0
- data/ext/protoc/protobuf/m4/stl_hash.m4 +72 -0
- data/ext/protoc/protobuf/more_tests/Makefile +41 -0
- data/ext/protoc/protobuf/post_process_dist.sh +60 -0
- data/ext/protoc/protobuf/protobuf-lite.pc.in +13 -0
- data/ext/protoc/protobuf/protobuf.pc.in +14 -0
- data/ext/protoc/protobuf/python/README.txt +105 -0
- data/ext/protoc/protobuf/python/ez_setup.py +284 -0
- data/ext/protoc/protobuf/python/google/__init__.py +1 -0
- data/ext/protoc/protobuf/python/google/protobuf/__init__.py +0 -0
- data/ext/protoc/protobuf/python/google/protobuf/descriptor.py +849 -0
- data/ext/protoc/protobuf/python/google/protobuf/descriptor_database.py +137 -0
- data/ext/protoc/protobuf/python/google/protobuf/descriptor_pool.py +643 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/__init__.py +0 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/api_implementation.cc +139 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/api_implementation.py +89 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/api_implementation_default_test.py +63 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/containers.py +269 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/cpp_message.py +663 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/decoder.py +831 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/descriptor_database_test.py +63 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/descriptor_pool_test.py +564 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/descriptor_pool_test1.proto +94 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/descriptor_pool_test2.proto +70 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/descriptor_python_test.py +54 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/descriptor_test.py +669 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/encoder.py +788 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/enum_type_wrapper.py +89 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/factory_test1.proto +57 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/factory_test2.proto +92 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/generator_test.py +343 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/message_factory_python_test.py +54 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/message_factory_test.py +131 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/message_listener.py +78 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/message_python_test.py +54 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/message_test.py +681 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/missing_enum_values.proto +50 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/more_extensions.proto +58 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/more_extensions_dynamic.proto +49 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/more_messages.proto +51 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/python_message.py +1251 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/reflection_test.py +2934 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/service_reflection_test.py +136 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/symbol_database_test.py +120 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/test_bad_identifiers.proto +52 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/test_util.py +662 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/text_encoding_test.py +68 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/text_format_test.py +743 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/type_checkers.py +328 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/unknown_fields_test.py +231 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/wire_format.py +268 -0
- data/ext/protoc/protobuf/python/google/protobuf/internal/wire_format_test.py +253 -0
- data/ext/protoc/protobuf/python/google/protobuf/message.py +284 -0
- data/ext/protoc/protobuf/python/google/protobuf/message_factory.py +155 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/README +6 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/__init__.py +0 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/cpp_message.py +61 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/descriptor.cc +357 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/descriptor.h +96 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/descriptor_cpp2_test.py +58 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/extension_dict.cc +338 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/extension_dict.h +123 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/message.cc +2561 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/message.h +305 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/message_factory_cpp2_test.py +56 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/proto2_api_test.proto +38 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/python.proto +66 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/python_protobuf.h +57 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/reflection_cpp2_generated_test.py +94 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/repeated_composite_container.cc +763 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/repeated_composite_container.h +172 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/repeated_scalar_container.cc +825 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/repeated_scalar_container.h +112 -0
- data/ext/protoc/protobuf/python/google/protobuf/pyext/scoped_pyobject_ptr.h +95 -0
- data/ext/protoc/protobuf/python/google/protobuf/reflection.py +205 -0
- data/ext/protoc/protobuf/python/google/protobuf/service.py +226 -0
- data/ext/protoc/protobuf/python/google/protobuf/service_reflection.py +284 -0
- data/ext/protoc/protobuf/python/google/protobuf/symbol_database.py +185 -0
- data/ext/protoc/protobuf/python/google/protobuf/text_encoding.py +110 -0
- data/ext/protoc/protobuf/python/google/protobuf/text_format.py +873 -0
- data/ext/protoc/protobuf/python/mox.py +1401 -0
- data/ext/protoc/protobuf/python/setup.py +201 -0
- data/ext/protoc/protobuf/python/stubout.py +140 -0
- data/ext/protoc/protobuf/src/Makefile.am +418 -0
- data/ext/protoc/protobuf/src/google/protobuf/SEBS +240 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/code_generator.cc +84 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/code_generator.h +145 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/command_line_interface.cc +1603 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/command_line_interface.h +378 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc +1654 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +158 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc +288 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.h +103 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +431 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.h +122 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.cc +210 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.h +86 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_field.cc +166 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_field.h +185 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc +665 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_file.h +99 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc +125 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h +72 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc +494 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h +206 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc +2645 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_message.h +175 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc +375 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.h +121 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_options.h +58 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc +123 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +451 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.h +123 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_service.cc +334 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_service.h +118 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc +642 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.h +127 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto +132 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc +2074 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.h +51 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/importer.cc +480 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/importer.h +317 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/importer_unittest.cc +617 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_context.cc +195 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_context.h +95 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_doc_comment.cc +233 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_doc_comment.h +69 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc +67 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_enum.cc +333 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_enum.h +99 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc +778 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_enum_field.h +158 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_extension.cc +207 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_extension.h +109 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_field.cc +213 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_field.h +162 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_file.cc +534 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_file.h +115 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_generator.cc +158 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_generator.h +72 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_generator_factory.cc +77 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_generator_factory.h +101 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_helpers.cc +737 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_helpers.h +322 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_lazy_message_field.cc +826 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_lazy_message_field.h +121 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_message.cc +1666 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_message.h +140 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_message_field.cc +1343 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_message_field.h +173 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_name_resolver.cc +266 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_name_resolver.h +124 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc +124 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc +877 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h +160 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_service.cc +473 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_service.h +135 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.cc +201 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.h +90 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_string_field.cc +1056 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/java/java_string_field.h +160 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/main.cc +61 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/mock_code_generator.cc +240 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/mock_code_generator.h +117 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/package_info.h +64 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/parser.cc +1750 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/parser.h +522 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/parser_unittest.cc +2612 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/plugin.cc +163 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/plugin.h +72 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/plugin.pb.cc +1148 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/plugin.pb.h +897 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/plugin.proto +147 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/python/python_generator.cc +1262 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/python/python_generator.h +166 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc +118 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/subprocess.cc +463 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/subprocess.h +108 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/test_plugin.cc +51 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/zip_output_unittest.sh +91 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/zip_writer.cc +218 -0
- data/ext/protoc/protobuf/src/google/protobuf/compiler/zip_writer.h +93 -0
- data/ext/protoc/protobuf/src/google/protobuf/descriptor.cc +5420 -0
- data/ext/protoc/protobuf/src/google/protobuf/descriptor.h +1691 -0
- data/ext/protoc/protobuf/src/google/protobuf/descriptor.pb.cc +9135 -0
- data/ext/protoc/protobuf/src/google/protobuf/descriptor.pb.h +6761 -0
- data/ext/protoc/protobuf/src/google/protobuf/descriptor.proto +687 -0
- data/ext/protoc/protobuf/src/google/protobuf/descriptor_database.cc +543 -0
- data/ext/protoc/protobuf/src/google/protobuf/descriptor_database.h +369 -0
- data/ext/protoc/protobuf/src/google/protobuf/descriptor_database_unittest.cc +748 -0
- data/ext/protoc/protobuf/src/google/protobuf/descriptor_pb2_test.py +54 -0
- data/ext/protoc/protobuf/src/google/protobuf/descriptor_unittest.cc +5501 -0
- data/ext/protoc/protobuf/src/google/protobuf/dynamic_message.cc +764 -0
- data/ext/protoc/protobuf/src/google/protobuf/dynamic_message.h +148 -0
- data/ext/protoc/protobuf/src/google/protobuf/dynamic_message_unittest.cc +230 -0
- data/ext/protoc/protobuf/src/google/protobuf/extension_set.cc +1663 -0
- data/ext/protoc/protobuf/src/google/protobuf/extension_set.h +1234 -0
- data/ext/protoc/protobuf/src/google/protobuf/extension_set_heavy.cc +734 -0
- data/ext/protoc/protobuf/src/google/protobuf/extension_set_unittest.cc +1095 -0
- data/ext/protoc/protobuf/src/google/protobuf/generated_enum_reflection.h +91 -0
- data/ext/protoc/protobuf/src/google/protobuf/generated_message_reflection.cc +1683 -0
- data/ext/protoc/protobuf/src/google/protobuf/generated_message_reflection.h +504 -0
- data/ext/protoc/protobuf/src/google/protobuf/generated_message_reflection_unittest.cc +795 -0
- data/ext/protoc/protobuf/src/google/protobuf/generated_message_util.cc +65 -0
- data/ext/protoc/protobuf/src/google/protobuf/generated_message_util.h +113 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/coded_stream.cc +914 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/coded_stream.h +1220 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/coded_stream_inl.h +69 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/coded_stream_unittest.cc +1378 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/gzip_stream.cc +326 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/gzip_stream.h +209 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/gzip_stream_unittest.sh +44 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/package_info.h +54 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/printer.cc +198 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/printer.h +136 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/printer_unittest.cc +285 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/strtod.cc +113 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/strtod.h +50 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/tokenizer.cc +1127 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/tokenizer.h +402 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/tokenizer_unittest.cc +999 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/zero_copy_stream.cc +57 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/zero_copy_stream.h +248 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc +473 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h +358 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc +405 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h +354 -0
- data/ext/protoc/protobuf/src/google/protobuf/io/zero_copy_stream_unittest.cc +965 -0
- data/ext/protoc/protobuf/src/google/protobuf/lite_unittest.cc +350 -0
- data/ext/protoc/protobuf/src/google/protobuf/message.cc +358 -0
- data/ext/protoc/protobuf/src/google/protobuf/message.h +866 -0
- data/ext/protoc/protobuf/src/google/protobuf/message_lite.cc +335 -0
- data/ext/protoc/protobuf/src/google/protobuf/message_lite.h +247 -0
- data/ext/protoc/protobuf/src/google/protobuf/message_unittest.cc +427 -0
- data/ext/protoc/protobuf/src/google/protobuf/package_info.h +64 -0
- data/ext/protoc/protobuf/src/google/protobuf/reflection_ops.cc +269 -0
- data/ext/protoc/protobuf/src/google/protobuf/reflection_ops.h +81 -0
- data/ext/protoc/protobuf/src/google/protobuf/reflection_ops_unittest.cc +475 -0
- data/ext/protoc/protobuf/src/google/protobuf/repeated_field.cc +87 -0
- data/ext/protoc/protobuf/src/google/protobuf/repeated_field.h +1603 -0
- data/ext/protoc/protobuf/src/google/protobuf/repeated_field_reflection_unittest.cc +195 -0
- data/ext/protoc/protobuf/src/google/protobuf/repeated_field_unittest.cc +1442 -0
- data/ext/protoc/protobuf/src/google/protobuf/service.cc +46 -0
- data/ext/protoc/protobuf/src/google/protobuf/service.h +291 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops.h +227 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h +325 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h +151 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h +146 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h +122 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h +137 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_macosx.h +225 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h +313 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_pnacl.h +73 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_solaris.h +188 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_tsan.h +219 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc +137 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h +293 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc +112 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h +150 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/common.cc +395 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/common.h +1226 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/common_unittest.cc +357 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/hash.h +232 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/map_util.h +771 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/once.cc +99 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/once.h +166 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/once_unittest.cc +253 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/platform_macros.h +103 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/shared_ptr.h +470 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/stl_util.h +121 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/stringprintf.cc +175 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/stringprintf.h +76 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/stringprintf_unittest.cc +152 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/structurally_valid.cc +536 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/structurally_valid_unittest.cc +40 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/strutil.cc +1279 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/strutil.h +562 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/strutil_unittest.cc +73 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/substitute.cc +134 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/substitute.h +170 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/template_util.h +138 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/template_util_unittest.cc +130 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/type_traits.h +336 -0
- data/ext/protoc/protobuf/src/google/protobuf/stubs/type_traits_unittest.cc +628 -0
- data/ext/protoc/protobuf/src/google/protobuf/test_util.cc +3345 -0
- data/ext/protoc/protobuf/src/google/protobuf/test_util.h +215 -0
- data/ext/protoc/protobuf/src/google/protobuf/test_util_lite.cc +1585 -0
- data/ext/protoc/protobuf/src/google/protobuf/test_util_lite.h +101 -0
- data/ext/protoc/protobuf/src/google/protobuf/testdata/bad_utf8_string +1 -0
- data/ext/protoc/protobuf/src/google/protobuf/testdata/golden_message +0 -0
- data/ext/protoc/protobuf/src/google/protobuf/testdata/golden_message_oneof_implemented +0 -0
- data/ext/protoc/protobuf/src/google/protobuf/testdata/golden_packed_fields_message +0 -0
- data/ext/protoc/protobuf/src/google/protobuf/testdata/text_format_unittest_data.txt +134 -0
- data/ext/protoc/protobuf/src/google/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt +129 -0
- data/ext/protoc/protobuf/src/google/protobuf/testdata/text_format_unittest_data_pointy.txt +134 -0
- data/ext/protoc/protobuf/src/google/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt +129 -0
- data/ext/protoc/protobuf/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt +134 -0
- data/ext/protoc/protobuf/src/google/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt +134 -0
- data/ext/protoc/protobuf/src/google/protobuf/testing/file.cc +194 -0
- data/ext/protoc/protobuf/src/google/protobuf/testing/file.h +97 -0
- data/ext/protoc/protobuf/src/google/protobuf/testing/googletest.cc +255 -0
- data/ext/protoc/protobuf/src/google/protobuf/testing/googletest.h +102 -0
- data/ext/protoc/protobuf/src/google/protobuf/testing/zcgunzip.cc +73 -0
- data/ext/protoc/protobuf/src/google/protobuf/testing/zcgzip.cc +79 -0
- data/ext/protoc/protobuf/src/google/protobuf/text_format.cc +1746 -0
- data/ext/protoc/protobuf/src/google/protobuf/text_format.h +473 -0
- data/ext/protoc/protobuf/src/google/protobuf/text_format_unittest.cc +1479 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest.proto +861 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest_custom_options.proto +393 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest_embed_optimize_for.proto +50 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest_empty.proto +37 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest_enormous_descriptor.proto +1046 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest_import.proto +64 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest_import_lite.proto +51 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest_import_public.proto +40 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest_import_public_lite.proto +42 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest_lite.proto +384 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest_lite_imports_nonlite.proto +43 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest_mset.proto +83 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest_no_generic_services.proto +53 -0
- data/ext/protoc/protobuf/src/google/protobuf/unittest_optimize_for.proto +66 -0
- data/ext/protoc/protobuf/src/google/protobuf/unknown_field_set.cc +265 -0
- data/ext/protoc/protobuf/src/google/protobuf/unknown_field_set.h +318 -0
- data/ext/protoc/protobuf/src/google/protobuf/unknown_field_set_unittest.cc +599 -0
- data/ext/protoc/protobuf/src/google/protobuf/wire_format.cc +1101 -0
- data/ext/protoc/protobuf/src/google/protobuf/wire_format.h +336 -0
- data/ext/protoc/protobuf/src/google/protobuf/wire_format_lite.cc +471 -0
- data/ext/protoc/protobuf/src/google/protobuf/wire_format_lite.h +661 -0
- data/ext/protoc/protobuf/src/google/protobuf/wire_format_lite_inl.h +860 -0
- data/ext/protoc/protobuf/src/google/protobuf/wire_format_unittest.cc +1120 -0
- data/ext/protoc/protobuf/src/solaris/libstdc++.la +51 -0
- data/ext/protoc/protobuf/vsprojects/config.h +29 -0
- data/ext/protoc/protobuf/vsprojects/convert2008to2005.sh +20 -0
- data/ext/protoc/protobuf/vsprojects/extract_includes.bat +50 -0
- data/ext/protoc/protobuf/vsprojects/libprotobuf-lite.vcproj +302 -0
- data/ext/protoc/protobuf/vsprojects/libprotobuf.vcproj +470 -0
- data/ext/protoc/protobuf/vsprojects/libprotoc.vcproj +466 -0
- data/ext/protoc/protobuf/vsprojects/lite-test.vcproj +305 -0
- data/ext/protoc/protobuf/vsprojects/protobuf.sln +92 -0
- data/ext/protoc/protobuf/vsprojects/protoc.vcproj +192 -0
- data/ext/protoc/protobuf/vsprojects/readme.txt +114 -0
- data/ext/protoc/protobuf/vsprojects/test_plugin.vcproj +209 -0
- data/ext/protoc/protobuf/vsprojects/tests.vcproj +681 -0
- data/lib/protoc/version.rb +1 -1
- metadata +480 -3
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
// Protocol Buffers - Google's data interchange format
|
|
2
|
+
// Copyright 2008 Google Inc. All rights reserved.
|
|
3
|
+
// https://developers.google.com/protocol-buffers/
|
|
4
|
+
//
|
|
5
|
+
// Redistribution and use in source and binary forms, with or without
|
|
6
|
+
// modification, are permitted provided that the following conditions are
|
|
7
|
+
// met:
|
|
8
|
+
//
|
|
9
|
+
// * Redistributions of source code must retain the above copyright
|
|
10
|
+
// notice, this list of conditions and the following disclaimer.
|
|
11
|
+
// * Redistributions in binary form must reproduce the above
|
|
12
|
+
// copyright notice, this list of conditions and the following disclaimer
|
|
13
|
+
// in the documentation and/or other materials provided with the
|
|
14
|
+
// distribution.
|
|
15
|
+
// * Neither the name of Google Inc. nor the names of its
|
|
16
|
+
// contributors may be used to endorse or promote products derived from
|
|
17
|
+
// this software without specific prior written permission.
|
|
18
|
+
//
|
|
19
|
+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
20
|
+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
21
|
+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
22
|
+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
23
|
+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
24
|
+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
25
|
+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
26
|
+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
27
|
+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
28
|
+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
30
|
+
|
|
31
|
+
// Author: kenton@google.com (Kenton Varda)
|
|
32
|
+
// Based on original Protocol Buffers design by
|
|
33
|
+
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
34
|
+
//
|
|
35
|
+
// Class for parsing tokenized text from a ZeroCopyInputStream.
|
|
36
|
+
|
|
37
|
+
#ifndef GOOGLE_PROTOBUF_IO_TOKENIZER_H__
|
|
38
|
+
#define GOOGLE_PROTOBUF_IO_TOKENIZER_H__
|
|
39
|
+
|
|
40
|
+
#include <string>
|
|
41
|
+
#include <vector>
|
|
42
|
+
#include <google/protobuf/stubs/common.h>
|
|
43
|
+
|
|
44
|
+
namespace google {
|
|
45
|
+
namespace protobuf {
|
|
46
|
+
namespace io {
|
|
47
|
+
|
|
48
|
+
class ZeroCopyInputStream; // zero_copy_stream.h
|
|
49
|
+
|
|
50
|
+
// Defined in this file.
|
|
51
|
+
class ErrorCollector;
|
|
52
|
+
class Tokenizer;
|
|
53
|
+
|
|
54
|
+
// Abstract interface for an object which collects the errors that occur
|
|
55
|
+
// during parsing. A typical implementation might simply print the errors
|
|
56
|
+
// to stdout.
|
|
57
|
+
class LIBPROTOBUF_EXPORT ErrorCollector {
|
|
58
|
+
public:
|
|
59
|
+
inline ErrorCollector() {}
|
|
60
|
+
virtual ~ErrorCollector();
|
|
61
|
+
|
|
62
|
+
// Indicates that there was an error in the input at the given line and
|
|
63
|
+
// column numbers. The numbers are zero-based, so you may want to add
|
|
64
|
+
// 1 to each before printing them.
|
|
65
|
+
virtual void AddError(int line, int column, const string& message) = 0;
|
|
66
|
+
|
|
67
|
+
// Indicates that there was a warning in the input at the given line and
|
|
68
|
+
// column numbers. The numbers are zero-based, so you may want to add
|
|
69
|
+
// 1 to each before printing them.
|
|
70
|
+
virtual void AddWarning(int /* line */, int /* column */,
|
|
71
|
+
const string& /* message */) { }
|
|
72
|
+
|
|
73
|
+
private:
|
|
74
|
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// This class converts a stream of raw text into a stream of tokens for
|
|
78
|
+
// the protocol definition parser to parse. The tokens recognized are
|
|
79
|
+
// similar to those that make up the C language; see the TokenType enum for
|
|
80
|
+
// precise descriptions. Whitespace and comments are skipped. By default,
|
|
81
|
+
// C- and C++-style comments are recognized, but other styles can be used by
|
|
82
|
+
// calling set_comment_style().
|
|
83
|
+
class LIBPROTOBUF_EXPORT Tokenizer {
|
|
84
|
+
public:
|
|
85
|
+
// Construct a Tokenizer that reads and tokenizes text from the given
|
|
86
|
+
// input stream and writes errors to the given error_collector.
|
|
87
|
+
// The caller keeps ownership of input and error_collector.
|
|
88
|
+
Tokenizer(ZeroCopyInputStream* input, ErrorCollector* error_collector);
|
|
89
|
+
~Tokenizer();
|
|
90
|
+
|
|
91
|
+
enum TokenType {
|
|
92
|
+
TYPE_START, // Next() has not yet been called.
|
|
93
|
+
TYPE_END, // End of input reached. "text" is empty.
|
|
94
|
+
|
|
95
|
+
TYPE_IDENTIFIER, // A sequence of letters, digits, and underscores, not
|
|
96
|
+
// starting with a digit. It is an error for a number
|
|
97
|
+
// to be followed by an identifier with no space in
|
|
98
|
+
// between.
|
|
99
|
+
TYPE_INTEGER, // A sequence of digits representing an integer. Normally
|
|
100
|
+
// the digits are decimal, but a prefix of "0x" indicates
|
|
101
|
+
// a hex number and a leading zero indicates octal, just
|
|
102
|
+
// like with C numeric literals. A leading negative sign
|
|
103
|
+
// is NOT included in the token; it's up to the parser to
|
|
104
|
+
// interpret the unary minus operator on its own.
|
|
105
|
+
TYPE_FLOAT, // A floating point literal, with a fractional part and/or
|
|
106
|
+
// an exponent. Always in decimal. Again, never
|
|
107
|
+
// negative.
|
|
108
|
+
TYPE_STRING, // A quoted sequence of escaped characters. Either single
|
|
109
|
+
// or double quotes can be used, but they must match.
|
|
110
|
+
// A string literal cannot cross a line break.
|
|
111
|
+
TYPE_SYMBOL, // Any other printable character, like '!' or '+'.
|
|
112
|
+
// Symbols are always a single character, so "!+$%" is
|
|
113
|
+
// four tokens.
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// Structure representing a token read from the token stream.
|
|
117
|
+
struct Token {
|
|
118
|
+
TokenType type;
|
|
119
|
+
string text; // The exact text of the token as it appeared in
|
|
120
|
+
// the input. e.g. tokens of TYPE_STRING will still
|
|
121
|
+
// be escaped and in quotes.
|
|
122
|
+
|
|
123
|
+
// "line" and "column" specify the position of the first character of
|
|
124
|
+
// the token within the input stream. They are zero-based.
|
|
125
|
+
int line;
|
|
126
|
+
int column;
|
|
127
|
+
int end_column;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// Get the current token. This is updated when Next() is called. Before
|
|
131
|
+
// the first call to Next(), current() has type TYPE_START and no contents.
|
|
132
|
+
const Token& current();
|
|
133
|
+
|
|
134
|
+
// Return the previous token -- i.e. what current() returned before the
|
|
135
|
+
// previous call to Next().
|
|
136
|
+
const Token& previous();
|
|
137
|
+
|
|
138
|
+
// Advance to the next token. Returns false if the end of the input is
|
|
139
|
+
// reached.
|
|
140
|
+
bool Next();
|
|
141
|
+
|
|
142
|
+
// Like Next(), but also collects comments which appear between the previous
|
|
143
|
+
// and next tokens.
|
|
144
|
+
//
|
|
145
|
+
// Comments which appear to be attached to the previous token are stored
|
|
146
|
+
// in *prev_tailing_comments. Comments which appear to be attached to the
|
|
147
|
+
// next token are stored in *next_leading_comments. Comments appearing in
|
|
148
|
+
// between which do not appear to be attached to either will be added to
|
|
149
|
+
// detached_comments. Any of these parameters can be NULL to simply discard
|
|
150
|
+
// the comments.
|
|
151
|
+
//
|
|
152
|
+
// A series of line comments appearing on consecutive lines, with no other
|
|
153
|
+
// tokens appearing on those lines, will be treated as a single comment.
|
|
154
|
+
//
|
|
155
|
+
// Only the comment content is returned; comment markers (e.g. //) are
|
|
156
|
+
// stripped out. For block comments, leading whitespace and an asterisk will
|
|
157
|
+
// be stripped from the beginning of each line other than the first. Newlines
|
|
158
|
+
// are included in the output.
|
|
159
|
+
//
|
|
160
|
+
// Examples:
|
|
161
|
+
//
|
|
162
|
+
// optional int32 foo = 1; // Comment attached to foo.
|
|
163
|
+
// // Comment attached to bar.
|
|
164
|
+
// optional int32 bar = 2;
|
|
165
|
+
//
|
|
166
|
+
// optional string baz = 3;
|
|
167
|
+
// // Comment attached to baz.
|
|
168
|
+
// // Another line attached to baz.
|
|
169
|
+
//
|
|
170
|
+
// // Comment attached to qux.
|
|
171
|
+
// //
|
|
172
|
+
// // Another line attached to qux.
|
|
173
|
+
// optional double qux = 4;
|
|
174
|
+
//
|
|
175
|
+
// // Detached comment. This is not attached to qux or corge
|
|
176
|
+
// // because there are blank lines separating it from both.
|
|
177
|
+
//
|
|
178
|
+
// optional string corge = 5;
|
|
179
|
+
// /* Block comment attached
|
|
180
|
+
// * to corge. Leading asterisks
|
|
181
|
+
// * will be removed. */
|
|
182
|
+
// /* Block comment attached to
|
|
183
|
+
// * grault. */
|
|
184
|
+
// optional int32 grault = 6;
|
|
185
|
+
bool NextWithComments(string* prev_trailing_comments,
|
|
186
|
+
vector<string>* detached_comments,
|
|
187
|
+
string* next_leading_comments);
|
|
188
|
+
|
|
189
|
+
// Parse helpers ---------------------------------------------------
|
|
190
|
+
|
|
191
|
+
// Parses a TYPE_FLOAT token. This never fails, so long as the text actually
|
|
192
|
+
// comes from a TYPE_FLOAT token parsed by Tokenizer. If it doesn't, the
|
|
193
|
+
// result is undefined (possibly an assert failure).
|
|
194
|
+
static double ParseFloat(const string& text);
|
|
195
|
+
|
|
196
|
+
// Parses a TYPE_STRING token. This never fails, so long as the text actually
|
|
197
|
+
// comes from a TYPE_STRING token parsed by Tokenizer. If it doesn't, the
|
|
198
|
+
// result is undefined (possibly an assert failure).
|
|
199
|
+
static void ParseString(const string& text, string* output);
|
|
200
|
+
|
|
201
|
+
// Identical to ParseString, but appends to output.
|
|
202
|
+
static void ParseStringAppend(const string& text, string* output);
|
|
203
|
+
|
|
204
|
+
// Parses a TYPE_INTEGER token. Returns false if the result would be
|
|
205
|
+
// greater than max_value. Otherwise, returns true and sets *output to the
|
|
206
|
+
// result. If the text is not from a Token of type TYPE_INTEGER originally
|
|
207
|
+
// parsed by a Tokenizer, the result is undefined (possibly an assert
|
|
208
|
+
// failure).
|
|
209
|
+
static bool ParseInteger(const string& text, uint64 max_value,
|
|
210
|
+
uint64* output);
|
|
211
|
+
|
|
212
|
+
// Options ---------------------------------------------------------
|
|
213
|
+
|
|
214
|
+
// Set true to allow floats to be suffixed with the letter 'f'. Tokens
|
|
215
|
+
// which would otherwise be integers but which have the 'f' suffix will be
|
|
216
|
+
// forced to be interpreted as floats. For all other purposes, the 'f' is
|
|
217
|
+
// ignored.
|
|
218
|
+
void set_allow_f_after_float(bool value) { allow_f_after_float_ = value; }
|
|
219
|
+
|
|
220
|
+
// Valid values for set_comment_style().
|
|
221
|
+
enum CommentStyle {
|
|
222
|
+
// Line comments begin with "//", block comments are delimited by "/*" and
|
|
223
|
+
// "*/".
|
|
224
|
+
CPP_COMMENT_STYLE,
|
|
225
|
+
// Line comments begin with "#". No way to write block comments.
|
|
226
|
+
SH_COMMENT_STYLE
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
// Sets the comment style.
|
|
230
|
+
void set_comment_style(CommentStyle style) { comment_style_ = style; }
|
|
231
|
+
|
|
232
|
+
// Whether to require whitespace between a number and a field name.
|
|
233
|
+
// Default is true. Do not use this; for Google-internal cleanup only.
|
|
234
|
+
void set_require_space_after_number(bool require) {
|
|
235
|
+
require_space_after_number_ = require;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Whether to allow string literals to span multiple lines. Default is false.
|
|
239
|
+
// Do not use this; for Google-internal cleanup only.
|
|
240
|
+
void set_allow_multiline_strings(bool allow) {
|
|
241
|
+
allow_multiline_strings_ = allow;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// External helper: validate an identifier.
|
|
245
|
+
static bool IsIdentifier(const string& text);
|
|
246
|
+
|
|
247
|
+
// -----------------------------------------------------------------
|
|
248
|
+
private:
|
|
249
|
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer);
|
|
250
|
+
|
|
251
|
+
Token current_; // Returned by current().
|
|
252
|
+
Token previous_; // Returned by previous().
|
|
253
|
+
|
|
254
|
+
ZeroCopyInputStream* input_;
|
|
255
|
+
ErrorCollector* error_collector_;
|
|
256
|
+
|
|
257
|
+
char current_char_; // == buffer_[buffer_pos_], updated by NextChar().
|
|
258
|
+
const char* buffer_; // Current buffer returned from input_.
|
|
259
|
+
int buffer_size_; // Size of buffer_.
|
|
260
|
+
int buffer_pos_; // Current position within the buffer.
|
|
261
|
+
bool read_error_; // Did we previously encounter a read error?
|
|
262
|
+
|
|
263
|
+
// Line and column number of current_char_ within the whole input stream.
|
|
264
|
+
int line_;
|
|
265
|
+
int column_;
|
|
266
|
+
|
|
267
|
+
// String to which text should be appended as we advance through it.
|
|
268
|
+
// Call RecordTo(&str) to start recording and StopRecording() to stop.
|
|
269
|
+
// E.g. StartToken() calls RecordTo(¤t_.text). record_start_ is the
|
|
270
|
+
// position within the current buffer where recording started.
|
|
271
|
+
string* record_target_;
|
|
272
|
+
int record_start_;
|
|
273
|
+
|
|
274
|
+
// Options.
|
|
275
|
+
bool allow_f_after_float_;
|
|
276
|
+
CommentStyle comment_style_;
|
|
277
|
+
bool require_space_after_number_;
|
|
278
|
+
bool allow_multiline_strings_;
|
|
279
|
+
|
|
280
|
+
// Since we count columns we need to interpret tabs somehow. We'll take
|
|
281
|
+
// the standard 8-character definition for lack of any way to do better.
|
|
282
|
+
static const int kTabWidth = 8;
|
|
283
|
+
|
|
284
|
+
// -----------------------------------------------------------------
|
|
285
|
+
// Helper methods.
|
|
286
|
+
|
|
287
|
+
// Consume this character and advance to the next one.
|
|
288
|
+
void NextChar();
|
|
289
|
+
|
|
290
|
+
// Read a new buffer from the input.
|
|
291
|
+
void Refresh();
|
|
292
|
+
|
|
293
|
+
inline void RecordTo(string* target);
|
|
294
|
+
inline void StopRecording();
|
|
295
|
+
|
|
296
|
+
// Called when the current character is the first character of a new
|
|
297
|
+
// token (not including whitespace or comments).
|
|
298
|
+
inline void StartToken();
|
|
299
|
+
// Called when the current character is the first character after the
|
|
300
|
+
// end of the last token. After this returns, current_.text will
|
|
301
|
+
// contain all text consumed since StartToken() was called.
|
|
302
|
+
inline void EndToken();
|
|
303
|
+
|
|
304
|
+
// Convenience method to add an error at the current line and column.
|
|
305
|
+
void AddError(const string& message) {
|
|
306
|
+
error_collector_->AddError(line_, column_, message);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// -----------------------------------------------------------------
|
|
310
|
+
// The following four methods are used to consume tokens of specific
|
|
311
|
+
// types. They are actually used to consume all characters *after*
|
|
312
|
+
// the first, since the calling function consumes the first character
|
|
313
|
+
// in order to decide what kind of token is being read.
|
|
314
|
+
|
|
315
|
+
// Read and consume a string, ending when the given delimiter is
|
|
316
|
+
// consumed.
|
|
317
|
+
void ConsumeString(char delimiter);
|
|
318
|
+
|
|
319
|
+
// Read and consume a number, returning TYPE_FLOAT or TYPE_INTEGER
|
|
320
|
+
// depending on what was read. This needs to know if the first
|
|
321
|
+
// character was a zero in order to correctly recognize hex and octal
|
|
322
|
+
// numbers.
|
|
323
|
+
// It also needs to know if the first characted was a . to parse floating
|
|
324
|
+
// point correctly.
|
|
325
|
+
TokenType ConsumeNumber(bool started_with_zero, bool started_with_dot);
|
|
326
|
+
|
|
327
|
+
// Consume the rest of a line.
|
|
328
|
+
void ConsumeLineComment(string* content);
|
|
329
|
+
// Consume until "*/".
|
|
330
|
+
void ConsumeBlockComment(string* content);
|
|
331
|
+
|
|
332
|
+
enum NextCommentStatus {
|
|
333
|
+
// Started a line comment.
|
|
334
|
+
LINE_COMMENT,
|
|
335
|
+
|
|
336
|
+
// Started a block comment.
|
|
337
|
+
BLOCK_COMMENT,
|
|
338
|
+
|
|
339
|
+
// Consumed a slash, then realized it wasn't a comment. current_ has
|
|
340
|
+
// been filled in with a slash token. The caller should return it.
|
|
341
|
+
SLASH_NOT_COMMENT,
|
|
342
|
+
|
|
343
|
+
// We do not appear to be starting a comment here.
|
|
344
|
+
NO_COMMENT
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
// If we're at the start of a new comment, consume it and return what kind
|
|
348
|
+
// of comment it is.
|
|
349
|
+
NextCommentStatus TryConsumeCommentStart();
|
|
350
|
+
|
|
351
|
+
// -----------------------------------------------------------------
|
|
352
|
+
// These helper methods make the parsing code more readable. The
|
|
353
|
+
// "character classes" refered to are defined at the top of the .cc file.
|
|
354
|
+
// Basically it is a C++ class with one method:
|
|
355
|
+
// static bool InClass(char c);
|
|
356
|
+
// The method returns true if c is a member of this "class", like "Letter"
|
|
357
|
+
// or "Digit".
|
|
358
|
+
|
|
359
|
+
// Returns true if the current character is of the given character
|
|
360
|
+
// class, but does not consume anything.
|
|
361
|
+
template<typename CharacterClass>
|
|
362
|
+
inline bool LookingAt();
|
|
363
|
+
|
|
364
|
+
// If the current character is in the given class, consume it and return
|
|
365
|
+
// true. Otherwise return false.
|
|
366
|
+
// e.g. TryConsumeOne<Letter>()
|
|
367
|
+
template<typename CharacterClass>
|
|
368
|
+
inline bool TryConsumeOne();
|
|
369
|
+
|
|
370
|
+
// Like above, but try to consume the specific character indicated.
|
|
371
|
+
inline bool TryConsume(char c);
|
|
372
|
+
|
|
373
|
+
// Consume zero or more of the given character class.
|
|
374
|
+
template<typename CharacterClass>
|
|
375
|
+
inline void ConsumeZeroOrMore();
|
|
376
|
+
|
|
377
|
+
// Consume one or more of the given character class or log the given
|
|
378
|
+
// error message.
|
|
379
|
+
// e.g. ConsumeOneOrMore<Digit>("Expected digits.");
|
|
380
|
+
template<typename CharacterClass>
|
|
381
|
+
inline void ConsumeOneOrMore(const char* error);
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
// inline methods ====================================================
|
|
385
|
+
inline const Tokenizer::Token& Tokenizer::current() {
|
|
386
|
+
return current_;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
inline const Tokenizer::Token& Tokenizer::previous() {
|
|
390
|
+
return previous_;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
inline void Tokenizer::ParseString(const string& text, string* output) {
|
|
394
|
+
output->clear();
|
|
395
|
+
ParseStringAppend(text, output);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
} // namespace io
|
|
399
|
+
} // namespace protobuf
|
|
400
|
+
|
|
401
|
+
} // namespace google
|
|
402
|
+
#endif // GOOGLE_PROTOBUF_IO_TOKENIZER_H__
|
|
@@ -0,0 +1,999 @@
|
|
|
1
|
+
// Protocol Buffers - Google's data interchange format
|
|
2
|
+
// Copyright 2008 Google Inc. All rights reserved.
|
|
3
|
+
// https://developers.google.com/protocol-buffers/
|
|
4
|
+
//
|
|
5
|
+
// Redistribution and use in source and binary forms, with or without
|
|
6
|
+
// modification, are permitted provided that the following conditions are
|
|
7
|
+
// met:
|
|
8
|
+
//
|
|
9
|
+
// * Redistributions of source code must retain the above copyright
|
|
10
|
+
// notice, this list of conditions and the following disclaimer.
|
|
11
|
+
// * Redistributions in binary form must reproduce the above
|
|
12
|
+
// copyright notice, this list of conditions and the following disclaimer
|
|
13
|
+
// in the documentation and/or other materials provided with the
|
|
14
|
+
// distribution.
|
|
15
|
+
// * Neither the name of Google Inc. nor the names of its
|
|
16
|
+
// contributors may be used to endorse or promote products derived from
|
|
17
|
+
// this software without specific prior written permission.
|
|
18
|
+
//
|
|
19
|
+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
20
|
+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
21
|
+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
22
|
+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
23
|
+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
24
|
+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
25
|
+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
26
|
+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
27
|
+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
28
|
+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
30
|
+
|
|
31
|
+
// Author: kenton@google.com (Kenton Varda)
|
|
32
|
+
// Based on original Protocol Buffers design by
|
|
33
|
+
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
34
|
+
|
|
35
|
+
#include <limits.h>
|
|
36
|
+
#include <math.h>
|
|
37
|
+
|
|
38
|
+
#include <vector>
|
|
39
|
+
|
|
40
|
+
#include <google/protobuf/io/tokenizer.h>
|
|
41
|
+
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
|
42
|
+
|
|
43
|
+
#include <google/protobuf/stubs/common.h>
|
|
44
|
+
#include <google/protobuf/stubs/strutil.h>
|
|
45
|
+
#include <google/protobuf/stubs/substitute.h>
|
|
46
|
+
#include <google/protobuf/testing/googletest.h>
|
|
47
|
+
#include <gtest/gtest.h>
|
|
48
|
+
|
|
49
|
+
namespace google {
|
|
50
|
+
namespace protobuf {
|
|
51
|
+
namespace io {
|
|
52
|
+
namespace {
|
|
53
|
+
|
|
54
|
+
// ===================================================================
|
|
55
|
+
// Data-Driven Test Infrastructure
|
|
56
|
+
|
|
57
|
+
// TODO(kenton): This is copied from coded_stream_unittest. This is
|
|
58
|
+
// temporary until these fetaures are integrated into gTest itself.
|
|
59
|
+
|
|
60
|
+
// TEST_1D and TEST_2D are macros I'd eventually like to see added to
|
|
61
|
+
// gTest. These macros can be used to declare tests which should be
|
|
62
|
+
// run multiple times, once for each item in some input array. TEST_1D
|
|
63
|
+
// tests all cases in a single input array. TEST_2D tests all
|
|
64
|
+
// combinations of cases from two arrays. The arrays must be statically
|
|
65
|
+
// defined such that the GOOGLE_ARRAYSIZE() macro works on them. Example:
|
|
66
|
+
//
|
|
67
|
+
// int kCases[] = {1, 2, 3, 4}
|
|
68
|
+
// TEST_1D(MyFixture, MyTest, kCases) {
|
|
69
|
+
// EXPECT_GT(kCases_case, 0);
|
|
70
|
+
// }
|
|
71
|
+
//
|
|
72
|
+
// This test iterates through the numbers 1, 2, 3, and 4 and tests that
|
|
73
|
+
// they are all grater than zero. In case of failure, the exact case
|
|
74
|
+
// which failed will be printed. The case type must be printable using
|
|
75
|
+
// ostream::operator<<.
|
|
76
|
+
|
|
77
|
+
#define TEST_1D(FIXTURE, NAME, CASES) \
|
|
78
|
+
class FIXTURE##_##NAME##_DD : public FIXTURE { \
|
|
79
|
+
protected: \
|
|
80
|
+
template <typename CaseType> \
|
|
81
|
+
void DoSingleCase(const CaseType& CASES##_case); \
|
|
82
|
+
}; \
|
|
83
|
+
\
|
|
84
|
+
TEST_F(FIXTURE##_##NAME##_DD, NAME) { \
|
|
85
|
+
for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) { \
|
|
86
|
+
SCOPED_TRACE(testing::Message() \
|
|
87
|
+
<< #CASES " case #" << i << ": " << CASES[i]); \
|
|
88
|
+
DoSingleCase(CASES[i]); \
|
|
89
|
+
} \
|
|
90
|
+
} \
|
|
91
|
+
\
|
|
92
|
+
template <typename CaseType> \
|
|
93
|
+
void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case)
|
|
94
|
+
|
|
95
|
+
#define TEST_2D(FIXTURE, NAME, CASES1, CASES2) \
|
|
96
|
+
class FIXTURE##_##NAME##_DD : public FIXTURE { \
|
|
97
|
+
protected: \
|
|
98
|
+
template <typename CaseType1, typename CaseType2> \
|
|
99
|
+
void DoSingleCase(const CaseType1& CASES1##_case, \
|
|
100
|
+
const CaseType2& CASES2##_case); \
|
|
101
|
+
}; \
|
|
102
|
+
\
|
|
103
|
+
TEST_F(FIXTURE##_##NAME##_DD, NAME) { \
|
|
104
|
+
for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) { \
|
|
105
|
+
for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) { \
|
|
106
|
+
SCOPED_TRACE(testing::Message() \
|
|
107
|
+
<< #CASES1 " case #" << i << ": " << CASES1[i] << ", " \
|
|
108
|
+
<< #CASES2 " case #" << j << ": " << CASES2[j]); \
|
|
109
|
+
DoSingleCase(CASES1[i], CASES2[j]); \
|
|
110
|
+
} \
|
|
111
|
+
} \
|
|
112
|
+
} \
|
|
113
|
+
\
|
|
114
|
+
template <typename CaseType1, typename CaseType2> \
|
|
115
|
+
void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \
|
|
116
|
+
const CaseType2& CASES2##_case)
|
|
117
|
+
|
|
118
|
+
// -------------------------------------------------------------------
|
|
119
|
+
|
|
120
|
+
// An input stream that is basically like an ArrayInputStream but sometimes
|
|
121
|
+
// returns empty buffers, just to throw us off.
|
|
122
|
+
class TestInputStream : public ZeroCopyInputStream {
|
|
123
|
+
public:
|
|
124
|
+
TestInputStream(const void* data, int size, int block_size)
|
|
125
|
+
: array_stream_(data, size, block_size), counter_(0) {}
|
|
126
|
+
~TestInputStream() {}
|
|
127
|
+
|
|
128
|
+
// implements ZeroCopyInputStream ----------------------------------
|
|
129
|
+
bool Next(const void** data, int* size) {
|
|
130
|
+
// We'll return empty buffers starting with the first buffer, and every
|
|
131
|
+
// 3 and 5 buffers after that.
|
|
132
|
+
if (counter_ % 3 == 0 || counter_ % 5 == 0) {
|
|
133
|
+
*data = NULL;
|
|
134
|
+
*size = 0;
|
|
135
|
+
++counter_;
|
|
136
|
+
return true;
|
|
137
|
+
} else {
|
|
138
|
+
++counter_;
|
|
139
|
+
return array_stream_.Next(data, size);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
void BackUp(int count) { return array_stream_.BackUp(count); }
|
|
144
|
+
bool Skip(int count) { return array_stream_.Skip(count); }
|
|
145
|
+
int64 ByteCount() const { return array_stream_.ByteCount(); }
|
|
146
|
+
|
|
147
|
+
private:
|
|
148
|
+
ArrayInputStream array_stream_;
|
|
149
|
+
int counter_;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// -------------------------------------------------------------------
|
|
153
|
+
|
|
154
|
+
// An error collector which simply concatenates all its errors into a big
|
|
155
|
+
// block of text which can be checked.
|
|
156
|
+
class TestErrorCollector : public ErrorCollector {
|
|
157
|
+
public:
|
|
158
|
+
TestErrorCollector() {}
|
|
159
|
+
~TestErrorCollector() {}
|
|
160
|
+
|
|
161
|
+
string text_;
|
|
162
|
+
|
|
163
|
+
// implements ErrorCollector ---------------------------------------
|
|
164
|
+
void AddError(int line, int column, const string& message) {
|
|
165
|
+
strings::SubstituteAndAppend(&text_, "$0:$1: $2\n",
|
|
166
|
+
line, column, message);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// -------------------------------------------------------------------
|
|
171
|
+
|
|
172
|
+
// We test each operation over a variety of block sizes to insure that
|
|
173
|
+
// we test cases where reads cross buffer boundaries as well as cases
|
|
174
|
+
// where they don't. This is sort of a brute-force approach to this,
|
|
175
|
+
// but it's easy to write and easy to understand.
|
|
176
|
+
const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024};
|
|
177
|
+
|
|
178
|
+
class TokenizerTest : public testing::Test {
|
|
179
|
+
protected:
|
|
180
|
+
// For easy testing.
|
|
181
|
+
uint64 ParseInteger(const string& text) {
|
|
182
|
+
uint64 result;
|
|
183
|
+
EXPECT_TRUE(Tokenizer::ParseInteger(text, kuint64max, &result));
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// ===================================================================
|
|
189
|
+
|
|
190
|
+
// These tests causes gcc 3.3.5 (and earlier?) to give the cryptic error:
|
|
191
|
+
// "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
|
|
192
|
+
#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
|
|
193
|
+
|
|
194
|
+
// In each test case, the entire input text should parse as a single token
|
|
195
|
+
// of the given type.
|
|
196
|
+
struct SimpleTokenCase {
|
|
197
|
+
string input;
|
|
198
|
+
Tokenizer::TokenType type;
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
inline ostream& operator<<(ostream& out,
|
|
202
|
+
const SimpleTokenCase& test_case) {
|
|
203
|
+
return out << CEscape(test_case.input);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
SimpleTokenCase kSimpleTokenCases[] = {
|
|
207
|
+
// Test identifiers.
|
|
208
|
+
{ "hello", Tokenizer::TYPE_IDENTIFIER },
|
|
209
|
+
|
|
210
|
+
// Test integers.
|
|
211
|
+
{ "123", Tokenizer::TYPE_INTEGER },
|
|
212
|
+
{ "0xab6", Tokenizer::TYPE_INTEGER },
|
|
213
|
+
{ "0XAB6", Tokenizer::TYPE_INTEGER },
|
|
214
|
+
{ "0X1234567", Tokenizer::TYPE_INTEGER },
|
|
215
|
+
{ "0x89abcdef", Tokenizer::TYPE_INTEGER },
|
|
216
|
+
{ "0x89ABCDEF", Tokenizer::TYPE_INTEGER },
|
|
217
|
+
{ "01234567", Tokenizer::TYPE_INTEGER },
|
|
218
|
+
|
|
219
|
+
// Test floats.
|
|
220
|
+
{ "123.45", Tokenizer::TYPE_FLOAT },
|
|
221
|
+
{ "1.", Tokenizer::TYPE_FLOAT },
|
|
222
|
+
{ "1e3", Tokenizer::TYPE_FLOAT },
|
|
223
|
+
{ "1E3", Tokenizer::TYPE_FLOAT },
|
|
224
|
+
{ "1e-3", Tokenizer::TYPE_FLOAT },
|
|
225
|
+
{ "1e+3", Tokenizer::TYPE_FLOAT },
|
|
226
|
+
{ "1.e3", Tokenizer::TYPE_FLOAT },
|
|
227
|
+
{ "1.2e3", Tokenizer::TYPE_FLOAT },
|
|
228
|
+
{ ".1", Tokenizer::TYPE_FLOAT },
|
|
229
|
+
{ ".1e3", Tokenizer::TYPE_FLOAT },
|
|
230
|
+
{ ".1e-3", Tokenizer::TYPE_FLOAT },
|
|
231
|
+
{ ".1e+3", Tokenizer::TYPE_FLOAT },
|
|
232
|
+
|
|
233
|
+
// Test strings.
|
|
234
|
+
{ "'hello'", Tokenizer::TYPE_STRING },
|
|
235
|
+
{ "\"foo\"", Tokenizer::TYPE_STRING },
|
|
236
|
+
{ "'a\"b'", Tokenizer::TYPE_STRING },
|
|
237
|
+
{ "\"a'b\"", Tokenizer::TYPE_STRING },
|
|
238
|
+
{ "'a\\'b'", Tokenizer::TYPE_STRING },
|
|
239
|
+
{ "\"a\\\"b\"", Tokenizer::TYPE_STRING },
|
|
240
|
+
{ "'\\xf'", Tokenizer::TYPE_STRING },
|
|
241
|
+
{ "'\\0'", Tokenizer::TYPE_STRING },
|
|
242
|
+
|
|
243
|
+
// Test symbols.
|
|
244
|
+
{ "+", Tokenizer::TYPE_SYMBOL },
|
|
245
|
+
{ ".", Tokenizer::TYPE_SYMBOL },
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) {
|
|
249
|
+
// Set up the tokenizer.
|
|
250
|
+
TestInputStream input(kSimpleTokenCases_case.input.data(),
|
|
251
|
+
kSimpleTokenCases_case.input.size(),
|
|
252
|
+
kBlockSizes_case);
|
|
253
|
+
TestErrorCollector error_collector;
|
|
254
|
+
Tokenizer tokenizer(&input, &error_collector);
|
|
255
|
+
|
|
256
|
+
// Before Next() is called, the initial token should always be TYPE_START.
|
|
257
|
+
EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type);
|
|
258
|
+
EXPECT_EQ("", tokenizer.current().text);
|
|
259
|
+
EXPECT_EQ(0, tokenizer.current().line);
|
|
260
|
+
EXPECT_EQ(0, tokenizer.current().column);
|
|
261
|
+
EXPECT_EQ(0, tokenizer.current().end_column);
|
|
262
|
+
|
|
263
|
+
// Parse the token.
|
|
264
|
+
ASSERT_TRUE(tokenizer.Next());
|
|
265
|
+
|
|
266
|
+
// Check that it has the right type.
|
|
267
|
+
EXPECT_EQ(kSimpleTokenCases_case.type, tokenizer.current().type);
|
|
268
|
+
// Check that it contains the complete input text.
|
|
269
|
+
EXPECT_EQ(kSimpleTokenCases_case.input, tokenizer.current().text);
|
|
270
|
+
// Check that it is located at the beginning of the input
|
|
271
|
+
EXPECT_EQ(0, tokenizer.current().line);
|
|
272
|
+
EXPECT_EQ(0, tokenizer.current().column);
|
|
273
|
+
EXPECT_EQ(kSimpleTokenCases_case.input.size(),
|
|
274
|
+
tokenizer.current().end_column);
|
|
275
|
+
|
|
276
|
+
// There should be no more input.
|
|
277
|
+
EXPECT_FALSE(tokenizer.Next());
|
|
278
|
+
|
|
279
|
+
// After Next() returns false, the token should have type TYPE_END.
|
|
280
|
+
EXPECT_EQ(Tokenizer::TYPE_END, tokenizer.current().type);
|
|
281
|
+
EXPECT_EQ("", tokenizer.current().text);
|
|
282
|
+
EXPECT_EQ(0, tokenizer.current().line);
|
|
283
|
+
EXPECT_EQ(kSimpleTokenCases_case.input.size(), tokenizer.current().column);
|
|
284
|
+
EXPECT_EQ(kSimpleTokenCases_case.input.size(),
|
|
285
|
+
tokenizer.current().end_column);
|
|
286
|
+
|
|
287
|
+
// There should be no errors.
|
|
288
|
+
EXPECT_TRUE(error_collector.text_.empty());
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
TEST_1D(TokenizerTest, FloatSuffix, kBlockSizes) {
|
|
292
|
+
// Test the "allow_f_after_float" option.
|
|
293
|
+
|
|
294
|
+
// Set up the tokenizer.
|
|
295
|
+
const char* text = "1f 2.5f 6e3f 7F";
|
|
296
|
+
TestInputStream input(text, strlen(text), kBlockSizes_case);
|
|
297
|
+
TestErrorCollector error_collector;
|
|
298
|
+
Tokenizer tokenizer(&input, &error_collector);
|
|
299
|
+
tokenizer.set_allow_f_after_float(true);
|
|
300
|
+
|
|
301
|
+
// Advance through tokens and check that they are parsed as expected.
|
|
302
|
+
ASSERT_TRUE(tokenizer.Next());
|
|
303
|
+
EXPECT_EQ(tokenizer.current().text, "1f");
|
|
304
|
+
EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
|
|
305
|
+
ASSERT_TRUE(tokenizer.Next());
|
|
306
|
+
EXPECT_EQ(tokenizer.current().text, "2.5f");
|
|
307
|
+
EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
|
|
308
|
+
ASSERT_TRUE(tokenizer.Next());
|
|
309
|
+
EXPECT_EQ(tokenizer.current().text, "6e3f");
|
|
310
|
+
EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
|
|
311
|
+
ASSERT_TRUE(tokenizer.Next());
|
|
312
|
+
EXPECT_EQ(tokenizer.current().text, "7F");
|
|
313
|
+
EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
|
|
314
|
+
|
|
315
|
+
// There should be no more input.
|
|
316
|
+
EXPECT_FALSE(tokenizer.Next());
|
|
317
|
+
// There should be no errors.
|
|
318
|
+
EXPECT_TRUE(error_collector.text_.empty());
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
#endif
|
|
322
|
+
|
|
323
|
+
// -------------------------------------------------------------------
|
|
324
|
+
|
|
325
|
+
// In each case, the input is parsed to produce a list of tokens. The
|
|
326
|
+
// last token in "output" must have type TYPE_END.
|
|
327
|
+
struct MultiTokenCase {
|
|
328
|
+
string input;
|
|
329
|
+
Tokenizer::Token output[10]; // The compiler wants a constant array
|
|
330
|
+
// size for initialization to work. There
|
|
331
|
+
// is no reason this can't be increased if
|
|
332
|
+
// needed.
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
inline ostream& operator<<(ostream& out,
|
|
336
|
+
const MultiTokenCase& test_case) {
|
|
337
|
+
return out << CEscape(test_case.input);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
MultiTokenCase kMultiTokenCases[] = {
|
|
341
|
+
// Test empty input.
|
|
342
|
+
{ "", {
|
|
343
|
+
{ Tokenizer::TYPE_END , "" , 0, 0 },
|
|
344
|
+
}},
|
|
345
|
+
|
|
346
|
+
// Test all token types at the same time.
|
|
347
|
+
{ "foo 1 1.2 + 'bar'", {
|
|
348
|
+
{ Tokenizer::TYPE_IDENTIFIER, "foo" , 0, 0, 3 },
|
|
349
|
+
{ Tokenizer::TYPE_INTEGER , "1" , 0, 4, 5 },
|
|
350
|
+
{ Tokenizer::TYPE_FLOAT , "1.2" , 0, 6, 9 },
|
|
351
|
+
{ Tokenizer::TYPE_SYMBOL , "+" , 0, 10, 11 },
|
|
352
|
+
{ Tokenizer::TYPE_STRING , "'bar'", 0, 12, 17 },
|
|
353
|
+
{ Tokenizer::TYPE_END , "" , 0, 17, 17 },
|
|
354
|
+
}},
|
|
355
|
+
|
|
356
|
+
// Test that consecutive symbols are parsed as separate tokens.
|
|
357
|
+
{ "!@+%", {
|
|
358
|
+
{ Tokenizer::TYPE_SYMBOL , "!" , 0, 0, 1 },
|
|
359
|
+
{ Tokenizer::TYPE_SYMBOL , "@" , 0, 1, 2 },
|
|
360
|
+
{ Tokenizer::TYPE_SYMBOL , "+" , 0, 2, 3 },
|
|
361
|
+
{ Tokenizer::TYPE_SYMBOL , "%" , 0, 3, 4 },
|
|
362
|
+
{ Tokenizer::TYPE_END , "" , 0, 4, 4 },
|
|
363
|
+
}},
|
|
364
|
+
|
|
365
|
+
// Test that newlines affect line numbers correctly.
|
|
366
|
+
{ "foo bar\nrab oof", {
|
|
367
|
+
{ Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
|
|
368
|
+
{ Tokenizer::TYPE_IDENTIFIER, "bar", 0, 4, 7 },
|
|
369
|
+
{ Tokenizer::TYPE_IDENTIFIER, "rab", 1, 0, 3 },
|
|
370
|
+
{ Tokenizer::TYPE_IDENTIFIER, "oof", 1, 4, 7 },
|
|
371
|
+
{ Tokenizer::TYPE_END , "" , 1, 7, 7 },
|
|
372
|
+
}},
|
|
373
|
+
|
|
374
|
+
// Test that tabs affect column numbers correctly.
|
|
375
|
+
{ "foo\tbar \tbaz", {
|
|
376
|
+
{ Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
|
|
377
|
+
{ Tokenizer::TYPE_IDENTIFIER, "bar", 0, 8, 11 },
|
|
378
|
+
{ Tokenizer::TYPE_IDENTIFIER, "baz", 0, 16, 19 },
|
|
379
|
+
{ Tokenizer::TYPE_END , "" , 0, 19, 19 },
|
|
380
|
+
}},
|
|
381
|
+
|
|
382
|
+
// Test that tabs in string literals affect column numbers correctly.
|
|
383
|
+
{ "\"foo\tbar\" baz", {
|
|
384
|
+
{ Tokenizer::TYPE_STRING , "\"foo\tbar\"", 0, 0, 12 },
|
|
385
|
+
{ Tokenizer::TYPE_IDENTIFIER, "baz" , 0, 13, 16 },
|
|
386
|
+
{ Tokenizer::TYPE_END , "" , 0, 16, 16 },
|
|
387
|
+
}},
|
|
388
|
+
|
|
389
|
+
// Test that line comments are ignored.
|
|
390
|
+
{ "foo // This is a comment\n"
|
|
391
|
+
"bar // This is another comment", {
|
|
392
|
+
{ Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
|
|
393
|
+
{ Tokenizer::TYPE_IDENTIFIER, "bar", 1, 0, 3 },
|
|
394
|
+
{ Tokenizer::TYPE_END , "" , 1, 30, 30 },
|
|
395
|
+
}},
|
|
396
|
+
|
|
397
|
+
// Test that block comments are ignored.
|
|
398
|
+
{ "foo /* This is a block comment */ bar", {
|
|
399
|
+
{ Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
|
|
400
|
+
{ Tokenizer::TYPE_IDENTIFIER, "bar", 0, 34, 37 },
|
|
401
|
+
{ Tokenizer::TYPE_END , "" , 0, 37, 37 },
|
|
402
|
+
}},
|
|
403
|
+
|
|
404
|
+
// Test that sh-style comments are not ignored by default.
|
|
405
|
+
{ "foo # bar\n"
|
|
406
|
+
"baz", {
|
|
407
|
+
{ Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
|
|
408
|
+
{ Tokenizer::TYPE_SYMBOL , "#" , 0, 4, 5 },
|
|
409
|
+
{ Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6, 9 },
|
|
410
|
+
{ Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0, 3 },
|
|
411
|
+
{ Tokenizer::TYPE_END , "" , 1, 3, 3 },
|
|
412
|
+
}},
|
|
413
|
+
|
|
414
|
+
// Test all whitespace chars
|
|
415
|
+
{ "foo\n\t\r\v\fbar", {
|
|
416
|
+
{ Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
|
|
417
|
+
{ Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11, 14 },
|
|
418
|
+
{ Tokenizer::TYPE_END , "" , 1, 14, 14 },
|
|
419
|
+
}},
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) {
|
|
423
|
+
// Set up the tokenizer.
|
|
424
|
+
TestInputStream input(kMultiTokenCases_case.input.data(),
|
|
425
|
+
kMultiTokenCases_case.input.size(),
|
|
426
|
+
kBlockSizes_case);
|
|
427
|
+
TestErrorCollector error_collector;
|
|
428
|
+
Tokenizer tokenizer(&input, &error_collector);
|
|
429
|
+
|
|
430
|
+
// Before Next() is called, the initial token should always be TYPE_START.
|
|
431
|
+
EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type);
|
|
432
|
+
EXPECT_EQ("", tokenizer.current().text);
|
|
433
|
+
EXPECT_EQ(0, tokenizer.current().line);
|
|
434
|
+
EXPECT_EQ(0, tokenizer.current().column);
|
|
435
|
+
EXPECT_EQ(0, tokenizer.current().end_column);
|
|
436
|
+
|
|
437
|
+
// Loop through all expected tokens.
|
|
438
|
+
int i = 0;
|
|
439
|
+
Tokenizer::Token token;
|
|
440
|
+
do {
|
|
441
|
+
token = kMultiTokenCases_case.output[i++];
|
|
442
|
+
|
|
443
|
+
SCOPED_TRACE(testing::Message() << "Token #" << i << ": " << token.text);
|
|
444
|
+
|
|
445
|
+
Tokenizer::Token previous = tokenizer.current();
|
|
446
|
+
|
|
447
|
+
// Next() should only return false when it hits the end token.
|
|
448
|
+
if (token.type != Tokenizer::TYPE_END) {
|
|
449
|
+
ASSERT_TRUE(tokenizer.Next());
|
|
450
|
+
} else {
|
|
451
|
+
ASSERT_FALSE(tokenizer.Next());
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// Check that the previous token is set correctly.
|
|
455
|
+
EXPECT_EQ(previous.type, tokenizer.previous().type);
|
|
456
|
+
EXPECT_EQ(previous.text, tokenizer.previous().text);
|
|
457
|
+
EXPECT_EQ(previous.line, tokenizer.previous().line);
|
|
458
|
+
EXPECT_EQ(previous.column, tokenizer.previous().column);
|
|
459
|
+
EXPECT_EQ(previous.end_column, tokenizer.previous().end_column);
|
|
460
|
+
|
|
461
|
+
// Check that the token matches the expected one.
|
|
462
|
+
EXPECT_EQ(token.type, tokenizer.current().type);
|
|
463
|
+
EXPECT_EQ(token.text, tokenizer.current().text);
|
|
464
|
+
EXPECT_EQ(token.line, tokenizer.current().line);
|
|
465
|
+
EXPECT_EQ(token.column, tokenizer.current().column);
|
|
466
|
+
EXPECT_EQ(token.end_column, tokenizer.current().end_column);
|
|
467
|
+
|
|
468
|
+
} while (token.type != Tokenizer::TYPE_END);
|
|
469
|
+
|
|
470
|
+
// There should be no errors.
|
|
471
|
+
EXPECT_TRUE(error_collector.text_.empty());
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error:
|
|
475
|
+
// "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
|
|
476
|
+
#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
|
|
477
|
+
|
|
478
|
+
TEST_1D(TokenizerTest, ShCommentStyle, kBlockSizes) {
|
|
479
|
+
// Test the "comment_style" option.
|
|
480
|
+
|
|
481
|
+
const char* text = "foo # bar\n"
|
|
482
|
+
"baz // qux\n"
|
|
483
|
+
"corge /* grault */\n"
|
|
484
|
+
"garply";
|
|
485
|
+
const char* const kTokens[] = {"foo", // "# bar" is ignored
|
|
486
|
+
"baz", "/", "/", "qux",
|
|
487
|
+
"corge", "/", "*", "grault", "*", "/",
|
|
488
|
+
"garply"};
|
|
489
|
+
|
|
490
|
+
// Set up the tokenizer.
|
|
491
|
+
TestInputStream input(text, strlen(text), kBlockSizes_case);
|
|
492
|
+
TestErrorCollector error_collector;
|
|
493
|
+
Tokenizer tokenizer(&input, &error_collector);
|
|
494
|
+
tokenizer.set_comment_style(Tokenizer::SH_COMMENT_STYLE);
|
|
495
|
+
|
|
496
|
+
// Advance through tokens and check that they are parsed as expected.
|
|
497
|
+
for (int i = 0; i < GOOGLE_ARRAYSIZE(kTokens); i++) {
|
|
498
|
+
EXPECT_TRUE(tokenizer.Next());
|
|
499
|
+
EXPECT_EQ(tokenizer.current().text, kTokens[i]);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// There should be no more input.
|
|
503
|
+
EXPECT_FALSE(tokenizer.Next());
|
|
504
|
+
// There should be no errors.
|
|
505
|
+
EXPECT_TRUE(error_collector.text_.empty());
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
#endif
|
|
509
|
+
|
|
510
|
+
// -------------------------------------------------------------------
|
|
511
|
+
|
|
512
|
+
// In each case, the input is expected to have two tokens named "prev" and
|
|
513
|
+
// "next" with comments in between.
|
|
514
|
+
struct DocCommentCase {
|
|
515
|
+
string input;
|
|
516
|
+
|
|
517
|
+
const char* prev_trailing_comments;
|
|
518
|
+
const char* detached_comments[10];
|
|
519
|
+
const char* next_leading_comments;
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
inline ostream& operator<<(ostream& out,
|
|
523
|
+
const DocCommentCase& test_case) {
|
|
524
|
+
return out << CEscape(test_case.input);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
DocCommentCase kDocCommentCases[] = {
|
|
528
|
+
{
|
|
529
|
+
"prev next",
|
|
530
|
+
|
|
531
|
+
"",
|
|
532
|
+
{},
|
|
533
|
+
""
|
|
534
|
+
},
|
|
535
|
+
|
|
536
|
+
{
|
|
537
|
+
"prev /* ignored */ next",
|
|
538
|
+
|
|
539
|
+
"",
|
|
540
|
+
{},
|
|
541
|
+
""
|
|
542
|
+
},
|
|
543
|
+
|
|
544
|
+
{
|
|
545
|
+
"prev // trailing comment\n"
|
|
546
|
+
"next",
|
|
547
|
+
|
|
548
|
+
" trailing comment\n",
|
|
549
|
+
{},
|
|
550
|
+
""
|
|
551
|
+
},
|
|
552
|
+
|
|
553
|
+
{
|
|
554
|
+
"prev\n"
|
|
555
|
+
"// leading comment\n"
|
|
556
|
+
"// line 2\n"
|
|
557
|
+
"next",
|
|
558
|
+
|
|
559
|
+
"",
|
|
560
|
+
{},
|
|
561
|
+
" leading comment\n"
|
|
562
|
+
" line 2\n"
|
|
563
|
+
},
|
|
564
|
+
|
|
565
|
+
{
|
|
566
|
+
"prev\n"
|
|
567
|
+
"// trailing comment\n"
|
|
568
|
+
"// line 2\n"
|
|
569
|
+
"\n"
|
|
570
|
+
"next",
|
|
571
|
+
|
|
572
|
+
" trailing comment\n"
|
|
573
|
+
" line 2\n",
|
|
574
|
+
{},
|
|
575
|
+
""
|
|
576
|
+
},
|
|
577
|
+
|
|
578
|
+
{
|
|
579
|
+
"prev // trailing comment\n"
|
|
580
|
+
"// leading comment\n"
|
|
581
|
+
"// line 2\n"
|
|
582
|
+
"next",
|
|
583
|
+
|
|
584
|
+
" trailing comment\n",
|
|
585
|
+
{},
|
|
586
|
+
" leading comment\n"
|
|
587
|
+
" line 2\n"
|
|
588
|
+
},
|
|
589
|
+
|
|
590
|
+
{
|
|
591
|
+
"prev /* trailing block comment */\n"
|
|
592
|
+
"/* leading block comment\n"
|
|
593
|
+
" * line 2\n"
|
|
594
|
+
" * line 3 */"
|
|
595
|
+
"next",
|
|
596
|
+
|
|
597
|
+
" trailing block comment ",
|
|
598
|
+
{},
|
|
599
|
+
" leading block comment\n"
|
|
600
|
+
" line 2\n"
|
|
601
|
+
" line 3 "
|
|
602
|
+
},
|
|
603
|
+
|
|
604
|
+
{
|
|
605
|
+
"prev\n"
|
|
606
|
+
"/* trailing block comment\n"
|
|
607
|
+
" * line 2\n"
|
|
608
|
+
" * line 3\n"
|
|
609
|
+
" */\n"
|
|
610
|
+
"/* leading block comment\n"
|
|
611
|
+
" * line 2\n"
|
|
612
|
+
" * line 3 */"
|
|
613
|
+
"next",
|
|
614
|
+
|
|
615
|
+
" trailing block comment\n"
|
|
616
|
+
" line 2\n"
|
|
617
|
+
" line 3\n",
|
|
618
|
+
{},
|
|
619
|
+
" leading block comment\n"
|
|
620
|
+
" line 2\n"
|
|
621
|
+
" line 3 "
|
|
622
|
+
},
|
|
623
|
+
|
|
624
|
+
{
|
|
625
|
+
"prev\n"
|
|
626
|
+
"// trailing comment\n"
|
|
627
|
+
"\n"
|
|
628
|
+
"// detached comment\n"
|
|
629
|
+
"// line 2\n"
|
|
630
|
+
"\n"
|
|
631
|
+
"// second detached comment\n"
|
|
632
|
+
"/* third detached comment\n"
|
|
633
|
+
" * line 2 */\n"
|
|
634
|
+
"// leading comment\n"
|
|
635
|
+
"next",
|
|
636
|
+
|
|
637
|
+
" trailing comment\n",
|
|
638
|
+
{
|
|
639
|
+
" detached comment\n"
|
|
640
|
+
" line 2\n",
|
|
641
|
+
" second detached comment\n",
|
|
642
|
+
" third detached comment\n"
|
|
643
|
+
" line 2 "
|
|
644
|
+
},
|
|
645
|
+
" leading comment\n"
|
|
646
|
+
},
|
|
647
|
+
|
|
648
|
+
{
|
|
649
|
+
"prev /**/\n"
|
|
650
|
+
"\n"
|
|
651
|
+
"// detached comment\n"
|
|
652
|
+
"\n"
|
|
653
|
+
"// leading comment\n"
|
|
654
|
+
"next",
|
|
655
|
+
|
|
656
|
+
"",
|
|
657
|
+
{
|
|
658
|
+
" detached comment\n"
|
|
659
|
+
},
|
|
660
|
+
" leading comment\n"
|
|
661
|
+
},
|
|
662
|
+
|
|
663
|
+
{
|
|
664
|
+
"prev /**/\n"
|
|
665
|
+
"// leading comment\n"
|
|
666
|
+
"next",
|
|
667
|
+
|
|
668
|
+
"",
|
|
669
|
+
{},
|
|
670
|
+
" leading comment\n"
|
|
671
|
+
},
|
|
672
|
+
};
|
|
673
|
+
|
|
674
|
+
TEST_2D(TokenizerTest, DocComments, kDocCommentCases, kBlockSizes) {
|
|
675
|
+
// Set up the tokenizer.
|
|
676
|
+
TestInputStream input(kDocCommentCases_case.input.data(),
|
|
677
|
+
kDocCommentCases_case.input.size(),
|
|
678
|
+
kBlockSizes_case);
|
|
679
|
+
TestErrorCollector error_collector;
|
|
680
|
+
Tokenizer tokenizer(&input, &error_collector);
|
|
681
|
+
|
|
682
|
+
// Set up a second tokenizer where we'll pass all NULLs to NextWithComments().
|
|
683
|
+
TestInputStream input2(kDocCommentCases_case.input.data(),
|
|
684
|
+
kDocCommentCases_case.input.size(),
|
|
685
|
+
kBlockSizes_case);
|
|
686
|
+
Tokenizer tokenizer2(&input2, &error_collector);
|
|
687
|
+
|
|
688
|
+
tokenizer.Next();
|
|
689
|
+
tokenizer2.Next();
|
|
690
|
+
|
|
691
|
+
EXPECT_EQ("prev", tokenizer.current().text);
|
|
692
|
+
EXPECT_EQ("prev", tokenizer2.current().text);
|
|
693
|
+
|
|
694
|
+
string prev_trailing_comments;
|
|
695
|
+
vector<string> detached_comments;
|
|
696
|
+
string next_leading_comments;
|
|
697
|
+
tokenizer.NextWithComments(&prev_trailing_comments, &detached_comments,
|
|
698
|
+
&next_leading_comments);
|
|
699
|
+
tokenizer2.NextWithComments(NULL, NULL, NULL);
|
|
700
|
+
EXPECT_EQ("next", tokenizer.current().text);
|
|
701
|
+
EXPECT_EQ("next", tokenizer2.current().text);
|
|
702
|
+
|
|
703
|
+
EXPECT_EQ(kDocCommentCases_case.prev_trailing_comments,
|
|
704
|
+
prev_trailing_comments);
|
|
705
|
+
|
|
706
|
+
for (int i = 0; i < detached_comments.size(); i++) {
|
|
707
|
+
ASSERT_LT(i, GOOGLE_ARRAYSIZE(kDocCommentCases));
|
|
708
|
+
ASSERT_TRUE(kDocCommentCases_case.detached_comments[i] != NULL);
|
|
709
|
+
EXPECT_EQ(kDocCommentCases_case.detached_comments[i],
|
|
710
|
+
detached_comments[i]);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// Verify that we matched all the detached comments.
|
|
714
|
+
EXPECT_EQ(NULL,
|
|
715
|
+
kDocCommentCases_case.detached_comments[detached_comments.size()]);
|
|
716
|
+
|
|
717
|
+
EXPECT_EQ(kDocCommentCases_case.next_leading_comments,
|
|
718
|
+
next_leading_comments);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
// -------------------------------------------------------------------
|
|
722
|
+
|
|
723
|
+
// Test parse helpers. It's not really worth setting up a full data-driven
|
|
724
|
+
// test here.
|
|
725
|
+
TEST_F(TokenizerTest, ParseInteger) {
|
|
726
|
+
EXPECT_EQ(0, ParseInteger("0"));
|
|
727
|
+
EXPECT_EQ(123, ParseInteger("123"));
|
|
728
|
+
EXPECT_EQ(0xabcdef12u, ParseInteger("0xabcdef12"));
|
|
729
|
+
EXPECT_EQ(0xabcdef12u, ParseInteger("0xABCDEF12"));
|
|
730
|
+
EXPECT_EQ(kuint64max, ParseInteger("0xFFFFFFFFFFFFFFFF"));
|
|
731
|
+
EXPECT_EQ(01234567, ParseInteger("01234567"));
|
|
732
|
+
EXPECT_EQ(0X123, ParseInteger("0X123"));
|
|
733
|
+
|
|
734
|
+
// Test invalid integers that may still be tokenized as integers.
|
|
735
|
+
EXPECT_EQ(0, ParseInteger("0x"));
|
|
736
|
+
|
|
737
|
+
uint64 i;
|
|
738
|
+
#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet
|
|
739
|
+
// Test invalid integers that will never be tokenized as integers.
|
|
740
|
+
EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("zxy", kuint64max, &i),
|
|
741
|
+
"passed text that could not have been tokenized as an integer");
|
|
742
|
+
EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("1.2", kuint64max, &i),
|
|
743
|
+
"passed text that could not have been tokenized as an integer");
|
|
744
|
+
EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("08", kuint64max, &i),
|
|
745
|
+
"passed text that could not have been tokenized as an integer");
|
|
746
|
+
EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("0xg", kuint64max, &i),
|
|
747
|
+
"passed text that could not have been tokenized as an integer");
|
|
748
|
+
EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("-1", kuint64max, &i),
|
|
749
|
+
"passed text that could not have been tokenized as an integer");
|
|
750
|
+
#endif // PROTOBUF_HAS_DEATH_TEST
|
|
751
|
+
|
|
752
|
+
// Test overflows.
|
|
753
|
+
EXPECT_TRUE (Tokenizer::ParseInteger("0", 0, &i));
|
|
754
|
+
EXPECT_FALSE(Tokenizer::ParseInteger("1", 0, &i));
|
|
755
|
+
EXPECT_TRUE (Tokenizer::ParseInteger("1", 1, &i));
|
|
756
|
+
EXPECT_TRUE (Tokenizer::ParseInteger("12345", 12345, &i));
|
|
757
|
+
EXPECT_FALSE(Tokenizer::ParseInteger("12346", 12345, &i));
|
|
758
|
+
EXPECT_TRUE (Tokenizer::ParseInteger("0xFFFFFFFFFFFFFFFF" , kuint64max, &i));
|
|
759
|
+
EXPECT_FALSE(Tokenizer::ParseInteger("0x10000000000000000", kuint64max, &i));
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
TEST_F(TokenizerTest, ParseFloat) {
|
|
763
|
+
EXPECT_DOUBLE_EQ(1 , Tokenizer::ParseFloat("1."));
|
|
764
|
+
EXPECT_DOUBLE_EQ(1e3 , Tokenizer::ParseFloat("1e3"));
|
|
765
|
+
EXPECT_DOUBLE_EQ(1e3 , Tokenizer::ParseFloat("1E3"));
|
|
766
|
+
EXPECT_DOUBLE_EQ(1.5e3, Tokenizer::ParseFloat("1.5e3"));
|
|
767
|
+
EXPECT_DOUBLE_EQ(.1 , Tokenizer::ParseFloat(".1"));
|
|
768
|
+
EXPECT_DOUBLE_EQ(.25 , Tokenizer::ParseFloat(".25"));
|
|
769
|
+
EXPECT_DOUBLE_EQ(.1e3 , Tokenizer::ParseFloat(".1e3"));
|
|
770
|
+
EXPECT_DOUBLE_EQ(.25e3, Tokenizer::ParseFloat(".25e3"));
|
|
771
|
+
EXPECT_DOUBLE_EQ(.1e+3, Tokenizer::ParseFloat(".1e+3"));
|
|
772
|
+
EXPECT_DOUBLE_EQ(.1e-3, Tokenizer::ParseFloat(".1e-3"));
|
|
773
|
+
EXPECT_DOUBLE_EQ(5 , Tokenizer::ParseFloat("5"));
|
|
774
|
+
EXPECT_DOUBLE_EQ(6e-12, Tokenizer::ParseFloat("6e-12"));
|
|
775
|
+
EXPECT_DOUBLE_EQ(1.2 , Tokenizer::ParseFloat("1.2"));
|
|
776
|
+
EXPECT_DOUBLE_EQ(1.e2 , Tokenizer::ParseFloat("1.e2"));
|
|
777
|
+
|
|
778
|
+
// Test invalid integers that may still be tokenized as integers.
|
|
779
|
+
EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e"));
|
|
780
|
+
EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e-"));
|
|
781
|
+
EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.e"));
|
|
782
|
+
|
|
783
|
+
// Test 'f' suffix.
|
|
784
|
+
EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1f"));
|
|
785
|
+
EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.0f"));
|
|
786
|
+
EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1F"));
|
|
787
|
+
|
|
788
|
+
// These should parse successfully even though they are out of range.
|
|
789
|
+
// Overflows become infinity and underflows become zero.
|
|
790
|
+
EXPECT_EQ( 0.0, Tokenizer::ParseFloat("1e-9999999999999999999999999999"));
|
|
791
|
+
EXPECT_EQ(HUGE_VAL, Tokenizer::ParseFloat("1e+9999999999999999999999999999"));
|
|
792
|
+
|
|
793
|
+
#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet
|
|
794
|
+
// Test invalid integers that will never be tokenized as integers.
|
|
795
|
+
EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("zxy"),
|
|
796
|
+
"passed text that could not have been tokenized as a float");
|
|
797
|
+
EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("1-e0"),
|
|
798
|
+
"passed text that could not have been tokenized as a float");
|
|
799
|
+
EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("-1.0"),
|
|
800
|
+
"passed text that could not have been tokenized as a float");
|
|
801
|
+
#endif // PROTOBUF_HAS_DEATH_TEST
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
TEST_F(TokenizerTest, ParseString) {
|
|
805
|
+
string output;
|
|
806
|
+
Tokenizer::ParseString("'hello'", &output);
|
|
807
|
+
EXPECT_EQ("hello", output);
|
|
808
|
+
Tokenizer::ParseString("\"blah\\nblah2\"", &output);
|
|
809
|
+
EXPECT_EQ("blah\nblah2", output);
|
|
810
|
+
Tokenizer::ParseString("'\\1x\\1\\123\\739\\52\\334n\\3'", &output);
|
|
811
|
+
EXPECT_EQ("\1x\1\123\739\52\334n\3", output);
|
|
812
|
+
Tokenizer::ParseString("'\\x20\\x4'", &output);
|
|
813
|
+
EXPECT_EQ("\x20\x4", output);
|
|
814
|
+
|
|
815
|
+
// Test invalid strings that may still be tokenized as strings.
|
|
816
|
+
Tokenizer::ParseString("\"\\a\\l\\v\\t", &output); // \l is invalid
|
|
817
|
+
EXPECT_EQ("\a?\v\t", output);
|
|
818
|
+
Tokenizer::ParseString("'", &output);
|
|
819
|
+
EXPECT_EQ("", output);
|
|
820
|
+
Tokenizer::ParseString("'\\", &output);
|
|
821
|
+
EXPECT_EQ("\\", output);
|
|
822
|
+
|
|
823
|
+
// Experiment with Unicode escapes. Here are one-, two- and three-byte Unicode
|
|
824
|
+
// characters.
|
|
825
|
+
Tokenizer::ParseString("'\\u0024\\u00a2\\u20ac\\U00024b62XX'", &output);
|
|
826
|
+
EXPECT_EQ("$¢€𤭢XX", output);
|
|
827
|
+
// Same thing encoded using UTF16.
|
|
828
|
+
Tokenizer::ParseString("'\\u0024\\u00a2\\u20ac\\ud852\\udf62XX'", &output);
|
|
829
|
+
EXPECT_EQ("$¢€𤭢XX", output);
|
|
830
|
+
// Here's some broken UTF16; there's a head surrogate with no tail surrogate.
|
|
831
|
+
// We just output this as if it were UTF8; it's not a defined code point, but
|
|
832
|
+
// it has a defined encoding.
|
|
833
|
+
Tokenizer::ParseString("'\\ud852XX'", &output);
|
|
834
|
+
EXPECT_EQ("\xed\xa1\x92XX", output);
|
|
835
|
+
// Malformed escape: Demons may fly out of the nose.
|
|
836
|
+
Tokenizer::ParseString("\\u0", &output);
|
|
837
|
+
EXPECT_EQ("u0", output);
|
|
838
|
+
|
|
839
|
+
// Test invalid strings that will never be tokenized as strings.
|
|
840
|
+
#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet
|
|
841
|
+
EXPECT_DEBUG_DEATH(Tokenizer::ParseString("", &output),
|
|
842
|
+
"passed text that could not have been tokenized as a string");
|
|
843
|
+
#endif // PROTOBUF_HAS_DEATH_TEST
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
TEST_F(TokenizerTest, ParseStringAppend) {
|
|
847
|
+
// Check that ParseString and ParseStringAppend differ.
|
|
848
|
+
string output("stuff+");
|
|
849
|
+
Tokenizer::ParseStringAppend("'hello'", &output);
|
|
850
|
+
EXPECT_EQ("stuff+hello", output);
|
|
851
|
+
Tokenizer::ParseString("'hello'", &output);
|
|
852
|
+
EXPECT_EQ("hello", output);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// -------------------------------------------------------------------
|
|
856
|
+
|
|
857
|
+
// Each case parses some input text, ignoring the tokens produced, and
|
|
858
|
+
// checks that the error output matches what is expected.
|
|
859
|
+
struct ErrorCase {
|
|
860
|
+
string input;
|
|
861
|
+
bool recoverable; // True if the tokenizer should be able to recover and
|
|
862
|
+
// parse more tokens after seeing this error. Cases
|
|
863
|
+
// for which this is true must end with "foo" as
|
|
864
|
+
// the last token, which the test will check for.
|
|
865
|
+
const char* errors;
|
|
866
|
+
};
|
|
867
|
+
|
|
868
|
+
inline ostream& operator<<(ostream& out,
|
|
869
|
+
const ErrorCase& test_case) {
|
|
870
|
+
return out << CEscape(test_case.input);
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
ErrorCase kErrorCases[] = {
|
|
874
|
+
// String errors.
|
|
875
|
+
{ "'\\l' foo", true,
|
|
876
|
+
"0:2: Invalid escape sequence in string literal.\n" },
|
|
877
|
+
{ "'\\x' foo", true,
|
|
878
|
+
"0:3: Expected hex digits for escape sequence.\n" },
|
|
879
|
+
{ "'foo", false,
|
|
880
|
+
"0:4: Unexpected end of string.\n" },
|
|
881
|
+
{ "'bar\nfoo", true,
|
|
882
|
+
"0:4: String literals cannot cross line boundaries.\n" },
|
|
883
|
+
{ "'\\u01' foo", true,
|
|
884
|
+
"0:5: Expected four hex digits for \\u escape sequence.\n" },
|
|
885
|
+
{ "'\\u01' foo", true,
|
|
886
|
+
"0:5: Expected four hex digits for \\u escape sequence.\n" },
|
|
887
|
+
{ "'\\uXYZ' foo", true,
|
|
888
|
+
"0:3: Expected four hex digits for \\u escape sequence.\n" },
|
|
889
|
+
|
|
890
|
+
// Integer errors.
|
|
891
|
+
{ "123foo", true,
|
|
892
|
+
"0:3: Need space between number and identifier.\n" },
|
|
893
|
+
|
|
894
|
+
// Hex/octal errors.
|
|
895
|
+
{ "0x foo", true,
|
|
896
|
+
"0:2: \"0x\" must be followed by hex digits.\n" },
|
|
897
|
+
{ "0541823 foo", true,
|
|
898
|
+
"0:4: Numbers starting with leading zero must be in octal.\n" },
|
|
899
|
+
{ "0x123z foo", true,
|
|
900
|
+
"0:5: Need space between number and identifier.\n" },
|
|
901
|
+
{ "0x123.4 foo", true,
|
|
902
|
+
"0:5: Hex and octal numbers must be integers.\n" },
|
|
903
|
+
{ "0123.4 foo", true,
|
|
904
|
+
"0:4: Hex and octal numbers must be integers.\n" },
|
|
905
|
+
|
|
906
|
+
// Float errors.
|
|
907
|
+
{ "1e foo", true,
|
|
908
|
+
"0:2: \"e\" must be followed by exponent.\n" },
|
|
909
|
+
{ "1e- foo", true,
|
|
910
|
+
"0:3: \"e\" must be followed by exponent.\n" },
|
|
911
|
+
{ "1.2.3 foo", true,
|
|
912
|
+
"0:3: Already saw decimal point or exponent; can't have another one.\n" },
|
|
913
|
+
{ "1e2.3 foo", true,
|
|
914
|
+
"0:3: Already saw decimal point or exponent; can't have another one.\n" },
|
|
915
|
+
{ "a.1 foo", true,
|
|
916
|
+
"0:1: Need space between identifier and decimal point.\n" },
|
|
917
|
+
// allow_f_after_float not enabled, so this should be an error.
|
|
918
|
+
{ "1.0f foo", true,
|
|
919
|
+
"0:3: Need space between number and identifier.\n" },
|
|
920
|
+
|
|
921
|
+
// Block comment errors.
|
|
922
|
+
{ "/*", false,
|
|
923
|
+
"0:2: End-of-file inside block comment.\n"
|
|
924
|
+
"0:0: Comment started here.\n"},
|
|
925
|
+
{ "/*/*/ foo", true,
|
|
926
|
+
"0:3: \"/*\" inside block comment. Block comments cannot be nested.\n"},
|
|
927
|
+
|
|
928
|
+
// Control characters. Multiple consecutive control characters should only
|
|
929
|
+
// produce one error.
|
|
930
|
+
{ "\b foo", true,
|
|
931
|
+
"0:0: Invalid control characters encountered in text.\n" },
|
|
932
|
+
{ "\b\b foo", true,
|
|
933
|
+
"0:0: Invalid control characters encountered in text.\n" },
|
|
934
|
+
|
|
935
|
+
// Check that control characters at end of input don't result in an
|
|
936
|
+
// infinite loop.
|
|
937
|
+
{ "\b", false,
|
|
938
|
+
"0:0: Invalid control characters encountered in text.\n" },
|
|
939
|
+
|
|
940
|
+
// Check recovery from '\0'. We have to explicitly specify the length of
|
|
941
|
+
// these strings because otherwise the string constructor will just call
|
|
942
|
+
// strlen() which will see the first '\0' and think that is the end of the
|
|
943
|
+
// string.
|
|
944
|
+
{ string("\0foo", 4), true,
|
|
945
|
+
"0:0: Invalid control characters encountered in text.\n" },
|
|
946
|
+
{ string("\0\0foo", 5), true,
|
|
947
|
+
"0:0: Invalid control characters encountered in text.\n" },
|
|
948
|
+
|
|
949
|
+
// Check error from high order bits set
|
|
950
|
+
{ "\300foo", true,
|
|
951
|
+
"0:0: Interpreting non ascii codepoint 192.\n" },
|
|
952
|
+
};
|
|
953
|
+
|
|
954
|
+
TEST_2D(TokenizerTest, Errors, kErrorCases, kBlockSizes) {
|
|
955
|
+
// Set up the tokenizer.
|
|
956
|
+
TestInputStream input(kErrorCases_case.input.data(),
|
|
957
|
+
kErrorCases_case.input.size(),
|
|
958
|
+
kBlockSizes_case);
|
|
959
|
+
TestErrorCollector error_collector;
|
|
960
|
+
Tokenizer tokenizer(&input, &error_collector);
|
|
961
|
+
|
|
962
|
+
// Ignore all input, except remember if the last token was "foo".
|
|
963
|
+
bool last_was_foo = false;
|
|
964
|
+
while (tokenizer.Next()) {
|
|
965
|
+
last_was_foo = tokenizer.current().text == "foo";
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
// Check that the errors match what was expected.
|
|
969
|
+
EXPECT_EQ(kErrorCases_case.errors, error_collector.text_);
|
|
970
|
+
|
|
971
|
+
// If the error was recoverable, make sure we saw "foo" after it.
|
|
972
|
+
if (kErrorCases_case.recoverable) {
|
|
973
|
+
EXPECT_TRUE(last_was_foo);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// -------------------------------------------------------------------
|
|
978
|
+
|
|
979
|
+
TEST_1D(TokenizerTest, BackUpOnDestruction, kBlockSizes) {
|
|
980
|
+
string text = "foo bar";
|
|
981
|
+
TestInputStream input(text.data(), text.size(), kBlockSizes_case);
|
|
982
|
+
|
|
983
|
+
// Create a tokenizer, read one token, then destroy it.
|
|
984
|
+
{
|
|
985
|
+
TestErrorCollector error_collector;
|
|
986
|
+
Tokenizer tokenizer(&input, &error_collector);
|
|
987
|
+
|
|
988
|
+
tokenizer.Next();
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
// Only "foo" should have been read.
|
|
992
|
+
EXPECT_EQ(strlen("foo"), input.ByteCount());
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
|
|
996
|
+
} // namespace
|
|
997
|
+
} // namespace io
|
|
998
|
+
} // namespace protobuf
|
|
999
|
+
} // namespace google
|