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,206 @@
|
|
|
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
|
+
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
|
|
36
|
+
#define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
|
|
37
|
+
|
|
38
|
+
#include <map>
|
|
39
|
+
#include <string>
|
|
40
|
+
#include <google/protobuf/descriptor.h>
|
|
41
|
+
#include <google/protobuf/descriptor.pb.h>
|
|
42
|
+
|
|
43
|
+
namespace google {
|
|
44
|
+
namespace protobuf {
|
|
45
|
+
|
|
46
|
+
namespace io {
|
|
47
|
+
class Printer;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
namespace compiler {
|
|
51
|
+
namespace cpp {
|
|
52
|
+
|
|
53
|
+
// Commonly-used separator comments. Thick is a line of '=', thin is a line
|
|
54
|
+
// of '-'.
|
|
55
|
+
extern const char kThickSeparator[];
|
|
56
|
+
extern const char kThinSeparator[];
|
|
57
|
+
|
|
58
|
+
// Returns the non-nested type name for the given type. If "qualified" is
|
|
59
|
+
// true, prefix the type with the full namespace. For example, if you had:
|
|
60
|
+
// package foo.bar;
|
|
61
|
+
// message Baz { message Qux {} }
|
|
62
|
+
// Then the qualified ClassName for Qux would be:
|
|
63
|
+
// ::foo::bar::Baz_Qux
|
|
64
|
+
// While the non-qualified version would be:
|
|
65
|
+
// Baz_Qux
|
|
66
|
+
string ClassName(const Descriptor* descriptor, bool qualified);
|
|
67
|
+
string ClassName(const EnumDescriptor* enum_descriptor, bool qualified);
|
|
68
|
+
|
|
69
|
+
string SuperClassName(const Descriptor* descriptor);
|
|
70
|
+
|
|
71
|
+
// Get the (unqualified) name that should be used for this field in C++ code.
|
|
72
|
+
// The name is coerced to lower-case to emulate proto1 behavior. People
|
|
73
|
+
// should be using lowercase-with-underscores style for proto field names
|
|
74
|
+
// anyway, so normally this just returns field->name().
|
|
75
|
+
string FieldName(const FieldDescriptor* field);
|
|
76
|
+
|
|
77
|
+
// Get the unqualified name that should be used for a field's field
|
|
78
|
+
// number constant.
|
|
79
|
+
string FieldConstantName(const FieldDescriptor *field);
|
|
80
|
+
|
|
81
|
+
// Returns the scope where the field was defined (for extensions, this is
|
|
82
|
+
// different from the message type to which the field applies).
|
|
83
|
+
inline const Descriptor* FieldScope(const FieldDescriptor* field) {
|
|
84
|
+
return field->is_extension() ?
|
|
85
|
+
field->extension_scope() : field->containing_type();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Returns the fully-qualified type name field->message_type(). Usually this
|
|
89
|
+
// is just ClassName(field->message_type(), true);
|
|
90
|
+
string FieldMessageTypeName(const FieldDescriptor* field);
|
|
91
|
+
|
|
92
|
+
// Strips ".proto" or ".protodevel" from the end of a filename.
|
|
93
|
+
string StripProto(const string& filename);
|
|
94
|
+
|
|
95
|
+
// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
|
|
96
|
+
// Note: non-built-in type names will be qualified, meaning they will start
|
|
97
|
+
// with a ::. If you are using the type as a template parameter, you will
|
|
98
|
+
// need to insure there is a space between the < and the ::, because the
|
|
99
|
+
// ridiculous C++ standard defines "<:" to be a synonym for "[".
|
|
100
|
+
const char* PrimitiveTypeName(FieldDescriptor::CppType type);
|
|
101
|
+
|
|
102
|
+
// Get the declared type name in CamelCase format, as is used e.g. for the
|
|
103
|
+
// methods of WireFormat. For example, TYPE_INT32 becomes "Int32".
|
|
104
|
+
const char* DeclaredTypeMethodName(FieldDescriptor::Type type);
|
|
105
|
+
|
|
106
|
+
// Return the code that evaluates to the number when compiled.
|
|
107
|
+
string Int32ToString(int number);
|
|
108
|
+
|
|
109
|
+
// Return the code that evaluates to the number when compiled.
|
|
110
|
+
string Int64ToString(int64 number);
|
|
111
|
+
|
|
112
|
+
// Get code that evaluates to the field's default value.
|
|
113
|
+
string DefaultValue(const FieldDescriptor* field);
|
|
114
|
+
|
|
115
|
+
// Convert a file name into a valid identifier.
|
|
116
|
+
string FilenameIdentifier(const string& filename);
|
|
117
|
+
|
|
118
|
+
// Return the name of the AddDescriptors() function for a given file.
|
|
119
|
+
string GlobalAddDescriptorsName(const string& filename);
|
|
120
|
+
|
|
121
|
+
// Return the name of the AssignDescriptors() function for a given file.
|
|
122
|
+
string GlobalAssignDescriptorsName(const string& filename);
|
|
123
|
+
|
|
124
|
+
// Return the qualified C++ name for a file level symbol.
|
|
125
|
+
string QualifiedFileLevelSymbol(const string& package, const string& name);
|
|
126
|
+
|
|
127
|
+
// Return the name of the ShutdownFile() function for a given file.
|
|
128
|
+
string GlobalShutdownFileName(const string& filename);
|
|
129
|
+
|
|
130
|
+
// Escape C++ trigraphs by escaping question marks to \?
|
|
131
|
+
string EscapeTrigraphs(const string& to_escape);
|
|
132
|
+
|
|
133
|
+
// Escaped function name to eliminate naming conflict.
|
|
134
|
+
string SafeFunctionName(const Descriptor* descriptor,
|
|
135
|
+
const FieldDescriptor* field,
|
|
136
|
+
const string& prefix);
|
|
137
|
+
|
|
138
|
+
// Do message classes in this file use UnknownFieldSet?
|
|
139
|
+
// Otherwise, messages will store unknown fields in a string
|
|
140
|
+
inline bool UseUnknownFieldSet(const FileDescriptor* file) {
|
|
141
|
+
return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
// Does this file have any enum type definitions?
|
|
146
|
+
bool HasEnumDefinitions(const FileDescriptor* file);
|
|
147
|
+
|
|
148
|
+
// Does this file have generated parsing, serialization, and other
|
|
149
|
+
// standard methods for which reflection-based fallback implementations exist?
|
|
150
|
+
inline bool HasGeneratedMethods(const FileDescriptor* file) {
|
|
151
|
+
return file->options().optimize_for() != FileOptions::CODE_SIZE;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Do message classes in this file have descriptor and reflection methods?
|
|
155
|
+
inline bool HasDescriptorMethods(const FileDescriptor* file) {
|
|
156
|
+
return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Should we generate generic services for this file?
|
|
160
|
+
inline bool HasGenericServices(const FileDescriptor* file) {
|
|
161
|
+
return file->service_count() > 0 &&
|
|
162
|
+
file->options().optimize_for() != FileOptions::LITE_RUNTIME &&
|
|
163
|
+
file->options().cc_generic_services();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Should string fields in this file verify that their contents are UTF-8?
|
|
167
|
+
inline bool HasUtf8Verification(const FileDescriptor* file) {
|
|
168
|
+
return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Should we generate a separate, super-optimized code path for serializing to
|
|
172
|
+
// flat arrays? We don't do this in Lite mode because we'd rather reduce code
|
|
173
|
+
// size.
|
|
174
|
+
inline bool HasFastArraySerialization(const FileDescriptor* file) {
|
|
175
|
+
return file->options().optimize_for() == FileOptions::SPEED;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Returns whether we have to generate code with static initializers.
|
|
179
|
+
bool StaticInitializersForced(const FileDescriptor* file);
|
|
180
|
+
|
|
181
|
+
// Prints 'with_static_init' if static initializers have to be used for the
|
|
182
|
+
// provided file. Otherwise emits both 'with_static_init' and
|
|
183
|
+
// 'without_static_init' using #ifdef.
|
|
184
|
+
void PrintHandlingOptionalStaticInitializers(
|
|
185
|
+
const FileDescriptor* file, io::Printer* printer,
|
|
186
|
+
const char* with_static_init, const char* without_static_init,
|
|
187
|
+
const char* var1 = NULL, const string& val1 = "",
|
|
188
|
+
const char* var2 = NULL, const string& val2 = "");
|
|
189
|
+
|
|
190
|
+
void PrintHandlingOptionalStaticInitializers(
|
|
191
|
+
const map<string, string>& vars, const FileDescriptor* file,
|
|
192
|
+
io::Printer* printer, const char* with_static_init,
|
|
193
|
+
const char* without_static_init);
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
// Returns true if the field's CPPTYPE is string or message.
|
|
197
|
+
bool IsStringOrMessage(const FieldDescriptor* field);
|
|
198
|
+
|
|
199
|
+
string UnderscoresToCamelCase(const string& input, bool cap_next_letter);
|
|
200
|
+
|
|
201
|
+
} // namespace cpp
|
|
202
|
+
} // namespace compiler
|
|
203
|
+
} // namespace protobuf
|
|
204
|
+
|
|
205
|
+
} // namespace google
|
|
206
|
+
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
|
|
@@ -0,0 +1,2645 @@
|
|
|
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 <algorithm>
|
|
36
|
+
#include <google/protobuf/stubs/hash.h>
|
|
37
|
+
#include <map>
|
|
38
|
+
#include <memory>
|
|
39
|
+
#include <set>
|
|
40
|
+
#include <utility>
|
|
41
|
+
#include <vector>
|
|
42
|
+
#include <google/protobuf/compiler/cpp/cpp_message.h>
|
|
43
|
+
#include <google/protobuf/compiler/cpp/cpp_field.h>
|
|
44
|
+
#include <google/protobuf/compiler/cpp/cpp_enum.h>
|
|
45
|
+
#include <google/protobuf/compiler/cpp/cpp_extension.h>
|
|
46
|
+
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
|
47
|
+
#include <google/protobuf/stubs/strutil.h>
|
|
48
|
+
#include <google/protobuf/io/printer.h>
|
|
49
|
+
#include <google/protobuf/io/coded_stream.h>
|
|
50
|
+
#include <google/protobuf/wire_format.h>
|
|
51
|
+
#include <google/protobuf/descriptor.pb.h>
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
namespace google {
|
|
55
|
+
namespace protobuf {
|
|
56
|
+
namespace compiler {
|
|
57
|
+
namespace cpp {
|
|
58
|
+
|
|
59
|
+
using internal::WireFormat;
|
|
60
|
+
using internal::WireFormatLite;
|
|
61
|
+
|
|
62
|
+
namespace {
|
|
63
|
+
|
|
64
|
+
void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
|
|
65
|
+
// Print the field's proto-syntax definition as a comment. We don't want to
|
|
66
|
+
// print group bodies so we cut off after the first line.
|
|
67
|
+
string def = field->DebugString();
|
|
68
|
+
printer->Print("// $def$\n",
|
|
69
|
+
"def", def.substr(0, def.find_first_of('\n')));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
struct FieldOrderingByNumber {
|
|
73
|
+
inline bool operator()(const FieldDescriptor* a,
|
|
74
|
+
const FieldDescriptor* b) const {
|
|
75
|
+
return a->number() < b->number();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Sort the fields of the given Descriptor by number into a new[]'d array
|
|
80
|
+
// and return it.
|
|
81
|
+
const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
|
|
82
|
+
const FieldDescriptor** fields =
|
|
83
|
+
new const FieldDescriptor*[descriptor->field_count()];
|
|
84
|
+
for (int i = 0; i < descriptor->field_count(); i++) {
|
|
85
|
+
fields[i] = descriptor->field(i);
|
|
86
|
+
}
|
|
87
|
+
sort(fields, fields + descriptor->field_count(),
|
|
88
|
+
FieldOrderingByNumber());
|
|
89
|
+
return fields;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Functor for sorting extension ranges by their "start" field number.
|
|
93
|
+
struct ExtensionRangeSorter {
|
|
94
|
+
bool operator()(const Descriptor::ExtensionRange* left,
|
|
95
|
+
const Descriptor::ExtensionRange* right) const {
|
|
96
|
+
return left->start < right->start;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// Returns true if the "required" restriction check should be ignored for the
|
|
101
|
+
// given field.
|
|
102
|
+
inline static bool ShouldIgnoreRequiredFieldCheck(
|
|
103
|
+
const FieldDescriptor* field) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Returns true if the message type has any required fields. If it doesn't,
|
|
108
|
+
// we can optimize out calls to its IsInitialized() method.
|
|
109
|
+
//
|
|
110
|
+
// already_seen is used to avoid checking the same type multiple times
|
|
111
|
+
// (and also to protect against recursion).
|
|
112
|
+
static bool HasRequiredFields(
|
|
113
|
+
const Descriptor* type,
|
|
114
|
+
hash_set<const Descriptor*>* already_seen) {
|
|
115
|
+
if (already_seen->count(type) > 0) {
|
|
116
|
+
// Since the first occurrence of a required field causes the whole
|
|
117
|
+
// function to return true, we can assume that if the type is already
|
|
118
|
+
// in the cache it didn't have any required fields.
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
already_seen->insert(type);
|
|
122
|
+
|
|
123
|
+
// If the type has extensions, an extension with message type could contain
|
|
124
|
+
// required fields, so we have to be conservative and assume such an
|
|
125
|
+
// extension exists.
|
|
126
|
+
if (type->extension_range_count() > 0) return true;
|
|
127
|
+
|
|
128
|
+
for (int i = 0; i < type->field_count(); i++) {
|
|
129
|
+
const FieldDescriptor* field = type->field(i);
|
|
130
|
+
if (field->is_required()) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
|
|
134
|
+
!ShouldIgnoreRequiredFieldCheck(field)) {
|
|
135
|
+
if (HasRequiredFields(field->message_type(), already_seen)) {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static bool HasRequiredFields(const Descriptor* type) {
|
|
145
|
+
hash_set<const Descriptor*> already_seen;
|
|
146
|
+
return HasRequiredFields(type, &already_seen);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// This returns an estimate of the compiler's alignment for the field. This
|
|
150
|
+
// can't guarantee to be correct because the generated code could be compiled on
|
|
151
|
+
// different systems with different alignment rules. The estimates below assume
|
|
152
|
+
// 64-bit pointers.
|
|
153
|
+
int EstimateAlignmentSize(const FieldDescriptor* field) {
|
|
154
|
+
if (field == NULL) return 0;
|
|
155
|
+
if (field->is_repeated()) return 8;
|
|
156
|
+
switch (field->cpp_type()) {
|
|
157
|
+
case FieldDescriptor::CPPTYPE_BOOL:
|
|
158
|
+
return 1;
|
|
159
|
+
|
|
160
|
+
case FieldDescriptor::CPPTYPE_INT32:
|
|
161
|
+
case FieldDescriptor::CPPTYPE_UINT32:
|
|
162
|
+
case FieldDescriptor::CPPTYPE_ENUM:
|
|
163
|
+
case FieldDescriptor::CPPTYPE_FLOAT:
|
|
164
|
+
return 4;
|
|
165
|
+
|
|
166
|
+
case FieldDescriptor::CPPTYPE_INT64:
|
|
167
|
+
case FieldDescriptor::CPPTYPE_UINT64:
|
|
168
|
+
case FieldDescriptor::CPPTYPE_DOUBLE:
|
|
169
|
+
case FieldDescriptor::CPPTYPE_STRING:
|
|
170
|
+
case FieldDescriptor::CPPTYPE_MESSAGE:
|
|
171
|
+
return 8;
|
|
172
|
+
}
|
|
173
|
+
GOOGLE_LOG(FATAL) << "Can't get here.";
|
|
174
|
+
return -1; // Make compiler happy.
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// FieldGroup is just a helper for OptimizePadding below. It holds a vector of
|
|
178
|
+
// fields that are grouped together because they have compatible alignment, and
|
|
179
|
+
// a preferred location in the final field ordering.
|
|
180
|
+
class FieldGroup {
|
|
181
|
+
public:
|
|
182
|
+
FieldGroup()
|
|
183
|
+
: preferred_location_(0) {}
|
|
184
|
+
|
|
185
|
+
// A group with a single field.
|
|
186
|
+
FieldGroup(float preferred_location, const FieldDescriptor* field)
|
|
187
|
+
: preferred_location_(preferred_location),
|
|
188
|
+
fields_(1, field) {}
|
|
189
|
+
|
|
190
|
+
// Append the fields in 'other' to this group.
|
|
191
|
+
void Append(const FieldGroup& other) {
|
|
192
|
+
if (other.fields_.empty()) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
// Preferred location is the average among all the fields, so we weight by
|
|
196
|
+
// the number of fields on each FieldGroup object.
|
|
197
|
+
preferred_location_ =
|
|
198
|
+
(preferred_location_ * fields_.size() +
|
|
199
|
+
(other.preferred_location_ * other.fields_.size())) /
|
|
200
|
+
(fields_.size() + other.fields_.size());
|
|
201
|
+
fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
void SetPreferredLocation(float location) { preferred_location_ = location; }
|
|
205
|
+
const vector<const FieldDescriptor*>& fields() const { return fields_; }
|
|
206
|
+
|
|
207
|
+
// FieldGroup objects sort by their preferred location.
|
|
208
|
+
bool operator<(const FieldGroup& other) const {
|
|
209
|
+
return preferred_location_ < other.preferred_location_;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private:
|
|
213
|
+
// "preferred_location_" is an estimate of where this group should go in the
|
|
214
|
+
// final list of fields. We compute this by taking the average index of each
|
|
215
|
+
// field in this group in the original ordering of fields. This is very
|
|
216
|
+
// approximate, but should put this group close to where its member fields
|
|
217
|
+
// originally went.
|
|
218
|
+
float preferred_location_;
|
|
219
|
+
vector<const FieldDescriptor*> fields_;
|
|
220
|
+
// We rely on the default copy constructor and operator= so this type can be
|
|
221
|
+
// used in a vector.
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
// Reorder 'fields' so that if the fields are output into a c++ class in the new
|
|
225
|
+
// order, the alignment padding is minimized. We try to do this while keeping
|
|
226
|
+
// each field as close as possible to its original position so that we don't
|
|
227
|
+
// reduce cache locality much for function that access each field in order.
|
|
228
|
+
void OptimizePadding(vector<const FieldDescriptor*>* fields) {
|
|
229
|
+
// First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
|
|
230
|
+
vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8;
|
|
231
|
+
for (int i = 0; i < fields->size(); ++i) {
|
|
232
|
+
switch (EstimateAlignmentSize((*fields)[i])) {
|
|
233
|
+
case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break;
|
|
234
|
+
case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break;
|
|
235
|
+
case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break;
|
|
236
|
+
default:
|
|
237
|
+
GOOGLE_LOG(FATAL) << "Unknown alignment size.";
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Now group fields aligned to 1 byte into sets of 4, and treat those like a
|
|
242
|
+
// single field aligned to 4 bytes.
|
|
243
|
+
for (int i = 0; i < aligned_to_1.size(); i += 4) {
|
|
244
|
+
FieldGroup field_group;
|
|
245
|
+
for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) {
|
|
246
|
+
field_group.Append(aligned_to_1[j]);
|
|
247
|
+
}
|
|
248
|
+
aligned_to_4.push_back(field_group);
|
|
249
|
+
}
|
|
250
|
+
// Sort by preferred location to keep fields as close to their original
|
|
251
|
+
// location as possible. Using stable_sort ensures that the output is
|
|
252
|
+
// consistent across runs.
|
|
253
|
+
stable_sort(aligned_to_4.begin(), aligned_to_4.end());
|
|
254
|
+
|
|
255
|
+
// Now group fields aligned to 4 bytes (or the 4-field groups created above)
|
|
256
|
+
// into pairs, and treat those like a single field aligned to 8 bytes.
|
|
257
|
+
for (int i = 0; i < aligned_to_4.size(); i += 2) {
|
|
258
|
+
FieldGroup field_group;
|
|
259
|
+
for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) {
|
|
260
|
+
field_group.Append(aligned_to_4[j]);
|
|
261
|
+
}
|
|
262
|
+
if (i == aligned_to_4.size() - 1) {
|
|
263
|
+
// Move incomplete 4-byte block to the end.
|
|
264
|
+
field_group.SetPreferredLocation(fields->size() + 1);
|
|
265
|
+
}
|
|
266
|
+
aligned_to_8.push_back(field_group);
|
|
267
|
+
}
|
|
268
|
+
// Sort by preferred location.
|
|
269
|
+
stable_sort(aligned_to_8.begin(), aligned_to_8.end());
|
|
270
|
+
|
|
271
|
+
// Now pull out all the FieldDescriptors in order.
|
|
272
|
+
fields->clear();
|
|
273
|
+
for (int i = 0; i < aligned_to_8.size(); ++i) {
|
|
274
|
+
fields->insert(fields->end(),
|
|
275
|
+
aligned_to_8[i].fields().begin(),
|
|
276
|
+
aligned_to_8[i].fields().end());
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
string MessageTypeProtoName(const FieldDescriptor* field) {
|
|
281
|
+
return field->message_type()->full_name();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// ===================================================================
|
|
287
|
+
|
|
288
|
+
MessageGenerator::MessageGenerator(const Descriptor* descriptor,
|
|
289
|
+
const Options& options)
|
|
290
|
+
: descriptor_(descriptor),
|
|
291
|
+
classname_(ClassName(descriptor, false)),
|
|
292
|
+
options_(options),
|
|
293
|
+
field_generators_(descriptor, options),
|
|
294
|
+
nested_generators_(new scoped_ptr<
|
|
295
|
+
MessageGenerator>[descriptor->nested_type_count()]),
|
|
296
|
+
enum_generators_(
|
|
297
|
+
new scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]),
|
|
298
|
+
extension_generators_(new scoped_ptr<
|
|
299
|
+
ExtensionGenerator>[descriptor->extension_count()]) {
|
|
300
|
+
|
|
301
|
+
for (int i = 0; i < descriptor->nested_type_count(); i++) {
|
|
302
|
+
nested_generators_[i].reset(
|
|
303
|
+
new MessageGenerator(descriptor->nested_type(i), options));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
for (int i = 0; i < descriptor->enum_type_count(); i++) {
|
|
307
|
+
enum_generators_[i].reset(
|
|
308
|
+
new EnumGenerator(descriptor->enum_type(i), options));
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
for (int i = 0; i < descriptor->extension_count(); i++) {
|
|
312
|
+
extension_generators_[i].reset(
|
|
313
|
+
new ExtensionGenerator(descriptor->extension(i), options));
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
MessageGenerator::~MessageGenerator() {}
|
|
318
|
+
|
|
319
|
+
void MessageGenerator::
|
|
320
|
+
GenerateForwardDeclaration(io::Printer* printer) {
|
|
321
|
+
printer->Print("class $classname$;\n",
|
|
322
|
+
"classname", classname_);
|
|
323
|
+
|
|
324
|
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
|
325
|
+
nested_generators_[i]->GenerateForwardDeclaration(printer);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
void MessageGenerator::
|
|
330
|
+
GenerateEnumDefinitions(io::Printer* printer) {
|
|
331
|
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
|
332
|
+
nested_generators_[i]->GenerateEnumDefinitions(printer);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
|
|
336
|
+
enum_generators_[i]->GenerateDefinition(printer);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
void MessageGenerator::
|
|
341
|
+
GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
|
|
342
|
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
|
343
|
+
nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
|
|
344
|
+
}
|
|
345
|
+
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
|
|
346
|
+
enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
void MessageGenerator::
|
|
351
|
+
GenerateFieldAccessorDeclarations(io::Printer* printer) {
|
|
352
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
353
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
354
|
+
|
|
355
|
+
PrintFieldComment(printer, field);
|
|
356
|
+
|
|
357
|
+
map<string, string> vars;
|
|
358
|
+
SetCommonFieldVariables(field, &vars, options_);
|
|
359
|
+
vars["constant_name"] = FieldConstantName(field);
|
|
360
|
+
|
|
361
|
+
if (field->is_repeated()) {
|
|
362
|
+
printer->Print(vars, "inline int $name$_size() const$deprecation$;\n");
|
|
363
|
+
} else {
|
|
364
|
+
printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n");
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
printer->Print(vars, "inline void clear_$name$()$deprecation$;\n");
|
|
368
|
+
printer->Print(vars, "static const int $constant_name$ = $number$;\n");
|
|
369
|
+
|
|
370
|
+
// Generate type-specific accessor declarations.
|
|
371
|
+
field_generators_.get(field).GenerateAccessorDeclarations(printer);
|
|
372
|
+
|
|
373
|
+
printer->Print("\n");
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (descriptor_->extension_range_count() > 0) {
|
|
377
|
+
// Generate accessors for extensions. We just call a macro located in
|
|
378
|
+
// extension_set.h since the accessors about 80 lines of static code.
|
|
379
|
+
printer->Print(
|
|
380
|
+
"GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
|
|
381
|
+
"classname", classname_);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
385
|
+
printer->Print(
|
|
386
|
+
"inline $camel_oneof_name$Case $oneof_name$_case() const;\n",
|
|
387
|
+
"camel_oneof_name",
|
|
388
|
+
UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true),
|
|
389
|
+
"oneof_name", descriptor_->oneof_decl(i)->name());
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
void MessageGenerator::
|
|
394
|
+
GenerateFieldAccessorDefinitions(io::Printer* printer) {
|
|
395
|
+
printer->Print("// $classname$\n\n", "classname", classname_);
|
|
396
|
+
|
|
397
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
398
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
399
|
+
|
|
400
|
+
PrintFieldComment(printer, field);
|
|
401
|
+
|
|
402
|
+
map<string, string> vars;
|
|
403
|
+
SetCommonFieldVariables(field, &vars, options_);
|
|
404
|
+
|
|
405
|
+
// Generate has_$name$() or $name$_size().
|
|
406
|
+
if (field->is_repeated()) {
|
|
407
|
+
printer->Print(vars,
|
|
408
|
+
"inline int $classname$::$name$_size() const {\n"
|
|
409
|
+
" return $name$_.size();\n"
|
|
410
|
+
"}\n");
|
|
411
|
+
} else if (field->containing_oneof()) {
|
|
412
|
+
// Singular field in a oneof
|
|
413
|
+
vars["field_name"] = UnderscoresToCamelCase(field->name(), true);
|
|
414
|
+
vars["oneof_name"] = field->containing_oneof()->name();
|
|
415
|
+
vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index());
|
|
416
|
+
printer->Print(vars,
|
|
417
|
+
"inline bool $classname$::has_$name$() const {\n"
|
|
418
|
+
" return $oneof_name$_case() == k$field_name$;\n"
|
|
419
|
+
"}\n"
|
|
420
|
+
"inline void $classname$::set_has_$name$() {\n"
|
|
421
|
+
" _oneof_case_[$oneof_index$] = k$field_name$;\n"
|
|
422
|
+
"}\n");
|
|
423
|
+
} else {
|
|
424
|
+
// Singular field.
|
|
425
|
+
char buffer[kFastToBufferSize];
|
|
426
|
+
vars["has_array_index"] = SimpleItoa(field->index() / 32);
|
|
427
|
+
vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer);
|
|
428
|
+
printer->Print(vars,
|
|
429
|
+
"inline bool $classname$::has_$name$() const {\n"
|
|
430
|
+
" return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
|
|
431
|
+
"}\n"
|
|
432
|
+
"inline void $classname$::set_has_$name$() {\n"
|
|
433
|
+
" _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n"
|
|
434
|
+
"}\n"
|
|
435
|
+
"inline void $classname$::clear_has_$name$() {\n"
|
|
436
|
+
" _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"
|
|
437
|
+
"}\n"
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Generate clear_$name$()
|
|
442
|
+
printer->Print(vars,
|
|
443
|
+
"inline void $classname$::clear_$name$() {\n");
|
|
444
|
+
|
|
445
|
+
printer->Indent();
|
|
446
|
+
|
|
447
|
+
if (field->containing_oneof()) {
|
|
448
|
+
// Clear this field only if it is the active field in this oneof,
|
|
449
|
+
// otherwise ignore
|
|
450
|
+
printer->Print(vars,
|
|
451
|
+
"if (has_$name$()) {\n");
|
|
452
|
+
printer->Indent();
|
|
453
|
+
field_generators_.get(field).GenerateClearingCode(printer);
|
|
454
|
+
printer->Print(vars,
|
|
455
|
+
"clear_has_$oneof_name$();\n");
|
|
456
|
+
printer->Outdent();
|
|
457
|
+
printer->Print("}\n");
|
|
458
|
+
} else {
|
|
459
|
+
field_generators_.get(field).GenerateClearingCode(printer);
|
|
460
|
+
if (!field->is_repeated()) {
|
|
461
|
+
printer->Print(vars,
|
|
462
|
+
"clear_has_$name$();\n");
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
printer->Outdent();
|
|
467
|
+
printer->Print("}\n");
|
|
468
|
+
|
|
469
|
+
// Generate type-specific accessors.
|
|
470
|
+
field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
|
|
471
|
+
|
|
472
|
+
printer->Print("\n");
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// Generate has_$name$() and clear_has_$name$() functions for oneofs
|
|
476
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
477
|
+
map<string, string> vars;
|
|
478
|
+
vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
|
|
479
|
+
vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
|
|
480
|
+
vars["cap_oneof_name"] =
|
|
481
|
+
ToUpper(descriptor_->oneof_decl(i)->name());
|
|
482
|
+
vars["classname"] = classname_;
|
|
483
|
+
printer->Print(
|
|
484
|
+
vars,
|
|
485
|
+
"inline bool $classname$::has_$oneof_name$() {\n"
|
|
486
|
+
" return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
|
|
487
|
+
"}\n"
|
|
488
|
+
"inline void $classname$::clear_has_$oneof_name$() {\n"
|
|
489
|
+
" _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
|
|
490
|
+
"}\n");
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Helper for the code that emits the Clear() method.
|
|
495
|
+
static bool CanClearByZeroing(const FieldDescriptor* field) {
|
|
496
|
+
if (field->is_repeated() || field->is_extension()) return false;
|
|
497
|
+
switch (field->cpp_type()) {
|
|
498
|
+
case internal::WireFormatLite::CPPTYPE_ENUM:
|
|
499
|
+
return field->default_value_enum()->number() == 0;
|
|
500
|
+
case internal::WireFormatLite::CPPTYPE_INT32:
|
|
501
|
+
return field->default_value_int32() == 0;
|
|
502
|
+
case internal::WireFormatLite::CPPTYPE_INT64:
|
|
503
|
+
return field->default_value_int64() == 0;
|
|
504
|
+
case internal::WireFormatLite::CPPTYPE_UINT32:
|
|
505
|
+
return field->default_value_uint32() == 0;
|
|
506
|
+
case internal::WireFormatLite::CPPTYPE_UINT64:
|
|
507
|
+
return field->default_value_uint64() == 0;
|
|
508
|
+
case internal::WireFormatLite::CPPTYPE_FLOAT:
|
|
509
|
+
return field->default_value_float() == 0;
|
|
510
|
+
case internal::WireFormatLite::CPPTYPE_DOUBLE:
|
|
511
|
+
return field->default_value_double() == 0;
|
|
512
|
+
case internal::WireFormatLite::CPPTYPE_BOOL:
|
|
513
|
+
return field->default_value_bool() == false;
|
|
514
|
+
default:
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
void MessageGenerator::
|
|
520
|
+
GenerateClassDefinition(io::Printer* printer) {
|
|
521
|
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
|
522
|
+
nested_generators_[i]->GenerateClassDefinition(printer);
|
|
523
|
+
printer->Print("\n");
|
|
524
|
+
printer->Print(kThinSeparator);
|
|
525
|
+
printer->Print("\n");
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
map<string, string> vars;
|
|
529
|
+
vars["classname"] = classname_;
|
|
530
|
+
vars["field_count"] = SimpleItoa(descriptor_->field_count());
|
|
531
|
+
vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count());
|
|
532
|
+
if (options_.dllexport_decl.empty()) {
|
|
533
|
+
vars["dllexport"] = "";
|
|
534
|
+
} else {
|
|
535
|
+
vars["dllexport"] = options_.dllexport_decl + " ";
|
|
536
|
+
}
|
|
537
|
+
vars["superclass"] = SuperClassName(descriptor_);
|
|
538
|
+
|
|
539
|
+
printer->Print(vars,
|
|
540
|
+
"class $dllexport$$classname$ : public $superclass$ {\n"
|
|
541
|
+
" public:\n");
|
|
542
|
+
printer->Indent();
|
|
543
|
+
|
|
544
|
+
printer->Print(vars,
|
|
545
|
+
"$classname$();\n"
|
|
546
|
+
"virtual ~$classname$();\n"
|
|
547
|
+
"\n"
|
|
548
|
+
"$classname$(const $classname$& from);\n"
|
|
549
|
+
"\n"
|
|
550
|
+
"inline $classname$& operator=(const $classname$& from) {\n"
|
|
551
|
+
" CopyFrom(from);\n"
|
|
552
|
+
" return *this;\n"
|
|
553
|
+
"}\n"
|
|
554
|
+
"\n");
|
|
555
|
+
|
|
556
|
+
if (UseUnknownFieldSet(descriptor_->file())) {
|
|
557
|
+
printer->Print(
|
|
558
|
+
"inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
|
|
559
|
+
" return _unknown_fields_;\n"
|
|
560
|
+
"}\n"
|
|
561
|
+
"\n"
|
|
562
|
+
"inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
|
|
563
|
+
" return &_unknown_fields_;\n"
|
|
564
|
+
"}\n"
|
|
565
|
+
"\n");
|
|
566
|
+
} else {
|
|
567
|
+
printer->Print(
|
|
568
|
+
"inline const ::std::string& unknown_fields() const {\n"
|
|
569
|
+
" return _unknown_fields_;\n"
|
|
570
|
+
"}\n"
|
|
571
|
+
"\n"
|
|
572
|
+
"inline ::std::string* mutable_unknown_fields() {\n"
|
|
573
|
+
" return &_unknown_fields_;\n"
|
|
574
|
+
"}\n"
|
|
575
|
+
"\n");
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// Only generate this member if it's not disabled.
|
|
579
|
+
if (HasDescriptorMethods(descriptor_->file()) &&
|
|
580
|
+
!descriptor_->options().no_standard_descriptor_accessor()) {
|
|
581
|
+
printer->Print(vars,
|
|
582
|
+
"static const ::google::protobuf::Descriptor* descriptor();\n");
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
printer->Print(vars,
|
|
586
|
+
"static const $classname$& default_instance();\n"
|
|
587
|
+
"\n");
|
|
588
|
+
|
|
589
|
+
// Generate enum values for every field in oneofs. One list is generated for
|
|
590
|
+
// each oneof with an additional *_NOT_SET value.
|
|
591
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
592
|
+
printer->Print(
|
|
593
|
+
"enum $camel_oneof_name$Case {\n",
|
|
594
|
+
"camel_oneof_name",
|
|
595
|
+
UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
|
|
596
|
+
printer->Indent();
|
|
597
|
+
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
|
|
598
|
+
printer->Print(
|
|
599
|
+
"k$field_name$ = $field_number$,\n",
|
|
600
|
+
"field_name",
|
|
601
|
+
UnderscoresToCamelCase(
|
|
602
|
+
descriptor_->oneof_decl(i)->field(j)->name(), true),
|
|
603
|
+
"field_number",
|
|
604
|
+
SimpleItoa(descriptor_->oneof_decl(i)->field(j)->number()));
|
|
605
|
+
}
|
|
606
|
+
printer->Print(
|
|
607
|
+
"$cap_oneof_name$_NOT_SET = 0,\n",
|
|
608
|
+
"cap_oneof_name",
|
|
609
|
+
ToUpper(descriptor_->oneof_decl(i)->name()));
|
|
610
|
+
printer->Outdent();
|
|
611
|
+
printer->Print(
|
|
612
|
+
"};\n"
|
|
613
|
+
"\n");
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
if (!StaticInitializersForced(descriptor_->file())) {
|
|
617
|
+
printer->Print(vars,
|
|
618
|
+
"#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
|
|
619
|
+
"// Returns the internal default instance pointer. This function can\n"
|
|
620
|
+
"// return NULL thus should not be used by the user. This is intended\n"
|
|
621
|
+
"// for Protobuf internal code. Please use default_instance() declared\n"
|
|
622
|
+
"// above instead.\n"
|
|
623
|
+
"static inline const $classname$* internal_default_instance() {\n"
|
|
624
|
+
" return default_instance_;\n"
|
|
625
|
+
"}\n"
|
|
626
|
+
"#endif\n"
|
|
627
|
+
"\n");
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
printer->Print(vars,
|
|
632
|
+
"void Swap($classname$* other);\n"
|
|
633
|
+
"\n"
|
|
634
|
+
"// implements Message ----------------------------------------------\n"
|
|
635
|
+
"\n"
|
|
636
|
+
"$classname$* New() const;\n");
|
|
637
|
+
|
|
638
|
+
if (HasGeneratedMethods(descriptor_->file())) {
|
|
639
|
+
if (HasDescriptorMethods(descriptor_->file())) {
|
|
640
|
+
printer->Print(vars,
|
|
641
|
+
"void CopyFrom(const ::google::protobuf::Message& from);\n"
|
|
642
|
+
"void MergeFrom(const ::google::protobuf::Message& from);\n");
|
|
643
|
+
} else {
|
|
644
|
+
printer->Print(vars,
|
|
645
|
+
"void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
printer->Print(vars,
|
|
649
|
+
"void CopyFrom(const $classname$& from);\n"
|
|
650
|
+
"void MergeFrom(const $classname$& from);\n"
|
|
651
|
+
"void Clear();\n"
|
|
652
|
+
"bool IsInitialized() const;\n"
|
|
653
|
+
"\n"
|
|
654
|
+
"int ByteSize() const;\n"
|
|
655
|
+
"bool MergePartialFromCodedStream(\n"
|
|
656
|
+
" ::google::protobuf::io::CodedInputStream* input);\n"
|
|
657
|
+
"void SerializeWithCachedSizes(\n"
|
|
658
|
+
" ::google::protobuf::io::CodedOutputStream* output) const;\n");
|
|
659
|
+
// DiscardUnknownFields() is implemented in message.cc using reflections. We
|
|
660
|
+
// need to implement this function in generated code for messages.
|
|
661
|
+
if (!UseUnknownFieldSet(descriptor_->file())) {
|
|
662
|
+
printer->Print(
|
|
663
|
+
"void DiscardUnknownFields();\n");
|
|
664
|
+
}
|
|
665
|
+
if (HasFastArraySerialization(descriptor_->file())) {
|
|
666
|
+
printer->Print(
|
|
667
|
+
"::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// Check all FieldDescriptors including those in oneofs to estimate
|
|
672
|
+
// whether ::std::string is likely to be used, and depending on that
|
|
673
|
+
// estimate, set uses_string_ to true or false. That contols
|
|
674
|
+
// whether to force initialization of empty_string_ in SharedCtor().
|
|
675
|
+
// It's often advantageous to do so to keep "is empty_string_
|
|
676
|
+
// inited?" code from appearing all over the place.
|
|
677
|
+
vector<const FieldDescriptor*> descriptors;
|
|
678
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
679
|
+
descriptors.push_back(descriptor_->field(i));
|
|
680
|
+
}
|
|
681
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
682
|
+
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
|
|
683
|
+
descriptors.push_back(descriptor_->oneof_decl(i)->field(j));
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
uses_string_ = false;
|
|
687
|
+
for (int i = 0; i < descriptors.size(); i++) {
|
|
688
|
+
const FieldDescriptor* field = descriptors[i];
|
|
689
|
+
if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
|
|
690
|
+
switch (field->options().ctype()) {
|
|
691
|
+
default: uses_string_ = true; break;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
printer->Print(
|
|
697
|
+
"int GetCachedSize() const { return _cached_size_; }\n"
|
|
698
|
+
"private:\n"
|
|
699
|
+
"void SharedCtor();\n"
|
|
700
|
+
"void SharedDtor();\n"
|
|
701
|
+
"void SetCachedSize(int size) const;\n"
|
|
702
|
+
"public:\n");
|
|
703
|
+
|
|
704
|
+
if (HasDescriptorMethods(descriptor_->file())) {
|
|
705
|
+
printer->Print(
|
|
706
|
+
"::google::protobuf::Metadata GetMetadata() const;\n"
|
|
707
|
+
"\n");
|
|
708
|
+
} else {
|
|
709
|
+
printer->Print(
|
|
710
|
+
"::std::string GetTypeName() const;\n"
|
|
711
|
+
"\n");
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
printer->Print(
|
|
715
|
+
"// nested types ----------------------------------------------------\n"
|
|
716
|
+
"\n");
|
|
717
|
+
|
|
718
|
+
// Import all nested message classes into this class's scope with typedefs.
|
|
719
|
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
|
720
|
+
const Descriptor* nested_type = descriptor_->nested_type(i);
|
|
721
|
+
printer->Print("typedef $nested_full_name$ $nested_name$;\n",
|
|
722
|
+
"nested_name", nested_type->name(),
|
|
723
|
+
"nested_full_name", ClassName(nested_type, false));
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
if (descriptor_->nested_type_count() > 0) {
|
|
727
|
+
printer->Print("\n");
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
// Import all nested enums and their values into this class's scope with
|
|
731
|
+
// typedefs and constants.
|
|
732
|
+
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
|
|
733
|
+
enum_generators_[i]->GenerateSymbolImports(printer);
|
|
734
|
+
printer->Print("\n");
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
printer->Print(
|
|
738
|
+
"// accessors -------------------------------------------------------\n"
|
|
739
|
+
"\n");
|
|
740
|
+
|
|
741
|
+
// Generate accessor methods for all fields.
|
|
742
|
+
GenerateFieldAccessorDeclarations(printer);
|
|
743
|
+
|
|
744
|
+
// Declare extension identifiers.
|
|
745
|
+
for (int i = 0; i < descriptor_->extension_count(); i++) {
|
|
746
|
+
extension_generators_[i]->GenerateDeclaration(printer);
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
printer->Print(
|
|
751
|
+
"// @@protoc_insertion_point(class_scope:$full_name$)\n",
|
|
752
|
+
"full_name", descriptor_->full_name());
|
|
753
|
+
|
|
754
|
+
// Generate private members.
|
|
755
|
+
printer->Outdent();
|
|
756
|
+
printer->Print(" private:\n");
|
|
757
|
+
printer->Indent();
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
761
|
+
if (!descriptor_->field(i)->is_repeated()) {
|
|
762
|
+
printer->Print(
|
|
763
|
+
"inline void set_has_$name$();\n",
|
|
764
|
+
"name", FieldName(descriptor_->field(i)));
|
|
765
|
+
if (!descriptor_->field(i)->containing_oneof()) {
|
|
766
|
+
printer->Print(
|
|
767
|
+
"inline void clear_has_$name$();\n",
|
|
768
|
+
"name", FieldName(descriptor_->field(i)));
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
printer->Print("\n");
|
|
773
|
+
|
|
774
|
+
// Generate oneof function declarations
|
|
775
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
776
|
+
printer->Print(
|
|
777
|
+
"inline bool has_$oneof_name$();\n"
|
|
778
|
+
"void clear_$oneof_name$();\n"
|
|
779
|
+
"inline void clear_has_$oneof_name$();\n\n",
|
|
780
|
+
"oneof_name", descriptor_->oneof_decl(i)->name());
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
// Prepare decls for _cached_size_ and _has_bits_. Their position in the
|
|
784
|
+
// output will be determined later.
|
|
785
|
+
|
|
786
|
+
bool need_to_emit_cached_size = true;
|
|
787
|
+
// TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it.
|
|
788
|
+
const string cached_size_decl = "mutable int _cached_size_;\n";
|
|
789
|
+
|
|
790
|
+
// TODO(jieluo) - Optimize _has_bits_ for repeated and oneof fields.
|
|
791
|
+
size_t sizeof_has_bits = (descriptor_->field_count() + 31) / 32 * 4;
|
|
792
|
+
if (descriptor_->field_count() == 0) {
|
|
793
|
+
// Zero-size arrays aren't technically allowed, and MSVC in particular
|
|
794
|
+
// doesn't like them. We still need to declare these arrays to make
|
|
795
|
+
// other code compile. Since this is an uncommon case, we'll just declare
|
|
796
|
+
// them with size 1 and waste some space. Oh well.
|
|
797
|
+
sizeof_has_bits = 4;
|
|
798
|
+
}
|
|
799
|
+
const string has_bits_decl = sizeof_has_bits == 0 ? "" :
|
|
800
|
+
"::google::protobuf::uint32 _has_bits_[" + SimpleItoa(sizeof_has_bits / 4) + "];\n";
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
// To minimize padding, data members are divided into three sections:
|
|
804
|
+
// (1) members assumed to align to 8 bytes
|
|
805
|
+
// (2) members corresponding to message fields, re-ordered to optimize
|
|
806
|
+
// alignment.
|
|
807
|
+
// (3) members assumed to align to 4 bytes.
|
|
808
|
+
|
|
809
|
+
// Members assumed to align to 8 bytes:
|
|
810
|
+
|
|
811
|
+
if (descriptor_->extension_range_count() > 0) {
|
|
812
|
+
printer->Print(
|
|
813
|
+
"::google::protobuf::internal::ExtensionSet _extensions_;\n"
|
|
814
|
+
"\n");
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
if (UseUnknownFieldSet(descriptor_->file())) {
|
|
818
|
+
printer->Print(
|
|
819
|
+
"::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
|
|
820
|
+
"\n");
|
|
821
|
+
} else {
|
|
822
|
+
printer->Print(
|
|
823
|
+
"::std::string _unknown_fields_;\n"
|
|
824
|
+
"\n");
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// _has_bits_ is frequently accessed, so to reduce code size and improve
|
|
828
|
+
// speed, it should be close to the start of the object. But, try not to
|
|
829
|
+
// waste space:_has_bits_ by itself always makes sense if its size is a
|
|
830
|
+
// multiple of 8, but, otherwise, maybe _has_bits_ and cached_size_ together
|
|
831
|
+
// will work well.
|
|
832
|
+
printer->Print(has_bits_decl.c_str());
|
|
833
|
+
if ((sizeof_has_bits % 8) != 0) {
|
|
834
|
+
printer->Print(cached_size_decl.c_str());
|
|
835
|
+
need_to_emit_cached_size = false;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
// Field members:
|
|
839
|
+
|
|
840
|
+
// List fields which doesn't belong to any oneof
|
|
841
|
+
vector<const FieldDescriptor*> fields;
|
|
842
|
+
hash_map<string, int> fieldname_to_chunk;
|
|
843
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
844
|
+
if (!descriptor_->field(i)->containing_oneof()) {
|
|
845
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
846
|
+
fields.push_back(field);
|
|
847
|
+
fieldname_to_chunk[FieldName(field)] = i / 8;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
OptimizePadding(&fields);
|
|
851
|
+
// Emit some private and static members
|
|
852
|
+
runs_of_fields_ = vector< vector<string> >(1);
|
|
853
|
+
for (int i = 0; i < fields.size(); ++i) {
|
|
854
|
+
const FieldDescriptor* field = fields[i];
|
|
855
|
+
const FieldGenerator& generator = field_generators_.get(field);
|
|
856
|
+
generator.GenerateStaticMembers(printer);
|
|
857
|
+
generator.GeneratePrivateMembers(printer);
|
|
858
|
+
if (CanClearByZeroing(field)) {
|
|
859
|
+
const string& fieldname = FieldName(field);
|
|
860
|
+
if (!runs_of_fields_.back().empty() &&
|
|
861
|
+
(fieldname_to_chunk[runs_of_fields_.back().back()] !=
|
|
862
|
+
fieldname_to_chunk[fieldname])) {
|
|
863
|
+
runs_of_fields_.push_back(vector<string>());
|
|
864
|
+
}
|
|
865
|
+
runs_of_fields_.back().push_back(fieldname);
|
|
866
|
+
} else if (!runs_of_fields_.back().empty()) {
|
|
867
|
+
runs_of_fields_.push_back(vector<string>());
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
// For each oneof generate a union
|
|
872
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
873
|
+
printer->Print(
|
|
874
|
+
"union $camel_oneof_name$Union {\n",
|
|
875
|
+
"camel_oneof_name",
|
|
876
|
+
UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
|
|
877
|
+
printer->Indent();
|
|
878
|
+
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
|
|
879
|
+
field_generators_.get(descriptor_->oneof_decl(i)->
|
|
880
|
+
field(j)).GeneratePrivateMembers(printer);
|
|
881
|
+
}
|
|
882
|
+
printer->Outdent();
|
|
883
|
+
printer->Print(
|
|
884
|
+
"} $oneof_name$_;\n",
|
|
885
|
+
"oneof_name", descriptor_->oneof_decl(i)->name());
|
|
886
|
+
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
|
|
887
|
+
field_generators_.get(descriptor_->oneof_decl(i)->
|
|
888
|
+
field(j)).GenerateStaticMembers(printer);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
// Members assumed to align to 4 bytes:
|
|
893
|
+
|
|
894
|
+
if (need_to_emit_cached_size) {
|
|
895
|
+
printer->Print(cached_size_decl.c_str());
|
|
896
|
+
need_to_emit_cached_size = false;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
// Generate _oneof_case_.
|
|
900
|
+
if (descriptor_->oneof_decl_count() > 0) {
|
|
901
|
+
printer->Print(vars,
|
|
902
|
+
"::google::protobuf::uint32 _oneof_case_[$oneof_decl_count$];\n"
|
|
903
|
+
"\n");
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
// Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
|
|
907
|
+
// friends so that they can access private static variables like
|
|
908
|
+
// default_instance_ and reflection_.
|
|
909
|
+
PrintHandlingOptionalStaticInitializers(
|
|
910
|
+
descriptor_->file(), printer,
|
|
911
|
+
// With static initializers.
|
|
912
|
+
"friend void $dllexport_decl$ $adddescriptorsname$();\n",
|
|
913
|
+
// Without.
|
|
914
|
+
"friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
|
|
915
|
+
// Vars.
|
|
916
|
+
"dllexport_decl", options_.dllexport_decl,
|
|
917
|
+
"adddescriptorsname",
|
|
918
|
+
GlobalAddDescriptorsName(descriptor_->file()->name()));
|
|
919
|
+
|
|
920
|
+
printer->Print(
|
|
921
|
+
"friend void $assigndescriptorsname$();\n"
|
|
922
|
+
"friend void $shutdownfilename$();\n"
|
|
923
|
+
"\n",
|
|
924
|
+
"assigndescriptorsname",
|
|
925
|
+
GlobalAssignDescriptorsName(descriptor_->file()->name()),
|
|
926
|
+
"shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
|
|
927
|
+
|
|
928
|
+
printer->Print(
|
|
929
|
+
"void InitAsDefaultInstance();\n"
|
|
930
|
+
"static $classname$* default_instance_;\n",
|
|
931
|
+
"classname", classname_);
|
|
932
|
+
|
|
933
|
+
printer->Outdent();
|
|
934
|
+
printer->Print(vars, "};");
|
|
935
|
+
GOOGLE_DCHECK(!need_to_emit_cached_size);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
void MessageGenerator::
|
|
939
|
+
GenerateInlineMethods(io::Printer* printer) {
|
|
940
|
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
|
941
|
+
nested_generators_[i]->GenerateInlineMethods(printer);
|
|
942
|
+
printer->Print(kThinSeparator);
|
|
943
|
+
printer->Print("\n");
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
GenerateFieldAccessorDefinitions(printer);
|
|
947
|
+
|
|
948
|
+
// Generate oneof_case() functions.
|
|
949
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
950
|
+
map<string, string> vars;
|
|
951
|
+
vars["class_name"] = classname_;
|
|
952
|
+
vars["camel_oneof_name"] = UnderscoresToCamelCase(
|
|
953
|
+
descriptor_->oneof_decl(i)->name(), true);
|
|
954
|
+
vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
|
|
955
|
+
vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
|
|
956
|
+
printer->Print(
|
|
957
|
+
vars,
|
|
958
|
+
"inline $class_name$::$camel_oneof_name$Case $class_name$::"
|
|
959
|
+
"$oneof_name$_case() const {\n"
|
|
960
|
+
" return $class_name$::$camel_oneof_name$Case("
|
|
961
|
+
"_oneof_case_[$oneof_index$]);\n"
|
|
962
|
+
"}\n");
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
void MessageGenerator::
|
|
967
|
+
GenerateDescriptorDeclarations(io::Printer* printer) {
|
|
968
|
+
printer->Print(
|
|
969
|
+
"const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
|
|
970
|
+
"const ::google::protobuf::internal::GeneratedMessageReflection*\n"
|
|
971
|
+
" $name$_reflection_ = NULL;\n",
|
|
972
|
+
"name", classname_);
|
|
973
|
+
|
|
974
|
+
// Generate oneof default instance for reflection usage.
|
|
975
|
+
if (descriptor_->oneof_decl_count() > 0) {
|
|
976
|
+
printer->Print("struct $name$OneofInstance {\n",
|
|
977
|
+
"name", classname_);
|
|
978
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
979
|
+
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
|
|
980
|
+
const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
|
|
981
|
+
printer->Print(" ");
|
|
982
|
+
if (IsStringOrMessage(field)) {
|
|
983
|
+
printer->Print("const ");
|
|
984
|
+
}
|
|
985
|
+
field_generators_.get(field).GeneratePrivateMembers(printer);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
printer->Print("}* $name$_default_oneof_instance_ = NULL;\n",
|
|
990
|
+
"name", classname_);
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
|
994
|
+
nested_generators_[i]->GenerateDescriptorDeclarations(printer);
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
|
|
998
|
+
printer->Print(
|
|
999
|
+
"const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
|
|
1000
|
+
"name", ClassName(descriptor_->enum_type(i), false));
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
void MessageGenerator::
|
|
1005
|
+
GenerateDescriptorInitializer(io::Printer* printer, int index) {
|
|
1006
|
+
// TODO(kenton): Passing the index to this method is redundant; just use
|
|
1007
|
+
// descriptor_->index() instead.
|
|
1008
|
+
map<string, string> vars;
|
|
1009
|
+
vars["classname"] = classname_;
|
|
1010
|
+
vars["index"] = SimpleItoa(index);
|
|
1011
|
+
|
|
1012
|
+
// Obtain the descriptor from the parent's descriptor.
|
|
1013
|
+
if (descriptor_->containing_type() == NULL) {
|
|
1014
|
+
printer->Print(vars,
|
|
1015
|
+
"$classname$_descriptor_ = file->message_type($index$);\n");
|
|
1016
|
+
} else {
|
|
1017
|
+
vars["parent"] = ClassName(descriptor_->containing_type(), false);
|
|
1018
|
+
printer->Print(vars,
|
|
1019
|
+
"$classname$_descriptor_ = "
|
|
1020
|
+
"$parent$_descriptor_->nested_type($index$);\n");
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
// Generate the offsets.
|
|
1024
|
+
GenerateOffsets(printer);
|
|
1025
|
+
|
|
1026
|
+
// Construct the reflection object.
|
|
1027
|
+
printer->Print(vars,
|
|
1028
|
+
"$classname$_reflection_ =\n"
|
|
1029
|
+
" new ::google::protobuf::internal::GeneratedMessageReflection(\n"
|
|
1030
|
+
" $classname$_descriptor_,\n"
|
|
1031
|
+
" $classname$::default_instance_,\n"
|
|
1032
|
+
" $classname$_offsets_,\n"
|
|
1033
|
+
" GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n"
|
|
1034
|
+
" GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
|
|
1035
|
+
"$classname$, _unknown_fields_),\n");
|
|
1036
|
+
if (descriptor_->extension_range_count() > 0) {
|
|
1037
|
+
printer->Print(vars,
|
|
1038
|
+
" GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
|
|
1039
|
+
"$classname$, _extensions_),\n");
|
|
1040
|
+
} else {
|
|
1041
|
+
// No extensions.
|
|
1042
|
+
printer->Print(vars,
|
|
1043
|
+
" -1,\n");
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
if (descriptor_->oneof_decl_count() > 0) {
|
|
1047
|
+
printer->Print(vars,
|
|
1048
|
+
" $classname$_default_oneof_instance_,\n"
|
|
1049
|
+
" GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
|
|
1050
|
+
"$classname$, _oneof_case_[0]),\n");
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
printer->Print(
|
|
1054
|
+
" ::google::protobuf::DescriptorPool::generated_pool(),\n");
|
|
1055
|
+
printer->Print(vars,
|
|
1056
|
+
" ::google::protobuf::MessageFactory::generated_factory(),\n");
|
|
1057
|
+
printer->Print(vars,
|
|
1058
|
+
" sizeof($classname$));\n");
|
|
1059
|
+
|
|
1060
|
+
// Handle nested types.
|
|
1061
|
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
|
1062
|
+
nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
|
|
1066
|
+
enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
void MessageGenerator::
|
|
1071
|
+
GenerateTypeRegistrations(io::Printer* printer) {
|
|
1072
|
+
// Register this message type with the message factory.
|
|
1073
|
+
printer->Print(
|
|
1074
|
+
"::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
|
|
1075
|
+
" $classname$_descriptor_, &$classname$::default_instance());\n",
|
|
1076
|
+
"classname", classname_);
|
|
1077
|
+
|
|
1078
|
+
// Handle nested types.
|
|
1079
|
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
|
1080
|
+
nested_generators_[i]->GenerateTypeRegistrations(printer);
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
void MessageGenerator::
|
|
1085
|
+
GenerateDefaultInstanceAllocator(io::Printer* printer) {
|
|
1086
|
+
// Construct the default instances of all fields, as they will be used
|
|
1087
|
+
// when creating the default instance of the entire message.
|
|
1088
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
1089
|
+
field_generators_.get(descriptor_->field(i))
|
|
1090
|
+
.GenerateDefaultInstanceAllocator(printer);
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
// Construct the default instance. We can't call InitAsDefaultInstance() yet
|
|
1094
|
+
// because we need to make sure all default instances that this one might
|
|
1095
|
+
// depend on are constructed first.
|
|
1096
|
+
printer->Print(
|
|
1097
|
+
"$classname$::default_instance_ = new $classname$();\n",
|
|
1098
|
+
"classname", classname_);
|
|
1099
|
+
|
|
1100
|
+
if ((descriptor_->oneof_decl_count() > 0) &&
|
|
1101
|
+
HasDescriptorMethods(descriptor_->file())) {
|
|
1102
|
+
printer->Print(
|
|
1103
|
+
"$classname$_default_oneof_instance_ = new $classname$OneofInstance;\n",
|
|
1104
|
+
"classname", classname_);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
// Handle nested types.
|
|
1108
|
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
|
1109
|
+
nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
void MessageGenerator::
|
|
1115
|
+
GenerateDefaultInstanceInitializer(io::Printer* printer) {
|
|
1116
|
+
printer->Print(
|
|
1117
|
+
"$classname$::default_instance_->InitAsDefaultInstance();\n",
|
|
1118
|
+
"classname", classname_);
|
|
1119
|
+
|
|
1120
|
+
// Register extensions.
|
|
1121
|
+
for (int i = 0; i < descriptor_->extension_count(); i++) {
|
|
1122
|
+
extension_generators_[i]->GenerateRegistration(printer);
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
// Handle nested types.
|
|
1126
|
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
|
1127
|
+
nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
void MessageGenerator::
|
|
1132
|
+
GenerateShutdownCode(io::Printer* printer) {
|
|
1133
|
+
printer->Print(
|
|
1134
|
+
"delete $classname$::default_instance_;\n",
|
|
1135
|
+
"classname", classname_);
|
|
1136
|
+
|
|
1137
|
+
if (HasDescriptorMethods(descriptor_->file())) {
|
|
1138
|
+
if (descriptor_->oneof_decl_count() > 0) {
|
|
1139
|
+
printer->Print(
|
|
1140
|
+
"delete $classname$_default_oneof_instance_;\n",
|
|
1141
|
+
"classname", classname_);
|
|
1142
|
+
}
|
|
1143
|
+
printer->Print(
|
|
1144
|
+
"delete $classname$_reflection_;\n",
|
|
1145
|
+
"classname", classname_);
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
// Handle default instances of fields.
|
|
1149
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
1150
|
+
field_generators_.get(descriptor_->field(i))
|
|
1151
|
+
.GenerateShutdownCode(printer);
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
// Handle nested types.
|
|
1155
|
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
|
1156
|
+
nested_generators_[i]->GenerateShutdownCode(printer);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
void MessageGenerator::
|
|
1161
|
+
GenerateClassMethods(io::Printer* printer) {
|
|
1162
|
+
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
|
|
1163
|
+
enum_generators_[i]->GenerateMethods(printer);
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
|
1167
|
+
nested_generators_[i]->GenerateClassMethods(printer);
|
|
1168
|
+
printer->Print("\n");
|
|
1169
|
+
printer->Print(kThinSeparator);
|
|
1170
|
+
printer->Print("\n");
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
// Generate non-inline field definitions.
|
|
1174
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
1175
|
+
field_generators_.get(descriptor_->field(i))
|
|
1176
|
+
.GenerateNonInlineAccessorDefinitions(printer);
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
// Generate field number constants.
|
|
1180
|
+
printer->Print("#ifndef _MSC_VER\n");
|
|
1181
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
1182
|
+
const FieldDescriptor *field = descriptor_->field(i);
|
|
1183
|
+
printer->Print(
|
|
1184
|
+
"const int $classname$::$constant_name$;\n",
|
|
1185
|
+
"classname", ClassName(FieldScope(field), false),
|
|
1186
|
+
"constant_name", FieldConstantName(field));
|
|
1187
|
+
}
|
|
1188
|
+
printer->Print(
|
|
1189
|
+
"#endif // !_MSC_VER\n"
|
|
1190
|
+
"\n");
|
|
1191
|
+
|
|
1192
|
+
// Define extension identifiers.
|
|
1193
|
+
for (int i = 0; i < descriptor_->extension_count(); i++) {
|
|
1194
|
+
extension_generators_[i]->GenerateDefinition(printer);
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
GenerateStructors(printer);
|
|
1198
|
+
printer->Print("\n");
|
|
1199
|
+
|
|
1200
|
+
if (descriptor_->oneof_decl_count() > 0) {
|
|
1201
|
+
GenerateOneofClear(printer);
|
|
1202
|
+
printer->Print("\n");
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
if (HasGeneratedMethods(descriptor_->file())) {
|
|
1206
|
+
GenerateClear(printer);
|
|
1207
|
+
printer->Print("\n");
|
|
1208
|
+
|
|
1209
|
+
GenerateMergeFromCodedStream(printer);
|
|
1210
|
+
printer->Print("\n");
|
|
1211
|
+
|
|
1212
|
+
GenerateSerializeWithCachedSizes(printer);
|
|
1213
|
+
printer->Print("\n");
|
|
1214
|
+
|
|
1215
|
+
if (HasFastArraySerialization(descriptor_->file())) {
|
|
1216
|
+
GenerateSerializeWithCachedSizesToArray(printer);
|
|
1217
|
+
printer->Print("\n");
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
GenerateByteSize(printer);
|
|
1221
|
+
printer->Print("\n");
|
|
1222
|
+
|
|
1223
|
+
GenerateMergeFrom(printer);
|
|
1224
|
+
printer->Print("\n");
|
|
1225
|
+
|
|
1226
|
+
GenerateCopyFrom(printer);
|
|
1227
|
+
printer->Print("\n");
|
|
1228
|
+
|
|
1229
|
+
GenerateIsInitialized(printer);
|
|
1230
|
+
printer->Print("\n");
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
GenerateSwap(printer);
|
|
1234
|
+
printer->Print("\n");
|
|
1235
|
+
|
|
1236
|
+
if (HasDescriptorMethods(descriptor_->file())) {
|
|
1237
|
+
printer->Print(
|
|
1238
|
+
"::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
|
|
1239
|
+
" protobuf_AssignDescriptorsOnce();\n"
|
|
1240
|
+
" ::google::protobuf::Metadata metadata;\n"
|
|
1241
|
+
" metadata.descriptor = $classname$_descriptor_;\n"
|
|
1242
|
+
" metadata.reflection = $classname$_reflection_;\n"
|
|
1243
|
+
" return metadata;\n"
|
|
1244
|
+
"}\n"
|
|
1245
|
+
"\n",
|
|
1246
|
+
"classname", classname_);
|
|
1247
|
+
} else {
|
|
1248
|
+
printer->Print(
|
|
1249
|
+
"::std::string $classname$::GetTypeName() const {\n"
|
|
1250
|
+
" return \"$type_name$\";\n"
|
|
1251
|
+
"}\n"
|
|
1252
|
+
"\n",
|
|
1253
|
+
"classname", classname_,
|
|
1254
|
+
"type_name", descriptor_->full_name());
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
void MessageGenerator::
|
|
1260
|
+
GenerateOffsets(io::Printer* printer) {
|
|
1261
|
+
printer->Print(
|
|
1262
|
+
"static const int $classname$_offsets_[$field_count$] = {\n",
|
|
1263
|
+
"classname", classname_,
|
|
1264
|
+
"field_count", SimpleItoa(max(
|
|
1265
|
+
1, descriptor_->field_count() + descriptor_->oneof_decl_count())));
|
|
1266
|
+
printer->Indent();
|
|
1267
|
+
|
|
1268
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
1269
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
1270
|
+
if (field->containing_oneof()) {
|
|
1271
|
+
printer->Print(
|
|
1272
|
+
"PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET("
|
|
1273
|
+
"$classname$_default_oneof_instance_, $name$_),\n",
|
|
1274
|
+
"classname", classname_,
|
|
1275
|
+
"name", FieldName(field));
|
|
1276
|
+
} else {
|
|
1277
|
+
printer->Print(
|
|
1278
|
+
"GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
|
|
1279
|
+
"$name$_),\n",
|
|
1280
|
+
"classname", classname_,
|
|
1281
|
+
"name", FieldName(field));
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
1286
|
+
const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
|
|
1287
|
+
printer->Print(
|
|
1288
|
+
"GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
|
|
1289
|
+
"classname", classname_,
|
|
1290
|
+
"name", oneof->name());
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
printer->Outdent();
|
|
1294
|
+
printer->Print("};\n");
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
void MessageGenerator::
|
|
1298
|
+
GenerateSharedConstructorCode(io::Printer* printer) {
|
|
1299
|
+
printer->Print(
|
|
1300
|
+
"void $classname$::SharedCtor() {\n",
|
|
1301
|
+
"classname", classname_);
|
|
1302
|
+
printer->Indent();
|
|
1303
|
+
|
|
1304
|
+
printer->Print(StrCat(
|
|
1305
|
+
uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "",
|
|
1306
|
+
"_cached_size_ = 0;\n").c_str());
|
|
1307
|
+
|
|
1308
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
1309
|
+
if (!descriptor_->field(i)->containing_oneof()) {
|
|
1310
|
+
field_generators_.get(descriptor_->field(i))
|
|
1311
|
+
.GenerateConstructorCode(printer);
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
printer->Print(
|
|
1316
|
+
"::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
|
|
1317
|
+
|
|
1318
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
1319
|
+
printer->Print(
|
|
1320
|
+
"clear_has_$oneof_name$();\n",
|
|
1321
|
+
"oneof_name", descriptor_->oneof_decl(i)->name());
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
printer->Outdent();
|
|
1325
|
+
printer->Print("}\n\n");
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
void MessageGenerator::
|
|
1329
|
+
GenerateSharedDestructorCode(io::Printer* printer) {
|
|
1330
|
+
printer->Print(
|
|
1331
|
+
"void $classname$::SharedDtor() {\n",
|
|
1332
|
+
"classname", classname_);
|
|
1333
|
+
printer->Indent();
|
|
1334
|
+
// Write the destructors for each field except oneof members.
|
|
1335
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
1336
|
+
if (!descriptor_->field(i)->containing_oneof()) {
|
|
1337
|
+
field_generators_.get(descriptor_->field(i))
|
|
1338
|
+
.GenerateDestructorCode(printer);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
// Generate code to destruct oneofs. Clearing should do the work.
|
|
1343
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
1344
|
+
printer->Print(
|
|
1345
|
+
"if (has_$oneof_name$()) {\n"
|
|
1346
|
+
" clear_$oneof_name$();\n"
|
|
1347
|
+
"}\n",
|
|
1348
|
+
"oneof_name", descriptor_->oneof_decl(i)->name());
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
PrintHandlingOptionalStaticInitializers(
|
|
1352
|
+
descriptor_->file(), printer,
|
|
1353
|
+
// With static initializers.
|
|
1354
|
+
"if (this != default_instance_) {\n",
|
|
1355
|
+
// Without.
|
|
1356
|
+
"if (this != &default_instance()) {\n");
|
|
1357
|
+
|
|
1358
|
+
// We need to delete all embedded messages.
|
|
1359
|
+
// TODO(kenton): If we make unset messages point at default instances
|
|
1360
|
+
// instead of NULL, then it would make sense to move this code into
|
|
1361
|
+
// MessageFieldGenerator::GenerateDestructorCode().
|
|
1362
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
1363
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
1364
|
+
|
|
1365
|
+
if (!field->is_repeated() &&
|
|
1366
|
+
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
|
|
1367
|
+
// Skip oneof members
|
|
1368
|
+
if (!field->containing_oneof()) {
|
|
1369
|
+
printer->Print(
|
|
1370
|
+
" delete $name$_;\n",
|
|
1371
|
+
"name", FieldName(field));
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
printer->Outdent();
|
|
1377
|
+
printer->Print(
|
|
1378
|
+
" }\n"
|
|
1379
|
+
"}\n"
|
|
1380
|
+
"\n");
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
void MessageGenerator::
|
|
1384
|
+
GenerateStructors(io::Printer* printer) {
|
|
1385
|
+
string superclass = SuperClassName(descriptor_);
|
|
1386
|
+
|
|
1387
|
+
// Generate the default constructor.
|
|
1388
|
+
printer->Print(
|
|
1389
|
+
"$classname$::$classname$()\n"
|
|
1390
|
+
" : $superclass$() {\n"
|
|
1391
|
+
" SharedCtor();\n"
|
|
1392
|
+
" // @@protoc_insertion_point(constructor:$full_name$)\n"
|
|
1393
|
+
"}\n",
|
|
1394
|
+
"classname", classname_,
|
|
1395
|
+
"superclass", superclass,
|
|
1396
|
+
"full_name", descriptor_->full_name());
|
|
1397
|
+
|
|
1398
|
+
printer->Print(
|
|
1399
|
+
"\n"
|
|
1400
|
+
"void $classname$::InitAsDefaultInstance() {\n",
|
|
1401
|
+
"classname", classname_);
|
|
1402
|
+
|
|
1403
|
+
// The default instance needs all of its embedded message pointers
|
|
1404
|
+
// cross-linked to other default instances. We can't do this initialization
|
|
1405
|
+
// in the constructor because some other default instances may not have been
|
|
1406
|
+
// constructed yet at that time.
|
|
1407
|
+
// TODO(kenton): Maybe all message fields (even for non-default messages)
|
|
1408
|
+
// should be initialized to point at default instances rather than NULL?
|
|
1409
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
1410
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
1411
|
+
|
|
1412
|
+
if (!field->is_repeated() &&
|
|
1413
|
+
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
|
|
1414
|
+
(field->containing_oneof() == NULL ||
|
|
1415
|
+
HasDescriptorMethods(descriptor_->file()))) {
|
|
1416
|
+
string name;
|
|
1417
|
+
if (field->containing_oneof()) {
|
|
1418
|
+
name = classname_ + "_default_oneof_instance_->";
|
|
1419
|
+
}
|
|
1420
|
+
name += FieldName(field);
|
|
1421
|
+
PrintHandlingOptionalStaticInitializers(
|
|
1422
|
+
descriptor_->file(), printer,
|
|
1423
|
+
// With static initializers.
|
|
1424
|
+
" $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
|
|
1425
|
+
// Without.
|
|
1426
|
+
" $name$_ = const_cast< $type$*>(\n"
|
|
1427
|
+
" $type$::internal_default_instance());\n",
|
|
1428
|
+
// Vars.
|
|
1429
|
+
"name", name,
|
|
1430
|
+
"type", FieldMessageTypeName(field));
|
|
1431
|
+
} else if (field->containing_oneof() &&
|
|
1432
|
+
HasDescriptorMethods(descriptor_->file())) {
|
|
1433
|
+
field_generators_.get(descriptor_->field(i))
|
|
1434
|
+
.GenerateConstructorCode(printer);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
printer->Print(
|
|
1438
|
+
"}\n"
|
|
1439
|
+
"\n");
|
|
1440
|
+
|
|
1441
|
+
// Generate the copy constructor.
|
|
1442
|
+
printer->Print(
|
|
1443
|
+
"$classname$::$classname$(const $classname$& from)\n"
|
|
1444
|
+
" : $superclass$() {\n"
|
|
1445
|
+
" SharedCtor();\n"
|
|
1446
|
+
" MergeFrom(from);\n"
|
|
1447
|
+
" // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
|
|
1448
|
+
"}\n"
|
|
1449
|
+
"\n",
|
|
1450
|
+
"classname", classname_,
|
|
1451
|
+
"superclass", superclass,
|
|
1452
|
+
"full_name", descriptor_->full_name());
|
|
1453
|
+
|
|
1454
|
+
// Generate the shared constructor code.
|
|
1455
|
+
GenerateSharedConstructorCode(printer);
|
|
1456
|
+
|
|
1457
|
+
// Generate the destructor.
|
|
1458
|
+
printer->Print(
|
|
1459
|
+
"$classname$::~$classname$() {\n"
|
|
1460
|
+
" // @@protoc_insertion_point(destructor:$full_name$)\n"
|
|
1461
|
+
" SharedDtor();\n"
|
|
1462
|
+
"}\n"
|
|
1463
|
+
"\n",
|
|
1464
|
+
"classname", classname_,
|
|
1465
|
+
"full_name", descriptor_->full_name());
|
|
1466
|
+
|
|
1467
|
+
// Generate the shared destructor code.
|
|
1468
|
+
GenerateSharedDestructorCode(printer);
|
|
1469
|
+
|
|
1470
|
+
// Generate SetCachedSize.
|
|
1471
|
+
printer->Print(
|
|
1472
|
+
"void $classname$::SetCachedSize(int size) const {\n"
|
|
1473
|
+
" GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
|
|
1474
|
+
" _cached_size_ = size;\n"
|
|
1475
|
+
" GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
|
|
1476
|
+
"}\n",
|
|
1477
|
+
"classname", classname_);
|
|
1478
|
+
|
|
1479
|
+
// Only generate this member if it's not disabled.
|
|
1480
|
+
if (HasDescriptorMethods(descriptor_->file()) &&
|
|
1481
|
+
!descriptor_->options().no_standard_descriptor_accessor()) {
|
|
1482
|
+
printer->Print(
|
|
1483
|
+
"const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
|
|
1484
|
+
" protobuf_AssignDescriptorsOnce();\n"
|
|
1485
|
+
" return $classname$_descriptor_;\n"
|
|
1486
|
+
"}\n"
|
|
1487
|
+
"\n",
|
|
1488
|
+
"classname", classname_,
|
|
1489
|
+
"adddescriptorsname",
|
|
1490
|
+
GlobalAddDescriptorsName(descriptor_->file()->name()));
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
printer->Print(
|
|
1494
|
+
"const $classname$& $classname$::default_instance() {\n",
|
|
1495
|
+
"classname", classname_);
|
|
1496
|
+
|
|
1497
|
+
PrintHandlingOptionalStaticInitializers(
|
|
1498
|
+
descriptor_->file(), printer,
|
|
1499
|
+
// With static initializers.
|
|
1500
|
+
" if (default_instance_ == NULL) $adddescriptorsname$();\n",
|
|
1501
|
+
// Without.
|
|
1502
|
+
" $adddescriptorsname$();\n",
|
|
1503
|
+
// Vars.
|
|
1504
|
+
"adddescriptorsname",
|
|
1505
|
+
GlobalAddDescriptorsName(descriptor_->file()->name()));
|
|
1506
|
+
|
|
1507
|
+
printer->Print(
|
|
1508
|
+
" return *default_instance_;\n"
|
|
1509
|
+
"}\n"
|
|
1510
|
+
"\n"
|
|
1511
|
+
"$classname$* $classname$::default_instance_ = NULL;\n"
|
|
1512
|
+
"\n",
|
|
1513
|
+
"classname", classname_);
|
|
1514
|
+
|
|
1515
|
+
printer->Print(
|
|
1516
|
+
"$classname$* $classname$::New() const {\n"
|
|
1517
|
+
" return new $classname$;\n"
|
|
1518
|
+
"}\n",
|
|
1519
|
+
"classname", classname_);
|
|
1520
|
+
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
// Return the number of bits set in n, a non-negative integer.
|
|
1524
|
+
static int popcnt(uint32 n) {
|
|
1525
|
+
int result = 0;
|
|
1526
|
+
while (n != 0) {
|
|
1527
|
+
result += (n & 1);
|
|
1528
|
+
n = n / 2;
|
|
1529
|
+
}
|
|
1530
|
+
return result;
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
void MessageGenerator::
|
|
1534
|
+
GenerateClear(io::Printer* printer) {
|
|
1535
|
+
printer->Print("void $classname$::Clear() {\n",
|
|
1536
|
+
"classname", classname_);
|
|
1537
|
+
printer->Indent();
|
|
1538
|
+
|
|
1539
|
+
// Step 1: Extensions
|
|
1540
|
+
if (descriptor_->extension_range_count() > 0) {
|
|
1541
|
+
printer->Print("_extensions_.Clear();\n");
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
// Step 2: Everything but extensions, repeateds, unions.
|
|
1545
|
+
// These are handled in chunks of 8. The first chunk is
|
|
1546
|
+
// the non-extensions-non-repeateds-non-unions in
|
|
1547
|
+
// descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7),
|
|
1548
|
+
// and the second chunk is the same for
|
|
1549
|
+
// descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15),
|
|
1550
|
+
// etc.
|
|
1551
|
+
set<int> step2_indices;
|
|
1552
|
+
hash_map<string, int> fieldname_to_chunk;
|
|
1553
|
+
hash_map<int, string> memsets_for_chunk;
|
|
1554
|
+
hash_map<int, int> memset_field_count_for_chunk;
|
|
1555
|
+
hash_set<string> handled; // fields that appear anywhere in memsets_for_chunk
|
|
1556
|
+
hash_map<int, uint32> fields_mask_for_chunk;
|
|
1557
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
1558
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
1559
|
+
if (!field->is_repeated() && !field->containing_oneof()) {
|
|
1560
|
+
step2_indices.insert(i);
|
|
1561
|
+
int chunk = i / 8;
|
|
1562
|
+
fieldname_to_chunk[FieldName(field)] = chunk;
|
|
1563
|
+
fields_mask_for_chunk[chunk] |= static_cast<uint32>(1) << (i % 32);
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
// Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0.
|
|
1568
|
+
// The generated code uses two macros to help it clear runs of fields:
|
|
1569
|
+
// OFFSET_OF_FIELD_ computes the offset (in bytes) of a field in the Message.
|
|
1570
|
+
// ZR_ zeroes a non-empty range of fields via memset.
|
|
1571
|
+
const char* macros =
|
|
1572
|
+
"#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \\\n"
|
|
1573
|
+
" &reinterpret_cast<$classname$*>(16)->f) - \\\n"
|
|
1574
|
+
" reinterpret_cast<char*>(16))\n\n"
|
|
1575
|
+
"#define ZR_(first, last) do { \\\n"
|
|
1576
|
+
" size_t f = OFFSET_OF_FIELD_(first); \\\n"
|
|
1577
|
+
" size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \\\n"
|
|
1578
|
+
" ::memset(&first, 0, n); \\\n"
|
|
1579
|
+
" } while (0)\n\n";
|
|
1580
|
+
for (int i = 0; i < runs_of_fields_.size(); i++) {
|
|
1581
|
+
const vector<string>& run = runs_of_fields_[i];
|
|
1582
|
+
if (run.size() < 2) continue;
|
|
1583
|
+
const string& first_field_name = run[0];
|
|
1584
|
+
const string& last_field_name = run.back();
|
|
1585
|
+
int chunk = fieldname_to_chunk[run[0]];
|
|
1586
|
+
memsets_for_chunk[chunk].append(
|
|
1587
|
+
"ZR_(" + first_field_name + "_, " + last_field_name + "_);\n");
|
|
1588
|
+
for (int j = 0; j < run.size(); j++) {
|
|
1589
|
+
GOOGLE_DCHECK_EQ(chunk, fieldname_to_chunk[run[j]]);
|
|
1590
|
+
handled.insert(run[j]);
|
|
1591
|
+
}
|
|
1592
|
+
memset_field_count_for_chunk[chunk] += run.size();
|
|
1593
|
+
}
|
|
1594
|
+
const bool macros_are_needed = handled.size() > 0;
|
|
1595
|
+
if (macros_are_needed) {
|
|
1596
|
+
printer->Outdent();
|
|
1597
|
+
printer->Print(macros,
|
|
1598
|
+
"classname", classname_);
|
|
1599
|
+
printer->Indent();
|
|
1600
|
+
}
|
|
1601
|
+
// Step 2b: Finish step 2, ignoring fields handled in step 2a.
|
|
1602
|
+
int last_index = -1;
|
|
1603
|
+
bool chunk_block_in_progress = false;
|
|
1604
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
1605
|
+
if (step2_indices.count(i) == 0) continue;
|
|
1606
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
1607
|
+
const string fieldname = FieldName(field);
|
|
1608
|
+
if (i / 8 != last_index / 8 || last_index < 0) {
|
|
1609
|
+
// End previous chunk, if there was one.
|
|
1610
|
+
if (chunk_block_in_progress) {
|
|
1611
|
+
printer->Outdent();
|
|
1612
|
+
printer->Print("}\n");
|
|
1613
|
+
chunk_block_in_progress = false;
|
|
1614
|
+
}
|
|
1615
|
+
// Start chunk.
|
|
1616
|
+
const string& memsets = memsets_for_chunk[i / 8];
|
|
1617
|
+
uint32 mask = fields_mask_for_chunk[i / 8];
|
|
1618
|
+
int count = popcnt(mask);
|
|
1619
|
+
if (count == 1 ||
|
|
1620
|
+
(count <= 4 && count == memset_field_count_for_chunk[i / 8])) {
|
|
1621
|
+
// No "if" here because the chunk is trivial.
|
|
1622
|
+
} else {
|
|
1623
|
+
printer->Print(
|
|
1624
|
+
"if (_has_bits_[$index$ / 32] & $mask$) {\n",
|
|
1625
|
+
"index", SimpleItoa(i / 8 * 8),
|
|
1626
|
+
"mask", SimpleItoa(mask));
|
|
1627
|
+
printer->Indent();
|
|
1628
|
+
chunk_block_in_progress = true;
|
|
1629
|
+
}
|
|
1630
|
+
printer->Print(memsets.c_str());
|
|
1631
|
+
}
|
|
1632
|
+
last_index = i;
|
|
1633
|
+
if (handled.count(fieldname) > 0) continue;
|
|
1634
|
+
|
|
1635
|
+
// It's faster to just overwrite primitive types, but we should
|
|
1636
|
+
// only clear strings and messages if they were set.
|
|
1637
|
+
// TODO(kenton): Let the CppFieldGenerator decide this somehow.
|
|
1638
|
+
bool should_check_bit =
|
|
1639
|
+
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
|
|
1640
|
+
field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
|
|
1641
|
+
|
|
1642
|
+
if (should_check_bit) {
|
|
1643
|
+
printer->Print("if (has_$name$()) {\n", "name", fieldname);
|
|
1644
|
+
printer->Indent();
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
field_generators_.get(field).GenerateClearingCode(printer);
|
|
1648
|
+
|
|
1649
|
+
if (should_check_bit) {
|
|
1650
|
+
printer->Outdent();
|
|
1651
|
+
printer->Print("}\n");
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
if (chunk_block_in_progress) {
|
|
1656
|
+
printer->Outdent();
|
|
1657
|
+
printer->Print("}\n");
|
|
1658
|
+
}
|
|
1659
|
+
if (macros_are_needed) {
|
|
1660
|
+
printer->Outdent();
|
|
1661
|
+
printer->Print("\n#undef OFFSET_OF_FIELD_\n#undef ZR_\n\n");
|
|
1662
|
+
printer->Indent();
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
// Step 3: Repeated fields don't use _has_bits_; emit code to clear them here.
|
|
1666
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
1667
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
1668
|
+
|
|
1669
|
+
if (field->is_repeated()) {
|
|
1670
|
+
field_generators_.get(field).GenerateClearingCode(printer);
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
// Step 4: Unions.
|
|
1675
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
1676
|
+
printer->Print(
|
|
1677
|
+
"clear_$oneof_name$();\n",
|
|
1678
|
+
"oneof_name", descriptor_->oneof_decl(i)->name());
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
// Step 5: Everything else.
|
|
1682
|
+
printer->Print(
|
|
1683
|
+
"::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
|
|
1684
|
+
|
|
1685
|
+
if (UseUnknownFieldSet(descriptor_->file())) {
|
|
1686
|
+
printer->Print(
|
|
1687
|
+
"mutable_unknown_fields()->Clear();\n");
|
|
1688
|
+
} else {
|
|
1689
|
+
printer->Print(
|
|
1690
|
+
"mutable_unknown_fields()->clear();\n");
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
printer->Outdent();
|
|
1694
|
+
printer->Print("}\n");
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
void MessageGenerator::
|
|
1698
|
+
GenerateOneofClear(io::Printer* printer) {
|
|
1699
|
+
// Generated function clears the active field and union case (e.g. foo_case_).
|
|
1700
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
1701
|
+
printer->Print(
|
|
1702
|
+
"void $classname$::clear_$oneofname$() {\n",
|
|
1703
|
+
"classname", classname_,
|
|
1704
|
+
"oneofname", descriptor_->oneof_decl(i)->name());
|
|
1705
|
+
printer->Indent();
|
|
1706
|
+
printer->Print(
|
|
1707
|
+
"switch($oneofname$_case()) {\n",
|
|
1708
|
+
"oneofname", descriptor_->oneof_decl(i)->name());
|
|
1709
|
+
printer->Indent();
|
|
1710
|
+
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
|
|
1711
|
+
const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
|
|
1712
|
+
printer->Print(
|
|
1713
|
+
"case k$field_name$: {\n",
|
|
1714
|
+
"field_name", UnderscoresToCamelCase(field->name(), true));
|
|
1715
|
+
printer->Indent();
|
|
1716
|
+
// We clear only allocated objects in oneofs
|
|
1717
|
+
if (!IsStringOrMessage(field)) {
|
|
1718
|
+
printer->Print(
|
|
1719
|
+
"// No need to clear\n");
|
|
1720
|
+
} else {
|
|
1721
|
+
field_generators_.get(field).GenerateClearingCode(printer);
|
|
1722
|
+
}
|
|
1723
|
+
printer->Print(
|
|
1724
|
+
"break;\n");
|
|
1725
|
+
printer->Outdent();
|
|
1726
|
+
printer->Print(
|
|
1727
|
+
"}\n");
|
|
1728
|
+
}
|
|
1729
|
+
printer->Print(
|
|
1730
|
+
"case $cap_oneof_name$_NOT_SET: {\n"
|
|
1731
|
+
" break;\n"
|
|
1732
|
+
"}\n",
|
|
1733
|
+
"cap_oneof_name",
|
|
1734
|
+
ToUpper(descriptor_->oneof_decl(i)->name()));
|
|
1735
|
+
printer->Outdent();
|
|
1736
|
+
printer->Print(
|
|
1737
|
+
"}\n"
|
|
1738
|
+
"_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n",
|
|
1739
|
+
"oneof_index", SimpleItoa(i),
|
|
1740
|
+
"cap_oneof_name",
|
|
1741
|
+
ToUpper(descriptor_->oneof_decl(i)->name()));
|
|
1742
|
+
printer->Outdent();
|
|
1743
|
+
printer->Print(
|
|
1744
|
+
"}\n"
|
|
1745
|
+
"\n");
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
void MessageGenerator::
|
|
1750
|
+
GenerateSwap(io::Printer* printer) {
|
|
1751
|
+
// Generate the Swap member function.
|
|
1752
|
+
printer->Print("void $classname$::Swap($classname$* other) {\n",
|
|
1753
|
+
"classname", classname_);
|
|
1754
|
+
printer->Indent();
|
|
1755
|
+
printer->Print("if (other != this) {\n");
|
|
1756
|
+
printer->Indent();
|
|
1757
|
+
|
|
1758
|
+
if (HasGeneratedMethods(descriptor_->file())) {
|
|
1759
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
1760
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
1761
|
+
field_generators_.get(field).GenerateSwappingCode(printer);
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
1765
|
+
printer->Print(
|
|
1766
|
+
"std::swap($oneof_name$_, other->$oneof_name$_);\n"
|
|
1767
|
+
"std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n",
|
|
1768
|
+
"oneof_name", descriptor_->oneof_decl(i)->name(),
|
|
1769
|
+
"i", SimpleItoa(i));
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
|
|
1773
|
+
printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
|
|
1774
|
+
"i", SimpleItoa(i));
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
if (UseUnknownFieldSet(descriptor_->file())) {
|
|
1778
|
+
printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
|
|
1779
|
+
} else {
|
|
1780
|
+
printer->Print("_unknown_fields_.swap(other->_unknown_fields_);\n");
|
|
1781
|
+
}
|
|
1782
|
+
printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
|
|
1783
|
+
if (descriptor_->extension_range_count() > 0) {
|
|
1784
|
+
printer->Print("_extensions_.Swap(&other->_extensions_);\n");
|
|
1785
|
+
}
|
|
1786
|
+
} else {
|
|
1787
|
+
printer->Print("GetReflection()->Swap(this, other);");
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
printer->Outdent();
|
|
1791
|
+
printer->Print("}\n");
|
|
1792
|
+
printer->Outdent();
|
|
1793
|
+
printer->Print("}\n");
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
void MessageGenerator::
|
|
1797
|
+
GenerateMergeFrom(io::Printer* printer) {
|
|
1798
|
+
if (HasDescriptorMethods(descriptor_->file())) {
|
|
1799
|
+
// Generate the generalized MergeFrom (aka that which takes in the Message
|
|
1800
|
+
// base class as a parameter).
|
|
1801
|
+
printer->Print(
|
|
1802
|
+
"void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
|
|
1803
|
+
" GOOGLE_CHECK_NE(&from, this);\n",
|
|
1804
|
+
"classname", classname_);
|
|
1805
|
+
printer->Indent();
|
|
1806
|
+
|
|
1807
|
+
// Cast the message to the proper type. If we find that the message is
|
|
1808
|
+
// *not* of the proper type, we can still call Merge via the reflection
|
|
1809
|
+
// system, as the GOOGLE_CHECK above ensured that we have the same descriptor
|
|
1810
|
+
// for each message.
|
|
1811
|
+
printer->Print(
|
|
1812
|
+
"const $classname$* source =\n"
|
|
1813
|
+
" ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
|
|
1814
|
+
" &from);\n"
|
|
1815
|
+
"if (source == NULL) {\n"
|
|
1816
|
+
" ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
|
|
1817
|
+
"} else {\n"
|
|
1818
|
+
" MergeFrom(*source);\n"
|
|
1819
|
+
"}\n",
|
|
1820
|
+
"classname", classname_);
|
|
1821
|
+
|
|
1822
|
+
printer->Outdent();
|
|
1823
|
+
printer->Print("}\n\n");
|
|
1824
|
+
} else {
|
|
1825
|
+
// Generate CheckTypeAndMergeFrom().
|
|
1826
|
+
printer->Print(
|
|
1827
|
+
"void $classname$::CheckTypeAndMergeFrom(\n"
|
|
1828
|
+
" const ::google::protobuf::MessageLite& from) {\n"
|
|
1829
|
+
" MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
|
|
1830
|
+
"}\n"
|
|
1831
|
+
"\n",
|
|
1832
|
+
"classname", classname_);
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
// Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
|
|
1836
|
+
printer->Print(
|
|
1837
|
+
"void $classname$::MergeFrom(const $classname$& from) {\n"
|
|
1838
|
+
" GOOGLE_CHECK_NE(&from, this);\n",
|
|
1839
|
+
"classname", classname_);
|
|
1840
|
+
printer->Indent();
|
|
1841
|
+
|
|
1842
|
+
// Merge Repeated fields. These fields do not require a
|
|
1843
|
+
// check as we can simply iterate over them.
|
|
1844
|
+
for (int i = 0; i < descriptor_->field_count(); ++i) {
|
|
1845
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
1846
|
+
|
|
1847
|
+
if (field->is_repeated()) {
|
|
1848
|
+
field_generators_.get(field).GenerateMergingCode(printer);
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1852
|
+
// Merge oneof fields. Oneof field requires oneof case check.
|
|
1853
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
|
|
1854
|
+
printer->Print(
|
|
1855
|
+
"switch (from.$oneofname$_case()) {\n",
|
|
1856
|
+
"oneofname", descriptor_->oneof_decl(i)->name());
|
|
1857
|
+
printer->Indent();
|
|
1858
|
+
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
|
|
1859
|
+
const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
|
|
1860
|
+
printer->Print(
|
|
1861
|
+
"case k$field_name$: {\n",
|
|
1862
|
+
"field_name", UnderscoresToCamelCase(field->name(), true));
|
|
1863
|
+
printer->Indent();
|
|
1864
|
+
field_generators_.get(field).GenerateMergingCode(printer);
|
|
1865
|
+
printer->Print(
|
|
1866
|
+
"break;\n");
|
|
1867
|
+
printer->Outdent();
|
|
1868
|
+
printer->Print(
|
|
1869
|
+
"}\n");
|
|
1870
|
+
}
|
|
1871
|
+
printer->Print(
|
|
1872
|
+
"case $cap_oneof_name$_NOT_SET: {\n"
|
|
1873
|
+
" break;\n"
|
|
1874
|
+
"}\n",
|
|
1875
|
+
"cap_oneof_name",
|
|
1876
|
+
ToUpper(descriptor_->oneof_decl(i)->name()));
|
|
1877
|
+
printer->Outdent();
|
|
1878
|
+
printer->Print(
|
|
1879
|
+
"}\n");
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
// Merge Optional and Required fields (after a _has_bit check).
|
|
1883
|
+
int last_index = -1;
|
|
1884
|
+
|
|
1885
|
+
for (int i = 0; i < descriptor_->field_count(); ++i) {
|
|
1886
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
1887
|
+
|
|
1888
|
+
if (!field->is_repeated() && !field->containing_oneof()) {
|
|
1889
|
+
// See above in GenerateClear for an explanation of this.
|
|
1890
|
+
if (i / 8 != last_index / 8 || last_index < 0) {
|
|
1891
|
+
if (last_index >= 0) {
|
|
1892
|
+
printer->Outdent();
|
|
1893
|
+
printer->Print("}\n");
|
|
1894
|
+
}
|
|
1895
|
+
printer->Print(
|
|
1896
|
+
"if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
|
|
1897
|
+
"index", SimpleItoa(field->index()));
|
|
1898
|
+
printer->Indent();
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
last_index = i;
|
|
1902
|
+
|
|
1903
|
+
printer->Print(
|
|
1904
|
+
"if (from.has_$name$()) {\n",
|
|
1905
|
+
"name", FieldName(field));
|
|
1906
|
+
printer->Indent();
|
|
1907
|
+
|
|
1908
|
+
field_generators_.get(field).GenerateMergingCode(printer);
|
|
1909
|
+
|
|
1910
|
+
printer->Outdent();
|
|
1911
|
+
printer->Print("}\n");
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
if (last_index >= 0) {
|
|
1916
|
+
printer->Outdent();
|
|
1917
|
+
printer->Print("}\n");
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
if (descriptor_->extension_range_count() > 0) {
|
|
1921
|
+
printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
if (UseUnknownFieldSet(descriptor_->file())) {
|
|
1925
|
+
printer->Print(
|
|
1926
|
+
"mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
|
|
1927
|
+
} else {
|
|
1928
|
+
printer->Print(
|
|
1929
|
+
"mutable_unknown_fields()->append(from.unknown_fields());\n");
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
printer->Outdent();
|
|
1933
|
+
printer->Print("}\n");
|
|
1934
|
+
}
|
|
1935
|
+
|
|
1936
|
+
void MessageGenerator::
|
|
1937
|
+
GenerateCopyFrom(io::Printer* printer) {
|
|
1938
|
+
if (HasDescriptorMethods(descriptor_->file())) {
|
|
1939
|
+
// Generate the generalized CopyFrom (aka that which takes in the Message
|
|
1940
|
+
// base class as a parameter).
|
|
1941
|
+
printer->Print(
|
|
1942
|
+
"void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
|
|
1943
|
+
"classname", classname_);
|
|
1944
|
+
printer->Indent();
|
|
1945
|
+
|
|
1946
|
+
printer->Print(
|
|
1947
|
+
"if (&from == this) return;\n"
|
|
1948
|
+
"Clear();\n"
|
|
1949
|
+
"MergeFrom(from);\n");
|
|
1950
|
+
|
|
1951
|
+
printer->Outdent();
|
|
1952
|
+
printer->Print("}\n\n");
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
// Generate the class-specific CopyFrom.
|
|
1956
|
+
printer->Print(
|
|
1957
|
+
"void $classname$::CopyFrom(const $classname$& from) {\n",
|
|
1958
|
+
"classname", classname_);
|
|
1959
|
+
printer->Indent();
|
|
1960
|
+
|
|
1961
|
+
printer->Print(
|
|
1962
|
+
"if (&from == this) return;\n"
|
|
1963
|
+
"Clear();\n"
|
|
1964
|
+
"MergeFrom(from);\n");
|
|
1965
|
+
|
|
1966
|
+
printer->Outdent();
|
|
1967
|
+
printer->Print("}\n");
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
void MessageGenerator::
|
|
1971
|
+
GenerateMergeFromCodedStream(io::Printer* printer) {
|
|
1972
|
+
if (descriptor_->options().message_set_wire_format()) {
|
|
1973
|
+
// Special-case MessageSet.
|
|
1974
|
+
printer->Print(
|
|
1975
|
+
"bool $classname$::MergePartialFromCodedStream(\n"
|
|
1976
|
+
" ::google::protobuf::io::CodedInputStream* input) {\n",
|
|
1977
|
+
"classname", classname_);
|
|
1978
|
+
|
|
1979
|
+
PrintHandlingOptionalStaticInitializers(
|
|
1980
|
+
descriptor_->file(), printer,
|
|
1981
|
+
// With static initializers.
|
|
1982
|
+
" return _extensions_.ParseMessageSet(input, default_instance_,\n"
|
|
1983
|
+
" mutable_unknown_fields());\n",
|
|
1984
|
+
// Without.
|
|
1985
|
+
" return _extensions_.ParseMessageSet(input, &default_instance(),\n"
|
|
1986
|
+
" mutable_unknown_fields());\n",
|
|
1987
|
+
// Vars.
|
|
1988
|
+
"classname", classname_);
|
|
1989
|
+
|
|
1990
|
+
printer->Print(
|
|
1991
|
+
"}\n");
|
|
1992
|
+
return;
|
|
1993
|
+
}
|
|
1994
|
+
|
|
1995
|
+
printer->Print(
|
|
1996
|
+
"bool $classname$::MergePartialFromCodedStream(\n"
|
|
1997
|
+
" ::google::protobuf::io::CodedInputStream* input) {\n"
|
|
1998
|
+
"#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure\n"
|
|
1999
|
+
" ::google::protobuf::uint32 tag;\n",
|
|
2000
|
+
"classname", classname_);
|
|
2001
|
+
|
|
2002
|
+
if (!UseUnknownFieldSet(descriptor_->file())) {
|
|
2003
|
+
printer->Print(
|
|
2004
|
+
" ::google::protobuf::io::StringOutputStream unknown_fields_string(\n"
|
|
2005
|
+
" mutable_unknown_fields());\n"
|
|
2006
|
+
" ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
|
|
2007
|
+
" &unknown_fields_string);\n");
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
printer->Print(
|
|
2011
|
+
" // @@protoc_insertion_point(parse_start:$full_name$)\n",
|
|
2012
|
+
"full_name", descriptor_->full_name());
|
|
2013
|
+
|
|
2014
|
+
printer->Indent();
|
|
2015
|
+
printer->Print("for (;;) {\n");
|
|
2016
|
+
printer->Indent();
|
|
2017
|
+
|
|
2018
|
+
scoped_array<const FieldDescriptor*> ordered_fields(
|
|
2019
|
+
SortFieldsByNumber(descriptor_));
|
|
2020
|
+
uint32 maxtag = descriptor_->field_count() == 0 ? 0 :
|
|
2021
|
+
WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]);
|
|
2022
|
+
const int kCutoff0 = 127; // fits in 1-byte varint
|
|
2023
|
+
const int kCutoff1 = (127 << 7) + 127; // fits in 2-byte varint
|
|
2024
|
+
printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = "
|
|
2025
|
+
"input->ReadTagWithCutoff($max$);\n"
|
|
2026
|
+
"tag = p.first;\n"
|
|
2027
|
+
"if (!p.second) goto handle_unusual;\n",
|
|
2028
|
+
"max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 :
|
|
2029
|
+
(maxtag <= kCutoff1 ? kCutoff1 :
|
|
2030
|
+
maxtag)));
|
|
2031
|
+
if (descriptor_->field_count() > 0) {
|
|
2032
|
+
// We don't even want to print the switch() if we have no fields because
|
|
2033
|
+
// MSVC dislikes switch() statements that contain only a default value.
|
|
2034
|
+
|
|
2035
|
+
// Note: If we just switched on the tag rather than the field number, we
|
|
2036
|
+
// could avoid the need for the if() to check the wire type at the beginning
|
|
2037
|
+
// of each case. However, this is actually a bit slower in practice as it
|
|
2038
|
+
// creates a jump table that is 8x larger and sparser, and meanwhile the
|
|
2039
|
+
// if()s are highly predictable.
|
|
2040
|
+
printer->Print("switch (::google::protobuf::internal::WireFormatLite::"
|
|
2041
|
+
"GetTagFieldNumber(tag)) {\n");
|
|
2042
|
+
|
|
2043
|
+
printer->Indent();
|
|
2044
|
+
|
|
2045
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
2046
|
+
const FieldDescriptor* field = ordered_fields[i];
|
|
2047
|
+
|
|
2048
|
+
PrintFieldComment(printer, field);
|
|
2049
|
+
|
|
2050
|
+
printer->Print(
|
|
2051
|
+
"case $number$: {\n",
|
|
2052
|
+
"number", SimpleItoa(field->number()));
|
|
2053
|
+
printer->Indent();
|
|
2054
|
+
const FieldGenerator& field_generator = field_generators_.get(field);
|
|
2055
|
+
|
|
2056
|
+
// Emit code to parse the common, expected case.
|
|
2057
|
+
printer->Print("if (tag == $commontag$) {\n",
|
|
2058
|
+
"commontag", SimpleItoa(WireFormat::MakeTag(field)));
|
|
2059
|
+
|
|
2060
|
+
if (i > 0 || (field->is_repeated() && !field->options().packed())) {
|
|
2061
|
+
printer->Print(
|
|
2062
|
+
" parse_$name$:\n",
|
|
2063
|
+
"name", field->name());
|
|
2064
|
+
}
|
|
2065
|
+
|
|
2066
|
+
printer->Indent();
|
|
2067
|
+
if (field->options().packed()) {
|
|
2068
|
+
field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
|
|
2069
|
+
} else {
|
|
2070
|
+
field_generator.GenerateMergeFromCodedStream(printer);
|
|
2071
|
+
}
|
|
2072
|
+
printer->Outdent();
|
|
2073
|
+
|
|
2074
|
+
// Emit code to parse unexpectedly packed or unpacked values.
|
|
2075
|
+
if (field->is_packable() && field->options().packed()) {
|
|
2076
|
+
internal::WireFormatLite::WireType wiretype =
|
|
2077
|
+
WireFormat::WireTypeForFieldType(field->type());
|
|
2078
|
+
printer->Print("} else if (tag == $uncommontag$) {\n",
|
|
2079
|
+
"uncommontag", SimpleItoa(
|
|
2080
|
+
internal::WireFormatLite::MakeTag(
|
|
2081
|
+
field->number(), wiretype)));
|
|
2082
|
+
printer->Indent();
|
|
2083
|
+
field_generator.GenerateMergeFromCodedStream(printer);
|
|
2084
|
+
printer->Outdent();
|
|
2085
|
+
} else if (field->is_packable() && !field->options().packed()) {
|
|
2086
|
+
internal::WireFormatLite::WireType wiretype =
|
|
2087
|
+
internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
|
|
2088
|
+
printer->Print("} else if (tag == $uncommontag$) {\n",
|
|
2089
|
+
"uncommontag", SimpleItoa(
|
|
2090
|
+
internal::WireFormatLite::MakeTag(
|
|
2091
|
+
field->number(), wiretype)));
|
|
2092
|
+
printer->Indent();
|
|
2093
|
+
field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
|
|
2094
|
+
printer->Outdent();
|
|
2095
|
+
}
|
|
2096
|
+
|
|
2097
|
+
printer->Print(
|
|
2098
|
+
"} else {\n"
|
|
2099
|
+
" goto handle_unusual;\n"
|
|
2100
|
+
"}\n");
|
|
2101
|
+
|
|
2102
|
+
// switch() is slow since it can't be predicted well. Insert some if()s
|
|
2103
|
+
// here that attempt to predict the next tag.
|
|
2104
|
+
if (field->is_repeated() && !field->options().packed()) {
|
|
2105
|
+
// Expect repeats of this field.
|
|
2106
|
+
printer->Print(
|
|
2107
|
+
"if (input->ExpectTag($tag$)) goto parse_$name$;\n",
|
|
2108
|
+
"tag", SimpleItoa(WireFormat::MakeTag(field)),
|
|
2109
|
+
"name", field->name());
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
if (i + 1 < descriptor_->field_count()) {
|
|
2113
|
+
// Expect the next field in order.
|
|
2114
|
+
const FieldDescriptor* next_field = ordered_fields[i + 1];
|
|
2115
|
+
printer->Print(
|
|
2116
|
+
"if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n",
|
|
2117
|
+
"next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
|
|
2118
|
+
"next_name", next_field->name());
|
|
2119
|
+
} else {
|
|
2120
|
+
// Expect EOF.
|
|
2121
|
+
// TODO(kenton): Expect group end-tag?
|
|
2122
|
+
printer->Print(
|
|
2123
|
+
"if (input->ExpectAtEnd()) goto success;\n");
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
printer->Print(
|
|
2127
|
+
"break;\n");
|
|
2128
|
+
|
|
2129
|
+
printer->Outdent();
|
|
2130
|
+
printer->Print("}\n\n");
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
printer->Print("default: {\n");
|
|
2134
|
+
printer->Indent();
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2137
|
+
printer->Outdent();
|
|
2138
|
+
printer->Print("handle_unusual:\n");
|
|
2139
|
+
printer->Indent();
|
|
2140
|
+
// If tag is 0 or an end-group tag then this must be the end of the message.
|
|
2141
|
+
printer->Print(
|
|
2142
|
+
"if (tag == 0 ||\n"
|
|
2143
|
+
" ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
|
|
2144
|
+
" ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
|
|
2145
|
+
" goto success;\n"
|
|
2146
|
+
"}\n");
|
|
2147
|
+
|
|
2148
|
+
// Handle extension ranges.
|
|
2149
|
+
if (descriptor_->extension_range_count() > 0) {
|
|
2150
|
+
printer->Print(
|
|
2151
|
+
"if (");
|
|
2152
|
+
for (int i = 0; i < descriptor_->extension_range_count(); i++) {
|
|
2153
|
+
const Descriptor::ExtensionRange* range =
|
|
2154
|
+
descriptor_->extension_range(i);
|
|
2155
|
+
if (i > 0) printer->Print(" ||\n ");
|
|
2156
|
+
|
|
2157
|
+
uint32 start_tag = WireFormatLite::MakeTag(
|
|
2158
|
+
range->start, static_cast<WireFormatLite::WireType>(0));
|
|
2159
|
+
uint32 end_tag = WireFormatLite::MakeTag(
|
|
2160
|
+
range->end, static_cast<WireFormatLite::WireType>(0));
|
|
2161
|
+
|
|
2162
|
+
if (range->end > FieldDescriptor::kMaxNumber) {
|
|
2163
|
+
printer->Print(
|
|
2164
|
+
"($start$u <= tag)",
|
|
2165
|
+
"start", SimpleItoa(start_tag));
|
|
2166
|
+
} else {
|
|
2167
|
+
printer->Print(
|
|
2168
|
+
"($start$u <= tag && tag < $end$u)",
|
|
2169
|
+
"start", SimpleItoa(start_tag),
|
|
2170
|
+
"end", SimpleItoa(end_tag));
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
printer->Print(") {\n");
|
|
2174
|
+
if (UseUnknownFieldSet(descriptor_->file())) {
|
|
2175
|
+
PrintHandlingOptionalStaticInitializers(
|
|
2176
|
+
descriptor_->file(), printer,
|
|
2177
|
+
// With static initializers.
|
|
2178
|
+
" DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
|
|
2179
|
+
" mutable_unknown_fields()));\n",
|
|
2180
|
+
// Without.
|
|
2181
|
+
" DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
|
|
2182
|
+
" mutable_unknown_fields()));\n");
|
|
2183
|
+
} else {
|
|
2184
|
+
PrintHandlingOptionalStaticInitializers(
|
|
2185
|
+
descriptor_->file(), printer,
|
|
2186
|
+
// With static initializers.
|
|
2187
|
+
" DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
|
|
2188
|
+
" &unknown_fields_stream));\n",
|
|
2189
|
+
// Without.
|
|
2190
|
+
" DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
|
|
2191
|
+
" &unknown_fields_stream));\n");
|
|
2192
|
+
}
|
|
2193
|
+
printer->Print(
|
|
2194
|
+
" continue;\n"
|
|
2195
|
+
"}\n");
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
// We really don't recognize this tag. Skip it.
|
|
2199
|
+
if (UseUnknownFieldSet(descriptor_->file())) {
|
|
2200
|
+
printer->Print(
|
|
2201
|
+
"DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
|
|
2202
|
+
" input, tag, mutable_unknown_fields()));\n");
|
|
2203
|
+
} else {
|
|
2204
|
+
printer->Print(
|
|
2205
|
+
"DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n"
|
|
2206
|
+
" input, tag, &unknown_fields_stream));\n");
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
if (descriptor_->field_count() > 0) {
|
|
2210
|
+
printer->Print("break;\n");
|
|
2211
|
+
printer->Outdent();
|
|
2212
|
+
printer->Print("}\n"); // default:
|
|
2213
|
+
printer->Outdent();
|
|
2214
|
+
printer->Print("}\n"); // switch
|
|
2215
|
+
}
|
|
2216
|
+
|
|
2217
|
+
printer->Outdent();
|
|
2218
|
+
printer->Outdent();
|
|
2219
|
+
printer->Print(
|
|
2220
|
+
" }\n" // for (;;)
|
|
2221
|
+
"success:\n"
|
|
2222
|
+
" // @@protoc_insertion_point(parse_success:$full_name$)\n"
|
|
2223
|
+
" return true;\n"
|
|
2224
|
+
"failure:\n"
|
|
2225
|
+
" // @@protoc_insertion_point(parse_failure:$full_name$)\n"
|
|
2226
|
+
" return false;\n"
|
|
2227
|
+
"#undef DO_\n"
|
|
2228
|
+
"}\n", "full_name", descriptor_->full_name());
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
void MessageGenerator::GenerateSerializeOneField(
|
|
2232
|
+
io::Printer* printer, const FieldDescriptor* field, bool to_array) {
|
|
2233
|
+
PrintFieldComment(printer, field);
|
|
2234
|
+
|
|
2235
|
+
if (!field->is_repeated()) {
|
|
2236
|
+
printer->Print(
|
|
2237
|
+
"if (has_$name$()) {\n",
|
|
2238
|
+
"name", FieldName(field));
|
|
2239
|
+
printer->Indent();
|
|
2240
|
+
}
|
|
2241
|
+
|
|
2242
|
+
if (to_array) {
|
|
2243
|
+
field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
|
|
2244
|
+
printer);
|
|
2245
|
+
} else {
|
|
2246
|
+
field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
|
|
2247
|
+
}
|
|
2248
|
+
|
|
2249
|
+
if (!field->is_repeated()) {
|
|
2250
|
+
printer->Outdent();
|
|
2251
|
+
printer->Print("}\n");
|
|
2252
|
+
}
|
|
2253
|
+
printer->Print("\n");
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
void MessageGenerator::GenerateSerializeOneExtensionRange(
|
|
2257
|
+
io::Printer* printer, const Descriptor::ExtensionRange* range,
|
|
2258
|
+
bool to_array) {
|
|
2259
|
+
map<string, string> vars;
|
|
2260
|
+
vars["start"] = SimpleItoa(range->start);
|
|
2261
|
+
vars["end"] = SimpleItoa(range->end);
|
|
2262
|
+
printer->Print(vars,
|
|
2263
|
+
"// Extension range [$start$, $end$)\n");
|
|
2264
|
+
if (to_array) {
|
|
2265
|
+
printer->Print(vars,
|
|
2266
|
+
"target = _extensions_.SerializeWithCachedSizesToArray(\n"
|
|
2267
|
+
" $start$, $end$, target);\n\n");
|
|
2268
|
+
} else {
|
|
2269
|
+
printer->Print(vars,
|
|
2270
|
+
"_extensions_.SerializeWithCachedSizes(\n"
|
|
2271
|
+
" $start$, $end$, output);\n\n");
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
|
|
2275
|
+
void MessageGenerator::
|
|
2276
|
+
GenerateSerializeWithCachedSizes(io::Printer* printer) {
|
|
2277
|
+
if (descriptor_->options().message_set_wire_format()) {
|
|
2278
|
+
// Special-case MessageSet.
|
|
2279
|
+
printer->Print(
|
|
2280
|
+
"void $classname$::SerializeWithCachedSizes(\n"
|
|
2281
|
+
" ::google::protobuf::io::CodedOutputStream* output) const {\n"
|
|
2282
|
+
" _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
|
|
2283
|
+
"classname", classname_);
|
|
2284
|
+
GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
|
|
2285
|
+
printer->Print(
|
|
2286
|
+
" ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
|
|
2287
|
+
" unknown_fields(), output);\n");
|
|
2288
|
+
printer->Print(
|
|
2289
|
+
"}\n");
|
|
2290
|
+
return;
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2293
|
+
printer->Print(
|
|
2294
|
+
"void $classname$::SerializeWithCachedSizes(\n"
|
|
2295
|
+
" ::google::protobuf::io::CodedOutputStream* output) const {\n",
|
|
2296
|
+
"classname", classname_);
|
|
2297
|
+
printer->Indent();
|
|
2298
|
+
|
|
2299
|
+
printer->Print(
|
|
2300
|
+
"// @@protoc_insertion_point(serialize_start:$full_name$)\n",
|
|
2301
|
+
"full_name", descriptor_->full_name());
|
|
2302
|
+
|
|
2303
|
+
GenerateSerializeWithCachedSizesBody(printer, false);
|
|
2304
|
+
|
|
2305
|
+
printer->Print(
|
|
2306
|
+
"// @@protoc_insertion_point(serialize_end:$full_name$)\n",
|
|
2307
|
+
"full_name", descriptor_->full_name());
|
|
2308
|
+
|
|
2309
|
+
printer->Outdent();
|
|
2310
|
+
printer->Print(
|
|
2311
|
+
"}\n");
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
void MessageGenerator::
|
|
2315
|
+
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
|
|
2316
|
+
if (descriptor_->options().message_set_wire_format()) {
|
|
2317
|
+
// Special-case MessageSet.
|
|
2318
|
+
printer->Print(
|
|
2319
|
+
"::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
|
|
2320
|
+
" ::google::protobuf::uint8* target) const {\n"
|
|
2321
|
+
" target =\n"
|
|
2322
|
+
" _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
|
|
2323
|
+
"classname", classname_);
|
|
2324
|
+
GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
|
|
2325
|
+
printer->Print(
|
|
2326
|
+
" target = ::google::protobuf::internal::WireFormat::\n"
|
|
2327
|
+
" SerializeUnknownMessageSetItemsToArray(\n"
|
|
2328
|
+
" unknown_fields(), target);\n");
|
|
2329
|
+
printer->Print(
|
|
2330
|
+
" return target;\n"
|
|
2331
|
+
"}\n");
|
|
2332
|
+
return;
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2335
|
+
printer->Print(
|
|
2336
|
+
"::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
|
|
2337
|
+
" ::google::protobuf::uint8* target) const {\n",
|
|
2338
|
+
"classname", classname_);
|
|
2339
|
+
printer->Indent();
|
|
2340
|
+
|
|
2341
|
+
printer->Print(
|
|
2342
|
+
"// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n",
|
|
2343
|
+
"full_name", descriptor_->full_name());
|
|
2344
|
+
|
|
2345
|
+
GenerateSerializeWithCachedSizesBody(printer, true);
|
|
2346
|
+
|
|
2347
|
+
printer->Print(
|
|
2348
|
+
"// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n",
|
|
2349
|
+
"full_name", descriptor_->full_name());
|
|
2350
|
+
|
|
2351
|
+
printer->Outdent();
|
|
2352
|
+
printer->Print(
|
|
2353
|
+
" return target;\n"
|
|
2354
|
+
"}\n");
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
void MessageGenerator::
|
|
2358
|
+
GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
|
|
2359
|
+
scoped_array<const FieldDescriptor*> ordered_fields(
|
|
2360
|
+
SortFieldsByNumber(descriptor_));
|
|
2361
|
+
|
|
2362
|
+
vector<const Descriptor::ExtensionRange*> sorted_extensions;
|
|
2363
|
+
for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
|
|
2364
|
+
sorted_extensions.push_back(descriptor_->extension_range(i));
|
|
2365
|
+
}
|
|
2366
|
+
sort(sorted_extensions.begin(), sorted_extensions.end(),
|
|
2367
|
+
ExtensionRangeSorter());
|
|
2368
|
+
|
|
2369
|
+
// Merge the fields and the extension ranges, both sorted by field number.
|
|
2370
|
+
int i, j;
|
|
2371
|
+
for (i = 0, j = 0;
|
|
2372
|
+
i < descriptor_->field_count() || j < sorted_extensions.size();
|
|
2373
|
+
) {
|
|
2374
|
+
if (i == descriptor_->field_count()) {
|
|
2375
|
+
GenerateSerializeOneExtensionRange(printer,
|
|
2376
|
+
sorted_extensions[j++],
|
|
2377
|
+
to_array);
|
|
2378
|
+
} else if (j == sorted_extensions.size()) {
|
|
2379
|
+
GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
|
|
2380
|
+
} else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
|
|
2381
|
+
GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
|
|
2382
|
+
} else {
|
|
2383
|
+
GenerateSerializeOneExtensionRange(printer,
|
|
2384
|
+
sorted_extensions[j++],
|
|
2385
|
+
to_array);
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
if (UseUnknownFieldSet(descriptor_->file())) {
|
|
2390
|
+
printer->Print("if (!unknown_fields().empty()) {\n");
|
|
2391
|
+
printer->Indent();
|
|
2392
|
+
if (to_array) {
|
|
2393
|
+
printer->Print(
|
|
2394
|
+
"target = "
|
|
2395
|
+
"::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
|
|
2396
|
+
" unknown_fields(), target);\n");
|
|
2397
|
+
} else {
|
|
2398
|
+
printer->Print(
|
|
2399
|
+
"::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
|
|
2400
|
+
" unknown_fields(), output);\n");
|
|
2401
|
+
}
|
|
2402
|
+
printer->Outdent();
|
|
2403
|
+
|
|
2404
|
+
printer->Print(
|
|
2405
|
+
"}\n");
|
|
2406
|
+
} else {
|
|
2407
|
+
printer->Print(
|
|
2408
|
+
"output->WriteRaw(unknown_fields().data(),\n"
|
|
2409
|
+
" unknown_fields().size());\n");
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
|
|
2413
|
+
void MessageGenerator::
|
|
2414
|
+
GenerateByteSize(io::Printer* printer) {
|
|
2415
|
+
if (descriptor_->options().message_set_wire_format()) {
|
|
2416
|
+
// Special-case MessageSet.
|
|
2417
|
+
printer->Print(
|
|
2418
|
+
"int $classname$::ByteSize() const {\n"
|
|
2419
|
+
" int total_size = _extensions_.MessageSetByteSize();\n",
|
|
2420
|
+
"classname", classname_);
|
|
2421
|
+
GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
|
|
2422
|
+
printer->Print(
|
|
2423
|
+
" total_size += ::google::protobuf::internal::WireFormat::\n"
|
|
2424
|
+
" ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
|
|
2425
|
+
printer->Print(
|
|
2426
|
+
" GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
|
|
2427
|
+
" _cached_size_ = total_size;\n"
|
|
2428
|
+
" GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
|
|
2429
|
+
" return total_size;\n"
|
|
2430
|
+
"}\n");
|
|
2431
|
+
return;
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
printer->Print(
|
|
2435
|
+
"int $classname$::ByteSize() const {\n",
|
|
2436
|
+
"classname", classname_);
|
|
2437
|
+
printer->Indent();
|
|
2438
|
+
printer->Print(
|
|
2439
|
+
"int total_size = 0;\n"
|
|
2440
|
+
"\n");
|
|
2441
|
+
|
|
2442
|
+
int last_index = -1;
|
|
2443
|
+
|
|
2444
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
2445
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
2446
|
+
|
|
2447
|
+
if (!field->is_repeated() && !field->containing_oneof()) {
|
|
2448
|
+
// See above in GenerateClear for an explanation of this.
|
|
2449
|
+
// TODO(kenton): Share code? Unclear how to do so without
|
|
2450
|
+
// over-engineering.
|
|
2451
|
+
if ((i / 8) != (last_index / 8) ||
|
|
2452
|
+
last_index < 0) {
|
|
2453
|
+
if (last_index >= 0) {
|
|
2454
|
+
printer->Outdent();
|
|
2455
|
+
printer->Print("}\n");
|
|
2456
|
+
}
|
|
2457
|
+
printer->Print(
|
|
2458
|
+
"if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
|
|
2459
|
+
"index", SimpleItoa(field->index()));
|
|
2460
|
+
printer->Indent();
|
|
2461
|
+
}
|
|
2462
|
+
last_index = i;
|
|
2463
|
+
|
|
2464
|
+
PrintFieldComment(printer, field);
|
|
2465
|
+
|
|
2466
|
+
printer->Print(
|
|
2467
|
+
"if (has_$name$()) {\n",
|
|
2468
|
+
"name", FieldName(field));
|
|
2469
|
+
printer->Indent();
|
|
2470
|
+
|
|
2471
|
+
field_generators_.get(field).GenerateByteSize(printer);
|
|
2472
|
+
|
|
2473
|
+
printer->Outdent();
|
|
2474
|
+
printer->Print(
|
|
2475
|
+
"}\n"
|
|
2476
|
+
"\n");
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
|
|
2480
|
+
if (last_index >= 0) {
|
|
2481
|
+
printer->Outdent();
|
|
2482
|
+
printer->Print("}\n");
|
|
2483
|
+
}
|
|
2484
|
+
|
|
2485
|
+
// Repeated fields don't use _has_bits_ so we count them in a separate
|
|
2486
|
+
// pass.
|
|
2487
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
2488
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
2489
|
+
|
|
2490
|
+
if (field->is_repeated()) {
|
|
2491
|
+
PrintFieldComment(printer, field);
|
|
2492
|
+
field_generators_.get(field).GenerateByteSize(printer);
|
|
2493
|
+
printer->Print("\n");
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
|
|
2497
|
+
// Fields inside a oneof don't use _has_bits_ so we count them in a separate
|
|
2498
|
+
// pass.
|
|
2499
|
+
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
2500
|
+
printer->Print(
|
|
2501
|
+
"switch ($oneofname$_case()) {\n",
|
|
2502
|
+
"oneofname", descriptor_->oneof_decl(i)->name());
|
|
2503
|
+
printer->Indent();
|
|
2504
|
+
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
|
|
2505
|
+
const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
|
|
2506
|
+
PrintFieldComment(printer, field);
|
|
2507
|
+
printer->Print(
|
|
2508
|
+
"case k$field_name$: {\n",
|
|
2509
|
+
"field_name", UnderscoresToCamelCase(field->name(), true));
|
|
2510
|
+
printer->Indent();
|
|
2511
|
+
field_generators_.get(field).GenerateByteSize(printer);
|
|
2512
|
+
printer->Print(
|
|
2513
|
+
"break;\n");
|
|
2514
|
+
printer->Outdent();
|
|
2515
|
+
printer->Print(
|
|
2516
|
+
"}\n");
|
|
2517
|
+
}
|
|
2518
|
+
printer->Print(
|
|
2519
|
+
"case $cap_oneof_name$_NOT_SET: {\n"
|
|
2520
|
+
" break;\n"
|
|
2521
|
+
"}\n",
|
|
2522
|
+
"cap_oneof_name",
|
|
2523
|
+
ToUpper(descriptor_->oneof_decl(i)->name()));
|
|
2524
|
+
printer->Outdent();
|
|
2525
|
+
printer->Print(
|
|
2526
|
+
"}\n");
|
|
2527
|
+
}
|
|
2528
|
+
|
|
2529
|
+
if (descriptor_->extension_range_count() > 0) {
|
|
2530
|
+
printer->Print(
|
|
2531
|
+
"total_size += _extensions_.ByteSize();\n"
|
|
2532
|
+
"\n");
|
|
2533
|
+
}
|
|
2534
|
+
|
|
2535
|
+
if (UseUnknownFieldSet(descriptor_->file())) {
|
|
2536
|
+
printer->Print("if (!unknown_fields().empty()) {\n");
|
|
2537
|
+
printer->Indent();
|
|
2538
|
+
printer->Print(
|
|
2539
|
+
"total_size +=\n"
|
|
2540
|
+
" ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
|
|
2541
|
+
" unknown_fields());\n");
|
|
2542
|
+
printer->Outdent();
|
|
2543
|
+
printer->Print("}\n");
|
|
2544
|
+
} else {
|
|
2545
|
+
printer->Print(
|
|
2546
|
+
"total_size += unknown_fields().size();\n"
|
|
2547
|
+
"\n");
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
// We update _cached_size_ even though this is a const method. In theory,
|
|
2551
|
+
// this is not thread-compatible, because concurrent writes have undefined
|
|
2552
|
+
// results. In practice, since any concurrent writes will be writing the
|
|
2553
|
+
// exact same value, it works on all common processors. In a future version
|
|
2554
|
+
// of C++, _cached_size_ should be made into an atomic<int>.
|
|
2555
|
+
printer->Print(
|
|
2556
|
+
"GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
|
|
2557
|
+
"_cached_size_ = total_size;\n"
|
|
2558
|
+
"GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
|
|
2559
|
+
"return total_size;\n");
|
|
2560
|
+
|
|
2561
|
+
printer->Outdent();
|
|
2562
|
+
printer->Print("}\n");
|
|
2563
|
+
}
|
|
2564
|
+
|
|
2565
|
+
void MessageGenerator::
|
|
2566
|
+
GenerateIsInitialized(io::Printer* printer) {
|
|
2567
|
+
printer->Print(
|
|
2568
|
+
"bool $classname$::IsInitialized() const {\n",
|
|
2569
|
+
"classname", classname_);
|
|
2570
|
+
printer->Indent();
|
|
2571
|
+
|
|
2572
|
+
// Check that all required fields in this message are set. We can do this
|
|
2573
|
+
// most efficiently by checking 32 "has bits" at a time.
|
|
2574
|
+
int has_bits_array_size = (descriptor_->field_count() + 31) / 32;
|
|
2575
|
+
for (int i = 0; i < has_bits_array_size; i++) {
|
|
2576
|
+
uint32 mask = 0;
|
|
2577
|
+
for (int bit = 0; bit < 32; bit++) {
|
|
2578
|
+
int index = i * 32 + bit;
|
|
2579
|
+
if (index >= descriptor_->field_count()) break;
|
|
2580
|
+
const FieldDescriptor* field = descriptor_->field(index);
|
|
2581
|
+
|
|
2582
|
+
if (field->is_required()) {
|
|
2583
|
+
mask |= 1 << bit;
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
|
|
2587
|
+
if (mask != 0) {
|
|
2588
|
+
char buffer[kFastToBufferSize];
|
|
2589
|
+
printer->Print(
|
|
2590
|
+
"if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
|
|
2591
|
+
"i", SimpleItoa(i),
|
|
2592
|
+
"mask", FastHex32ToBuffer(mask, buffer));
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2596
|
+
// Now check that all embedded messages are initialized.
|
|
2597
|
+
printer->Print("\n");
|
|
2598
|
+
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
2599
|
+
const FieldDescriptor* field = descriptor_->field(i);
|
|
2600
|
+
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
|
|
2601
|
+
!ShouldIgnoreRequiredFieldCheck(field) &&
|
|
2602
|
+
HasRequiredFields(field->message_type())) {
|
|
2603
|
+
if (field->is_repeated()) {
|
|
2604
|
+
printer->Print(
|
|
2605
|
+
"if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))"
|
|
2606
|
+
" return false;\n",
|
|
2607
|
+
"name", FieldName(field));
|
|
2608
|
+
} else {
|
|
2609
|
+
if (field->options().weak()) {
|
|
2610
|
+
// For weak fields, use the data member (google::protobuf::Message*) instead
|
|
2611
|
+
// of the getter to avoid a link dependency on the weak message type
|
|
2612
|
+
// which is only forward declared.
|
|
2613
|
+
printer->Print(
|
|
2614
|
+
"if (has_$name$()) {\n"
|
|
2615
|
+
" if (!this->$name$_->IsInitialized()) return false;\n"
|
|
2616
|
+
"}\n",
|
|
2617
|
+
"name", FieldName(field));
|
|
2618
|
+
} else {
|
|
2619
|
+
printer->Print(
|
|
2620
|
+
"if (has_$name$()) {\n"
|
|
2621
|
+
" if (!this->$name$().IsInitialized()) return false;\n"
|
|
2622
|
+
"}\n",
|
|
2623
|
+
"name", FieldName(field));
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2629
|
+
if (descriptor_->extension_range_count() > 0) {
|
|
2630
|
+
printer->Print(
|
|
2631
|
+
"\n"
|
|
2632
|
+
"if (!_extensions_.IsInitialized()) return false;");
|
|
2633
|
+
}
|
|
2634
|
+
|
|
2635
|
+
printer->Outdent();
|
|
2636
|
+
printer->Print(
|
|
2637
|
+
" return true;\n"
|
|
2638
|
+
"}\n");
|
|
2639
|
+
}
|
|
2640
|
+
|
|
2641
|
+
|
|
2642
|
+
} // namespace cpp
|
|
2643
|
+
} // namespace compiler
|
|
2644
|
+
} // namespace protobuf
|
|
2645
|
+
} // namespace google
|